klg-jpa:spring-data-jpa 最佳实践

项目介绍

码云地址:https://gitee.com/klguang/klg-jpa

JPA是sun为POJO持久化制定的标准规范,用来操作实体对象,执行CRUD操作,让开发者从繁琐的JDBC和SQL代码中解脱出来。 但是JPA有以下两个缺陷:
1.臃肿的动态条件查询 

2.众所周知,复杂查询(联接表查询)的效率低 
spring-data-jpa和mybatis可以整合在一起使用有什么优缺点,这个问答种了解到 spring-data-jpa-extra这个库,让我们可用更方便的写sql查询。

klg-jpa,spring-data-jpa 最佳实践,用起来就像开了挂,更多例子klg-j2ee-dataacess-demo 演示

单表查询最佳实践

1. find by attribute是一种较灵活的方式,需要用到jpa生成的metamodel,在快速开发的利器 

BaseRepository api:

 //-------------find by attribute------------------------public Page<T> findPage(Pageable pageable,AttrExpression...exprs);public List<T> findList(Sort sort,AttrExpression...exprs);public List<T> findList(AttrExpression...exprs);public T getOne(AttrExpression...exprs);public long count(AttrExpression...exprs);

find by attribute 适合不定条件单表查询,默认是不忽略空值的(null或者""),如果要忽略空值,请用AExpr属性表达式构造器的igEmpty()方法。

Pageable pageable = new PageRequest(0, 10, new Sort(Direction.DESC, "userId"));
Page<User> userPage = userDAO.findPage(pageable, AExpr.eq(User_.account, "").igEmpty(),AExpr.contain(User_.userName, "fd"));

含有开始和结束时间 动态查询的处理

@ResponseBody
@RequestMapping("/findpage")
public EasyUIPage findpage(@RequestParam int page,@RequestParam int rows,@RequestParam(required=false) Long employeeid,@RequestParam(required=false) @DateTimeFormat(pattern="yyyy-MM-dd") Date startDate,@RequestParam(required=false) @DateTimeFormat(pattern="yyyy-MM-dd") Date endDate){Pageable pageable=new PageRequest(page<1?0:page-1, rows, new Sort(Direction.DESC,"numId"));_EmployeeName employeeName=employeeid==null?null:MyReflectUtil.createWithSet(_EmployeeName.class, "id", employeeid);Page<DrugOut> pageData=drugOutService.findPage(pageable, AExpr.eq(DrugOut_.employeeName, employeeName).igEmpty(),AExpr.gte(DrugOut_.saledate, startDate).igEmpty(),AExpr.lte(DrugOut_.saledate, endDate).igEmpty());return new EasyUIPage(pageData);
}

注意: 
1).复杂属性的表达式处理:先判断复杂属性的实体的id是否为空
2).动态查询,参数(required=false)、查询的属性表达式列表(igEmpty)

2. 通过解析Repository中的方法名创建查询,是spring-data-jpa的一大特色。符合经典的java三层架构:表现层(UI),业务逻辑层(BLL),数据访问层(DAL) 

这是spring官网的例子:通过EmailAddress和Lastname来查找用户

public interface UserRepository extends Repository<User, Long> {List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
}

详见spring-data-jpa#Query Creation

3. 页面参数封装到实体,然后运用qbe(query by example)。qbe会自动忽略null值 
BaseRepository api:

    //--------------qbe(query by example)--------------------public Page<T> findPage(T example,Pageable pageable);public List<T> findList(T example,Sort sort);public List<T> findList(T example);public T getOne(T example);public long count(T example);

qbe复杂查询只支持String的模糊查询,大于、小于、between and均不支持。
ExampleMatcher例字,嵌套属性模糊匹配

//User有属性logrole
ExampleMatcher matcher=ExampleMatcher.matching().withMatcher("logrole.logRoleName", GenericPropertyMatcher.of(StringMatcher.CONTAINING).ignoreCase());
List<User> users=userDAO.findAll(Example.of(user,matcher));

详见spirng-data-jpa#query-by-example

复杂查询最佳实践

复杂查询,无论是用java代码进行sql拼接还是臃肿的Criteria动态查询都是不推荐的。因为这么做一方面是不够优雅,更重要的是难以维护。Mybatis的流行给了我们很多启发,复杂查询用sql配置文件,是一种灵活且方便维护的方式。
以下两种方式是我推荐大家使用的:

  1. 可用使用@NamedQuery,或spring-data-jpa的@Query
  2. 引入spring-data-jpa-extra这个库

使用说明

  1. 下载本项目,并执行maven install ,在项目引入依赖
  2. 项目中Repository继承BaseRepository,Service接口继承BaseService,ServiceImpl继承BaseServiceImpl;BaseService的接口中有BaseRepository的大部分方法
  3. spring配置如下:
   <!-- 指定 BaseRepositoryFactoryBean --><jpa:repositories base-package="demo,com.slyak.spring.jpa"factory-class="klg.common.dataaccess.BaseRepositoryFactoryBean"entity-manager-factory-ref="entityManagerFactory"transaction-manager-ref="transactionManager" repository-impl-postfix="Impl" /><!-- 配置 freemarkerSqlTemplates解析相关--><bean id="freemarkerSqlTemplates" class="com.slyak.spring.jpa.FreemarkerSqlTemplates"><property name="suffix" value=".sftl" /><property name="templateLocation" value="classpath*:/sqls"/></bean>

