动态SQL/HQL
我们使用hibernate的时候,总是会苦恼,我们的SQL/HQL写入到JAVA代码中导致SQL/HQL很难维护,而且代码中SQL格式很难调节,并且没有继承等等,很多逻辑还需要JAVA代码去判断。说到这里,可能有些人会觉得,Hibernate通过SQL来指定需要查询的字段,会破坏了Hibernate开发的简洁性,但本人觉得,一切框架都是为功能服务,什么方便,我们程序员就使用什么,不然就不是我们在使用框架,而是框架在使用我们。
好了,动态SQL/HQL的语法,他的基础于是继承了Freemarker的语法。并扩展了include_sql、include_hql标签,用于公用的SQL片段的引用。
Mapper XML 文件
Mapper XML配置文件有几个要素:
mapper –XML配置文件根节点,其中namespace只是一个预留,目前没有特别的用处.
sql – 可被其他语句引用的可重用SQL语句块。
hql – 可被其他语句引用的可重用的HQL语句块。
sql-query – SQL查询语句
hql-query – HQL查询语句
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper SYSTEM "http://www.jeeweb.cn/dtd/dynamic-hibernate-statement-1.0.dtd">
<mapper namespace="cn.jeeweb">
<!-- SQL 片段 -->
<sql id="userfield">
<![CDATA[
id,realname
]]>
</sql>
<!-- HQL 片段-->
<hql id="userfield">
<![CDATA[
id,realname
]]>
</hql>
<!-- SQL查询 -->
<sql-query id="sys">
<![CDATA[
select * from sys_user where id=?
]]>
</sql-query>
<!-- HQL查询 -->
<hql-query id="notirication">
<![CDATA[
FROM OaNotificationEntity m WHERE m.title like :title
]]>
</hql-query>
</mapper>
Mapper XML 语法
动态SQL/HQL的语法,他的基础于是继承了Freemarker的语法。并扩展了include_sql、include_hql标签,用于公用的SQL片段的引用。这里重点介绍基本的集中,其他的语法可以参照Freemarker。
- 变量格式${expr}
<sql-query id="sys">
<![CDATA[
select * from sys_user where id=${id}
]]>
</sql-query>
- 判断if…elseif…else语句
动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。比如:<sql-query id="sys.user">
<![CDATA[
select * from sys_user where id=${id}
<#if sex == '男'>
and t.sex=1
<#else>
and t.sex=0
</#if>
]]>
</sql-query>
-
循环<#list productList as p></#list>
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:<sql-query id="sys.user">
<![CDATA[
select * from sys_user where id in
(<#list ids as id>
'${id}'<#if !id_has_next>,</#if>
</list>)
]]>
</sql-query>
list标签的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。
-
sql引用
refid 为Sql片段的ID<sql-query id="sys.user">
<![CDATA[
select<@include_sql refid="userfield" />from sys_user where id='${id}'
]]>
</sql-query>
- hql代码段引用
refid 为HQL片段的ID<hql-query id="sys.user">
<![CDATA[
select<@include_hql
refid="userfield" />from sys_user where id='${id}'
]]>
</hql-query>
-
程序调用。
动态SQL,我们采用ID查找方法来过来SQL判断,或者直接查询列表等等。
在项目中,我们可以使用@Autowired
private IDynamicHibernateAdapter dynamicHibernateAdapter,(一般不建设这样只用);
初始化dynamicHibernateAdapter,通过Adapter中丰富的方法来执行自己想要的操作。
int updateByHqlQueryId(final String queryId, final Object... params);
int updateByAliasHqlQueryId(final String queryId, final Map<String, Object> alias);
Long countByHqlQueryId(final String queryId, final Object... params);
Long countByAliasHqlQueryId(final String queryId, final Map<String, Object> alias);
<T> List<T> listByHqlQueryId(final String queryId, final Object... params);
<T> List<T> listByAliasHqlQueryId(final String queryId, final Map<String, Object> alias);
<T> List<T> listByHqlQueryId(final String queryId, int page, int rows, final Object... params);
List<Map<String, Object>> listMapByHqlQueryId(final String queryId, final Object... params);
List<Map<String, Object>> listMapByHqlQueryId(final String queryId,int page, int rows, final Object... params);
List<Map<String, Object>> listMapByAliasHqlQueryId(final String queryId, final Map<String, Object> alias);
List<Map<String, Object>> listMapByAliasHqlQueryId(final String queryId, int page, int rows,final Map<String, Object> alias);
void executeSqlQueryId(String queryId, final Object... params);
Integer countBySqlQueryId(String queryId, final Object... params);
List<Map<String, Object>> listBySqlQueryId(String queryId, final Object... params);
List<Map<String, Object>> listByAliasSqlQueryId(String queryId, final Map<String, Object> alias);
List<Map<String, Object>> listPageBySqlQueryId(String queryId, int page, int rows, final Object... params);
List<Map<String, Object>> listPageByAliasSqlQueryId(String queryId, int page, int rows,
final Map<String, Object> alias);
<T> List<T> listEntityBySqlQueryId(String queryId, Class<T> entityClass, final Object... params);
<T> List<T> listEntityByAliasSqlQueryId(String queryId, Class<T> entityClass, final Map<String, Object> alias);
<T> List<T> listPageEntityBySqlQueryId(String queryId, int page, int rows, Class<T> entityClass,
final Object... params);
<T> List<T> listPageEntityByAliasSqlQueryId(String queryId, int page, int rows, Class<T> entityClass,
final Map<String, Object> alias);
我们也可以使用Service类的类似方法来执行操作。
@Autowired
private IUserService userService;
查询列表
Map<String, Object> data = new HashMap<String, Object>();
data.put("id", "40288ab85ce3c20a015ce3ca6df60000");
List<Map<String, Object>> dataList = userService.listByAliasSqlQueryId("sys.user", data);
方法:listByAliasSqlQueryId(String queryid,final Map alias);第一个参数对应xml中的ID,第二个参数对应xml中的数据,必须一Map方式传入。
说明:
虽然动态Sql提供了丰富的方法,但是可以通过方法的命名规则就可以识别,(返回数据)+[请求数据的类型]+(类型ID)。如:listByAliasSqlQueryId,及通过SQL别名查询方式获取数据列表。这里SqlQueryId,默认返回List,如果需要返回Entity类行,则使用listPageEntityBySqlQueryId。Hql方式则反之。