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. 测试用例跑通

klg-jpa:spring-data-jpa 最佳实践的更多相关文章

  1. spring data jpa 全面解析(实践 + 源码分析)

    前言 本文将从示例.原理.应用3个方面介绍spring data jpa. 以下分析基于spring boot 2.0 + spring 5.0.4版本源码 概述 JPA是什么? JPA (Java ...

  2. 【spring boot 系列】spring data jpa 全面解析(实践 + 源码分析)

    前言 本文将从示例.原理.应用3个方面介绍spring data jpa. 以下分析基于spring boot 2.0 + spring 5.0.4版本源码 概述 JPA是什么? JPA (Java ...

  3. 来说说JPA、Hibernate、Spring Data JPA之间的什么关系?

    目录 JPA Hibernate Spring Data JPA 实践 来说说JPA.Hibernate.Spring Data JPA之间的什么关系 Java 持久层框架访问数据库的方式大致分为两种 ...

  4. JPA && Spring Data && Spring Data JPA

    1.JPA  Java Persistence API,用于对象持久化的一组API,JPA本身是一组规范,让开发者用同一种方式访问不同的ORM框架.其实也就是java实体对象和关系型数据库建立起映射关 ...

  5. SpringBoot入门:Spring Data JPA 和 JPA(理论)

    参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...

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

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

  7. spring-boot (三) spring data jpa

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

  8. springboot:spring data jpa介绍

    转载自:https://www.cnblogs.com/ityouknow/p/5891443.html 在上篇文章springboot(二):web综合开发中简单介绍了一下spring data j ...

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

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

  10. spring boot(五)Spring data jpa介绍

    在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...

随机推荐

  1. (void)0和0的区别及用法

    (void)0相当于宏NULL,NULL本身的含义为“空”,在c语言代表“不存在.不确定”的含义. 0不能简单的理解为“没有”的意思,在c语言及二进制中,0和1代表的是“一件事物的正反两个方面“,0是 ...

  2. jquery获取元素索引值index()

    jquery获取元素索引值index()方法实例. jquery获取元素索引值index()方法: jquery的index()方法 搜索匹配的元素,并返回相应元素的索引值,从0开始计数. 如果不给 ...

  3. python爬虫解析库之re模块

    re模块 一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中, ...

  4. 偏于SQL语句的 sqlAlchemy 增删改查操作

    ORM 江湖 曾几何时,程序员因为惧怕SQL而在开发的时候小心翼翼的写着sql,心中总是少不了恐慌,万一不小心sql语句出错,搞坏了数据库怎么办?又或者为了获取一些数据,什么内外左右连接,函数存储过程 ...

  5. 在sql中根据成绩显示学生排名

    1.准备 create table newtable ( name ), yuwen ), shuxue ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; , ); , ...

  6. Linux下C语言的调试

    调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...

  7. love2d教程32--碎图打包器texturepacker

    texturepacker是一个碎图打包器,可以把小图合并成一张大图,并对大图做优化.我用的是特别版(只好用xx版了, 不然导出的图片会被变成红色),网盘下载,文件会提示有毒,我也是在网上找的,其实是 ...

  8. 软件配置管理中的SVN

    一.简单介绍 1.什么是软件配置管理 软件配置管理是指通过运行版本号控制.变更控制的规程.以及使用合适的配置管理软件.来保证全部配置项的完整性和可跟踪性. 配置管理是对工作成果的一种有效保护. 2.为 ...

  9. lnmp服务器的目录信息

    LNMP状态管理命令: LNMP状态管理: /root/lnmp {start|stop|reload|restart|kill|status}Nginx状态管理:/etc/init.d/nginx ...

  10. 一条经典SQL语句优化实例

    1.概述 如下SQL语句发生严重消耗资源的问题,使得OS's load average会在30以上,一条语句需要执行上百秒. /*PIXPatient 184176条DomainPatient 184 ...