如有疑问下载klg-j2ee-dataacess-demo 演示

注意

本项目依赖spring-data-jpa-extra-2.1.2.RELEASE,但我做了一些改动,然后打成jar包
项目地址:https://github.com/klguang/spring-data-jpa-extra/tree/2.1.2.RELEASE

  1. com.slyak.spring.jpa.ContextHolder 访问控制为public,目的是让原来项目中已经存在的BaseRepositoryFactoryBean能工作。
  2. 模板文件名为Entity的java full name
  3. 测试用例跑通

转载于:https://www.cnblogs.com/klguang/p/9797598.html

klg-jpa:spring-data-jpa 最佳实践相关推荐

  1. JPA Spring Data JPA详解

    JPA & Spring Data JPA 一.JPA 1. JPA是什么 JPA(Java Persistence API)Java持久化 API,是一套基于ORM思想的规范. ORM(Ob ...

  2. JPA: Spring Data JPA @OneToMany 注解参数 orphanRemoval,一对多删除详解

    分析了OneToMany级联操作多方的插入.更新.删除.我们得到如下结论: 1.插入,建议一方设置mappedBy,好处是只会执行一条insert语句.不会执行多余的update外键的sql. 2.更 ...

  3. Spring Data JPA例子[基于Spring Boot、Mysql]

    关于Spring Data Spring社区的一个顶级工程,主要用于简化数据(关系型&非关系型)访问,如果我们使用Spring Data来开发程序的话,那么可以省去很多低级别的数据访问操作,如 ...

  4. Spring Boot(五):spring data jpa的使用

    Spring Boot(五):spring data jpa的使用 一.spring data jpa介绍 1,JPA是什么 JPA(Java Persistence API)是Sun官方提出的Jav ...

  5. spring-boot (三) spring data jpa

    学习文章来自:http://www.ityouknow.com/spring-boot.html spring data jpa介绍 首先了解JPA是什么? JPA(Java Persistence ...

  6. hql实例 jpa_SpringBoot学习笔记九:Spring Data Jpa的使用

    Spring Data Jpa 简介 JPA JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338,这些接口 ...

  7. JPA、Hibernate和Spring Data JPA区别

    大家好,我是神韵,是一个技术&生活博主.出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己.二是希望我的文章可以帮到大家.欢迎来点赞打卡,你们的行动将是我无限的动力. 本篇主题是: ...

  8. Spring data JPA使用详解(超详细)

    目录 Jpa 元模型 Criteria查询 CriteriaBuilder 安全查询创建工厂 CriteriaQuery 安全查询主语句 Root Predicate 过滤条件 Predicate 多 ...

  9. 干货|一文读懂 Spring Data Jpa!

    有很多读者留言希望松哥能好好聊聊 Spring Data Jpa!其实这个话题松哥以前零零散散的介绍过,在我的书里也有介绍过,但是在公众号中还没和大伙聊过,因此本文就和大家来仔细聊聊 Spring D ...

  10. 【SpringBoot框架篇】11.Spring Data Jpa实战

    文章目录 1.简介 1.1.JPA 1.2.Spring Data Jpa 1.3.Hibernate 1.4.Jpa.Spring Data Jpa.Hibernate三者之间的关系 2.引入依赖 ...

最新文章

  1. 世界首富贝佐斯将“退休”
  2. Java的登陆验证问题
  3. 服务器性能/压力测试工具http_load、webbench、ab、Siege使用教程
  4. 【Tools】gcc4.4升级到gcc4.8
  5. 一个免费调用的OData服务,无需用户名密码,适用于SAP UI5的学习
  6. jax-rs jax-ws_什么是JAX-RS注释? (第3部分)
  7. wso2 安装_WSO2注册表安装简介
  8. java 打印abcd_用JAVA编程统计字符串ABCD123!@#$%ab中大写字母、小写字母、数字、其它字符的个数并打印出来...
  9. java线程池 synchronized_java多线程学习(二) 之 synchronized
  10. Vue中$refs的理解
  11. struts2漏洞_Apache Struts2057远程代码执行漏洞复现
  12. JDK集合框架结构分析(二)
  13. 面试之js 数组插入删除
  14. VMP 虚拟机(加壳原理)
  15. Mac下librdkafka下载安装
  16. 通用后台管理系统(1)-数据库设计
  17. 15款android设备上的代码编辑器
  18. [cocos2d-x]SpaceFighting[安卓/IOS都适用]
  19. php中COM函数的使用
  20. the owning Session was closed

热门文章

  1. Python爬虫爬取单张图片
  2. 在u盘运行linux系统软件,主编帮你xp系统利用U盘直接运行Linux软件 的步骤【图】...
  3. CHIL-SQL-function 函数
  4. 【生活记录】[2020年]上海居转户流程
  5. 上海市专业计算机学校地址,上海计算机专业学校
  6. Python搞不定蝴蝶图?
  7. Category 类别 -Objective-C
  8. 15、【华为HCIE-Storage】--多路径技术
  9. 华为鸿蒙中标麒麟,华为鸿蒙OS短时间内威胁不到麒麟操作系统和统信UOS系统
  10. 使用Shell脚本对Oracle元数据进行动态版本控制