同步操作将从 klguang/klg-jpa 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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(ide自动生成),快速开发的利器
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) String typeCode,
@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"));
Page<DrugOut> pageData=drugOutService.findPage(pageable,
AExpr.eq(DrugOut_.employeeid, employeeid).igEmpty(),// igEmpty()忽略空值,包括null和""
AExpr.eq(DrugOut_.typeCode, typeCode).igEmpty(),
AExpr.gte(DrugOut_.saledate, startDate).igEmpty(),//大于
AExpr.lte(DrugOut_.saledate, endDate).igEmpty());//小于
return new EasyUIPage(pageData);
}
注意:
1).复杂属性的表达式处理:先判断复杂属性实体的id是否为空
2).动态查询,参数(required=false)、查询的属性表达式列表(igEmpty)
方法 | 说明 |
---|---|
eq | = |
ne | <> |
gt | > |
lt | < |
gte | >= |
lte | <= |
like | 模糊匹配,注意必须包含"%"通配符 |
contain | 包含字符串,即like查询,在两边都有"%"通配符 |
in | in |
between | between |
isNull | isNull |
isNotNull | isNotNull |
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配置文件,是一种灵活且方便维护的方式。
以下两种方式是我推荐大家使用的:
Repository接口
public interface SampleRepository extends BaseRepository<Sample, Long> {
@TemplateQuery
Page<Sample> findByContent(@Param("content") String content, Pageable pageable);
}
com.slyak.spring.jpa.extra.Sample.sftl模板文件
--findByContent
SELECT * FROM t_sample WHERE 1 = 1
<#if content??>
AND content LIKE :content
</#if>
<!-- 指定 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包,放在lib目录下
项目地址:https://github.com/klguang/spring-data-jpa-extra/tree/2.1.2.RELEASE
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。