TemplateQuery
Macula扩展了spring-data-jpa的功能,除了原先可以支持的@Query、@NamedQuery等方法上的注解,Macula提供了TemplateQuery注解。
原先的注解SQL语句不支持动态条件,不能写if等表达式。TemplateQuery注解支持在注解中或者模板文件中编写SQL语句,可以使用freemarker语法编写,具体使用方式如下:
package org.macula.core.test.repository;
...
public UserRepository extends MaculaJpaRepository<User> {
...
@TemplateQuery
public Page<UserVo> findByLastNameVo(@Param("lastName") String lastName, Pageable pageable);
@TemplateQuery
public Page<User> findByLastNameMap(@Param("data") Map<String, Object> data, Pageable pageable);
@TemplateQuery("select * from MY_USER u where 1=1" +
"<#if (data.lastName)??>" +
" and u.last_name = :data.lastName" +
"</#if>" +
"<#if firstNames??>" +
" and u.first_name in (:firstNames)" +
"</#if>")
public Page<User> findByLastNameMapAndList(@Param("data") Map<String, Object> data,
@Param("firstNames") List<String> firstNames, Pageable pageable);
@TemplateQuery
public Page<User> findByLastNameMapAndListx(@Param("data") Map<String, Object> data,
@Param("firstNames") List<String> firstNames, Pageable pageable);
@TemplateQuery
public Page<User> findByLastNameMapy(@Param("data") Map<String, Object> data, Pageable pageable);
@TemplateQuery
public Page<User> findByLastNameMapAndListy(@Param("data") Map<String, Object> data,
@Param("firstNames") List<String> firstNames, Pageable pageable);
}
同时,没有在@TemplateQuery value中写的SQL需要在文件中编写对应的SQL模板:
xml格式模板
xml中编写SQL,文件放在该TemplateQuery方法所属的Repository类路径下,和Repository类名称一致,以xml结尾。例如:src/java/org/macula/core/test/repository/UserRepository.xml
<?xml version="1.0" encoding="utf-8" ?>
<sqls xmlns="http://www.maculaframework.org/schema/repository"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.maculaframework.org/schema/repository http://macula.top/schema/repository/macula-repository-1.0.xsd">
<sql name="findByLastNameVo">
<![CDATA[
select u.first_name, u.last_name from MY_USER u where u.last_name = :lastName
]]>
</sql>
<sql name="findByLastNameMap">
<![CDATA[
select * from MY_USER u where u.last_name = :data.lastName
]]>
</sql>
<sql name="findByLastNameMapAndListx">
<![CDATA[
select * from MY_USER u where 1=1
<#if (data.lastName)??>
and u.last_name = :data.lastName
</#if>
<#if firstNames??>
and u.first_name in (:firstNames)
</#if>
]]>
</sql>
</sqls>
2.sftl格式模板
具体放置路径同XML模板,只是把后缀改为.sftl:
--findByLastNameMapy
select * from MY_USER u where u.last_name = :data.lastName
--findByLastNameMapAndListy
select * from MY_USER u where 1=1
<#if (data.lastName)??>
and u.last_name = :data.lastName
</#if>
<#if firstNames??>
and u.first_name in (:firstNames)
</#if>
TemplateQuery使用优先级
TemplateQuery支持通过注解、文件、配置属性提供SQL,如果出现RepositoryName加MethodName重复,则配置属性优先,注解次之,文件中的SQL最后。
使用通用配置热修复TemplateQuery的SQL
线上运行的系统有时发现TemplateQuery的SQL写得有问题,可以通过Macula支持的基于zookeeper和Nacos的通用配置临时添加一个属性热修复。具体属性KEY是macula.templateQuery.{repositoryName}.{methodName},内容是SQL模板。请谨慎使用,待程序修复后要即时删除该配置,否则永远是这个配置优先。