data jpa扩展支持动态sql
2018-02-08 10:26
2206 查看
data jpa扩展支持动态sql
更多干货
分布式实战(干货)spring cloud 实战(干货)
mybatis 实战(干货)
spring boot 实战(干货)
React 入门实战(干货)
构建中小型互联网企业架构(干货)
前言
一般在写业务接口的过程中,很有可能需要实现可以动态组合各种查询条件的接口。如果我们根据一种查询条件组合一个方法的做法来写,那么将会有大量方法存在,繁琐,维护起来相当困难。想要实现动态查询,其实就是要实现拼接SQL语句。spring data jpa扩展代码地址github
spring-data-jpa-extra一、如何使用之定义动态sql在文件
sql 默认支持后缀sftl和xml定义sql文件默认与实体类名字相同如:Sample.sftl
使用sftl定义方式
-- findByContent SELECT * FROM t_sample WHERE 1 = 1 <#if content??> AND content LIKE :content </#if> --countContent SELECT count(*) FROM t_sample WHERE 1 = 1 <#if content??> AND content LIKE :content </#if> --findDtos SELECT id, content as contentShow FROM t_sample --findByTemplateQueryObject SELECT * FROM t_sample WHERE 1 = 1 <#if content??> AND content LIKE :content </#if> --findMap SELECT * FROM t_sample
xml方式定义
<?xml version="1.0" encoding="utf-8" ?> <sqls xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.slyak.com/schema/templatequery" xsi:schemaLocation="http://www.slyak.com/schema/templatequery http://www.slyak.com/schema/templatequery.xsd"> <sql name="findByContent"> <![CDATA[ SELECT * FROM t_sample WHERE 1=1 <#if content??> AND content LIKE :content </#if> ]]> </sql> <sql name="countContent"> <![CDATA[ SELECT count(*) FROM t_sample WHERE 1=1 <#if content??> AND content LIKE :content </#if> ]]> </sql> <sql name="findDtos"> <![CDATA[ SELECT id,content as contentShow FROM t_sample ]]> </sql> <sql name="findByTemplateQueryObject"> <![CDATA[ SELECT * FROM t_sample WHERE 1=1 <#if content??> AND content LIKE :content </#if> ]]> </sql> </sqls>
二、如何使用之 SampleRepository
@TemplateQuery 自定义注解:repository 中的方法如果有注解TemplateQuery,则会根据方法名字到对于的文件中查找对于的sqlpublic interface SampleRepository extends GenericJpaRepository<Sample, Long> { @TemplateQuery Page<Sample> findByContent(String content, Pageable pageable); @TemplateQuery List<Sample> findByTemplateQueryObject(SampleQuery sampleQuery, Pageable pageable); @TemplateQuery Long countContent(String content); @TemplateQuery List<SampleDTO> findDtos(); // #{name?:'and content like :name'} @Query(nativeQuery = true, value = "select * from t_sample where content like ?1") List<Sample> findDtos2(String name); @TemplateQuery List<Map<String,Object>> findMap(); }
源代码解析
一、自定义一注解用于区分哪些方法需要使用到动态sql
TemplateQuery.java@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) @QueryAnnotation @Documented public @interface TemplateQuery { String value() default ""; }
二、GenericJpaRepositoryFactory.java
GenericJpaRepositoryFactory 中重写getQueryLookupStrategy(动态创建查询方法)@Override protected QueryLookupStrategy getQueryLookupStrategy(QueryLookupStrategy.Key key, EvaluationContextProvider evaluationContextProvider) { return TemplateQueryLookupStrategy.create(entityManager, key, extractor, evaluationContextProvider); }
三、TemplateQueryLookupStrategy.java
TemplateQueryLookupStrategy 模版查询策略 其中关键代码:@Override public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, ProjectionFactory factory, NamedQueries namedQueries) { if (method.getAnnotation(TemplateQuery.class) == null) { return jpaQueryLookupStrategy.resolveQuery(method, metadata, factory, namedQueries); } else { return new FreemarkerTemplateQuery(new JpaQueryMethod(method, metadata, factory, extractor), entityManager); } }resolveQuery 中解析query。判断方法上是否有注解TemplateQuery。如果有则使用动态sql。如果没有则使用jpa默认
四、FreemarkerTemplateQuery
FreemarkerTemplateQuery 结合freemarker动态构造Query对象关键代码如下
@Override protected TypedQuery<Long> doCreateCountQuery(Object[] values) { TypedQuery query = (TypedQuery) getEntityManager() .createNativeQuery(QueryBuilder.toCountQuery(getQuery(values))); bind(query, values); return query; }
关键类解析
FreemarkerSqlTemplates 从文件中解析sql。使用freemarkerSftlNamedTemplateResolver 解析.sftl文件 其中的sql 使用分隔符-- 隔开
QueryBuilder.toCountQuery 根据select sql 构造出 count sql 查询总条目
相关文章推荐
- 对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
- ”对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成“解决办法
- guzz1.2.8 beta2发布--支持动态加载在线调试SQL
- 【Swift 4.0】扩展 WCDB 支持 SQL 语句
- 对于不返回任何键列信息的 selectcommand 不支持 updatecommand 的动态 sql 生成
- 对于不返回任何键列信息的 SelectCommand 不支持 UpdateCommand 的动态 SQL 生成问题的解决办法
- 扩展Bundle支持动态Bundle和javascript混淆
- 对于不返回任何键列信息的 SelectCommand 不支持 UpdateCommand 的动态 SQL 生成”问题的解决
- 对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成
- 未处理InvalidOperationExcepton:对于不返回任何键列信息的SelectCommand,不支持UpdateCommand的动态SQL生成
- 转载:ASP.NET MVC扩展自定义视图引擎支持多模板&动态换肤skins机制
- sqlserver 支持定位当前页,自定义排序的分页SQL(拒绝动态SQL)
- “对于不返回任何键列信息的 SelectCommand 不支持 UpdateCommand 的动态 SQL 生成”问题的解决
- 动态扩展Nginx支持Lua功能
- ASP.NET网站开发——LINQ to SQL 类动态数据支持
- wampserver增加php对sqlserver的支持,增加sqlsrv和pdo_sqlsrv扩展
- easyui 扩展layout的方法,支持动态添加删除块
- 代码中(C#)支持动态拼接SQL的参数化查询
- 对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成