hibernate显示sql语句 Restrictions.sqlRestriction 在查询条件中添加sql语句在多表关联是{alias}怎么用?

查看文章 hibernate Restrictions用法
Restrictions.eq
Restrictions.allEq
利用Map来进行多个等于的限制
Restrictions.gt
Restrictions.ge
Restrictions.lt
Restrictions.le
Restrictions.between
Restrictions.like
Restrictions.in
Restrictions.and
Restrictions.or
Restrictions.sqlRestriction
用SQL限定查询
有空再添加上,代码示例。
QBC常用限定方法
Restrictions.eq --& equal,等于.
Restrictions.allEq --& 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果
Restrictions.gt --& great-than & 大于
Restrictions.ge --& great-equal &= 大于等于
Restrictions.lt --& less-than, & 小于
Restrictions.le --& less-equal &= 小于等于
Restrictions.between --& 对应SQL的between子句
Restrictions.like --& 对应SQL的LIKE子句
Restrictions.in --& 对应SQL的in子句
Restrictions.and --& and 关系
Restrictions.or --& or 关系
Restrictions.isNull --& 判断属性是否为空,为空则返回true
Restrictions.isNotNull --& 与isNull相反
Restrictions.sqlRestriction --& SQL限定的查询
Order.asc --& 根据传入的字段进行升序排序
Order.desc --& 根据传入的字段进行降序排序
MatchMode.EXACT --& 字符串精确匹配.相当于&like 'value'&
MatchMode.ANYWHERE --& 字符串在中间匹配.相当于&like '%value%'&
MatchMode.START --& 字符串在最前面的位置.相当于&like 'value%'&
MatchMode.END --& 字符串在最后面的位置.相当于&like '%value'&
查询年龄在20-30岁之间的所有学生对象
List list = session.createCriteria(Student.class)
.add(Restrictions.between(&age&,new Integer(20),new Integer(30)).list();
查询学生姓名在AAA,BBB,CCC之间的学生对象
String[] names = {&AAA&,&BBB&,&CCC&};
List list = session.createCriteria(Student.class)
.add(Restrictions.in(&name&,names)).list();
查询年龄为空的学生对象
List list = session.createCriteria(Student.class)
.add(Restrictions.isNull(&age&)).list();
查询年龄等于20或者年龄为空的学生对象
List list = session.createCriteria(Student.class)
.add(Restrictions.or(Restrictions.eq(&age&,new Integer(20)),
Restrictions.isNull(&age&)).list();
--------------------------------------------------------------------
使用QBC实现动态查询
public List findStudents(String name,int age){
Criteria criteria = session.createCriteria(Student.class);
if(name != null){
criteria.add(Restrictions.liek(&name&,name,MatchMode.ANYWHERE));
if(age != 0){
criteria.add(Restrictions.eq(&age&,new Integer(age)));
criteria.addOrder(Order.asc(&name&));//根据名字升序排列
return criteria.list();
-----------------------------------------------------------------------------------
今天用了写hibernate高级查询时用了Restrictions(当然Expression也是可以以的)这个类.感觉不错.
下面的代码写的不易读.其实核心就是一句
Restrictions.or(Restrictions.like(),Restrictions.or(Restrictions.like,........))
里面的or可以无限加的.还是比较好用
Session session = getHibernateTemplate().getSessionFactory()
.openSession();
Criteria criteria = session.createCriteria(Film.class);
List&Film& list = criteria.add(
Restrictions.or(Restrictions.like(&description&, key,MatchMode.ANYWHERE),
Restrictions.or(Restrictions.like(&name&, key,MatchMode.ANYWHERE),
Restrictions.or(&&& Restrictions.like(&direct&, key,MatchMode.ANYWHERE),
Restrictions.or(Restrictions.like(&mainplay&,key,MatchMode.ANYWHERE),
Restrictions.like(&filearea&, key,MatchMode.ANYWHERE)))))).list();
session.close();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:17907次
排名:千里之外
原创:15篇
转载:22篇
(2)(1)(4)(2)(2)(8)(2)(1)(1)(4)(1)(9)> Hibernate Criteria查询有关问题:连表查询增加关联条件(生成的sql条件指定到on后面)
Hibernate Criteria查询有关问题:连表查询增加关联条件(生成的sql条件指定到on后面)
guazixing & &
发布时间: & &
浏览:7 & &
回复:0 & &
悬赏:0.0希赛币
Hibernate Criteria查询问题:连表查询增加关联条件(生成的sql条件指定到on后面)代码如下:&
Session&session=this.getHibernateTemplate().getSessionFactory().getCurrentSession();&
session.createCriteria(ProjectBD.class,"h")&
.add(Restrictions.eq("h.xmguid",&xmguid))&
.addOrder(Order.desc("h.subtime"))&
.createAlias("bidCompany",&"b",Criteria.LEFT_JOIN)&
.add(Restrictions.eq("b.xxx",&1))&
这里连表生成的sql语句中b.xxx这个条件是在where后面的,怎么加到&left&join&...&on&(&这里&)&直接where&,,,还有and&啊。。
from&ProjectBD&p&left&join&p.bidCompany&b&where&xmguid= &&and&b.xxxxx= &order&by&subtime&&不行吗?用着中动态的查询的话,是不能多表关联的!建议用hql吧!顶上去啊,没人回答?没人知道?该回复于 16:35:02被管理员删除引用:  用着中动态的查询的话,是不能多表关联的!建议用hql吧!
用hql怎么写条件呢
from&ProjectBD&p&left&join&p.bidCompany&b&where&xmguid= &order&by&subtime
这个b.xxx这个条件怎么加上去?(加到on后面而不是where后面)引用:  直接where&,,,还有and&啊。。
from&ProjectBD&p&left&join&p.bidCompany&b&where&xmguid= &&and&b.xxxxx= &order&by&subtime&&不行吗?
这样不行的,加到where后面会影响返回的结果
这问题自己解决了,解决方法就是加filter&
&set&name="bdBidCompany"&cascade="all"&inverse="true"&sort="natural"$>$
&&&&&key&column="XMGUID"&/$>$
&&&&&one-to-many&class="procurement.bean.BDBidCompany"&/$>$
&&&&&filter&name="ifzhongbiaoFilter"&condition="ifzhongbiao=:ifzhongbiao"/$>$
&filter-def&name="ifzhongbiaoFilter"$>$
&&&&&filter-param&name="ifzhongbiao"&type="integer"/$>$
&/filter-def$>$
然后代码中这样&
Session&session=this.getHibernateTemplate().getSessionFactory().getCurrentSession();&
session.enableFilter("ifzhongbiaoFilter").setParameter("ifzhongbiao",&1);&  &set&name="bdBidCompany"&cascade="all"&inverse="true"&sort="natural"$>$
&&&&&key&column="XMGUID"&/$>$
&&&&&one-to-many&class="procurement.bean.BDBidCompany"&/$>$
&&&&&filter&name="ifzhongbiaoFilter"&condition="ifzhongbiao=:ifzhongbiao"/$>$
&filter-def&name="ifzhongbiaoFilter"$>$
&&&&&filter-param&name="ifzhongbiao"&type="integer"/$>$
&/filter-def$>$
  Session&session=this.getHibernateTemplate().getSessionFactory().getCurrentSession();&
session.enableFilter("ifzhongbiaoFilter").setParameter("ifzhongbiao",&1);&&
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&hibernate根据条件动态组装sql/hql语句(仿ibatis动态查询语句功能)
java简单例子
发布时间: 18:31:52
1.功能需求背景
& 项目中使用hibernate作为数据持久层框架,主要考虑hibernate在进行一些简单的crud操作时非常便利,不需要和ibatis似的为每个sql操作都写一堆文件,但是同时也带来了一些局限性,如类似ibatis强大的动态查询功能用不了了,但是这个功能在项目中的应用场景又很大,hibernate自身也支持将sql/hql语句写在.hbm.xml映射文件中&sql-query&和&query&元素,但是这个功能只能对那些查询限制条件固定的sql有用,对于需要动态拼接的sql语句,hibernate就显得力不从心了,如何给hibernate插上ibatis动态查询的翅膀,既保留crud的简洁性,又能收获ibatis的特性呢?接下来的文章将会重点介绍
2.设计思路
& 先看一下ibatis的动态查询时怎么做的
&&&& &select id=&getUserList& resultMap=&user&&
&&&&&&&& select * from user
&&&&&&&&&&& &isGreaterThan prepend=&and& property=&id& compareValue=&0&&
&&&&&&&&&&&&&&&&&& where user_id = #userId#
&&&&&&&&&&& &/isGreaterThan&
&&&&&&&&&&&& order by createTime desc
&&& &/select&
& ibatis在程序实现内部回去解析sql语句中的标签,然后去解析计算,我们在ibatis在实现的时候也参考了这个解决思路,但是否是需要把ibatis里的解析sql的语法都抄到我们的dao框架中呢-显然这样太复杂了,而且ibatis自己的sql元素是和那些resultMap等是绑定在一起用的,而在hibernate是没用这些东西的,要改造这些东西是一项非常浩大的工程,因此这个方案被放弃了
& 我们在实现的时候采取了一种非常简洁又功能强大的方式-模板技术!对,就是利用freemarker把sql/hql中的动态拼接条件判断语法都交给freemarker语法去处理,这样既能复用freemarker框架,又保持了我们框架设计的简洁性-不需要自己写过多的处理逻辑,以下是我们需要进行动态处理的sql/hql语句的样例
&?xml version=&1.0& encoding=&utf-8&?& &!DOCTYPE dynamic-hibernate-statement PUBLIC &-//Haier/HOP Hibernate Dynamic Statement DTD 1.0//EN& &/dtd/dynamic-hibernate-statement-1.0.dtd&& &dynamic-hibernate-statement&
&!-- 查询某个资源下的直接子节点 --&
&hql-query name=&resource.getChildren&&
from Resource where parent.id=${parentId} and parent.id != id
&/hql-query&
&!-- 查询系统中所有的root资源 --&
&hql-query name=&resource.getRoots&&
from Resource where parent.id = id order by orderIndex
&/hql-query&
&!-- 获取某个用户可访问的某个资源下的所有子资源 --&
&sql-query name=&resource.getDescendants&&
select distinct t.id,
t.description,
t.configuration,
t.module_name,
t.gmt_create,
t.gmt_modified,
t.create_by,
t.last_modified_by,
t.order_index,
t.parent_id
from resource_info t
inner join role_resource rr
on t.id = rr.resource_id
inner join user_role ur
on rr.role_id = ur.role_id
where ur.user_id = ${userId}
&#if type == '1'&
and t.type=1
and t.type=0
and t.type =
and t.status =
start with t.code = '${code}'
connect by nocycle prior t.id = t.parent_id
&/sql-query& &/dynamic-hibernate-statement&这个文件看起来非常类似ibatis的语句了,只是没用ibatis的哪些标签-改成了freemarker语法,没错,我们就是复用freemarker来帮我们解决这些烦杂的判断操作的
这样我们的动态sql程序就可以总结成以下流程
a.系统加载阶段
& 这个阶段程序负责将指定路径下的动态sql文件加载到内存中,一次性缓存起来,没错,这些东西只需要加载一次,以后直接读取就行了,没必要每次去查找,缓存也非常简单,一个Map&String,String&就搞定,key是sql-query或hql-query元素的name属性,value就是与其对应的sql/hql语句
b.程序调用查询阶段
&& 调用程序通过sql/hql语句的name属性和传入查询参数来得到最终解析出来的语句
我们期望的方法可能是这样的:
public &X& List&X& findByNamedQuery(final String queryName, final Map&String, ?& parameters) 通过queryName从缓存中查找出其对应的sql/hql语句(最原始的,里面带有freemarker语法)
然后通过freemarker模板和传递进去的parameters参数对模板进行解析,得到最终的语句(纯sql/hql)
最后将解析后的sql/hql传递给底层api,返回查询结果
& 上面介绍了大致的思路,这里介绍具体的代码实现
& 3.1DTD定义
&&&&& 我们是把动态的sql/hql语句放在单独的xml配置文件里的,为了规范xml文档,我们给文档定义了dtd文件,这里我们只定义了两个元素&sql-query&和&hql-query&分别表示sql查询语句和hql查询语句,这两个元素目前自有一个name属性用来唯一标示该语句,如下
&!-- HOP Hibernate Dynamic Statement Mapping DTD.
&!DOCTYPE dynamic-hibernate-statement PUBLIC
&-//Haier/HOP Hibernate Dynamic Statement DTD 1.0//EN&
&/dtd/dynamic-hibernate-statement-1.0.dtd&&
这个文件时用来定义动态参数语句,类似itabis
The document root.
&!ELEMENT dynamic-hibernate-statement (
(hql-query|sql-query)* )&
&!-- default: none --&
&!-- The query element declares a named Hibernate query string --&
&!ELEMENT hql-query (#PCDATA)&
&!ATTLIST hql-query name CDATA #REQUIRED&
&!-- The sql-query element declares a named SQL query string --&
&!ELEMENT sql-query (#PCDATA)&
&!ATTLIST sql-query name CDATA #REQUIRED&
然后将其保存为dynamic-hibernate-statement-1.0.dtd,放在classpath下
编写DTD校验器
* hibernate动态sql dtd解析器
* @author WangXuzheng
*/ public class DynamicStatementDTDEntityResolver implements EntityResolver, Serializable{
private static final long serialVersionUID = 4762965L;
private static final Logger LOGGER = LoggerFactory.getLogger( DynamicStatementDTDEntityResolver.class );
private static final String HOP_DYNAMIC_STATEMENT = &/dtd/&;
public InputSource resolveEntity(String publicId, String systemId) {
InputSource source = // returning null triggers default behavior
if ( systemId != null ) {
LOGGER.debug( &trying to resolve system-id [& + systemId + &]& );
if ( systemId.startsWith( HOP_DYNAMIC_STATEMENT ) ) {
LOGGER.debug( &recognized hop dyanmic attempting to resolve on classpath under com/haier/openplatform/dao/hibernate/& );
source = resolveOnClassPath( publicId, systemId, HOP_DYNAMIC_STATEMENT );
private InputSource resolveOnClassPath(String publicId, String systemId, String namespace) {
InputSource source =
String path = &com/haier/openplatform/dao/hibernate/& + systemId.substring( namespace.length() );
InputStream dtdStream = resolveInHibernateNamespace( path );
if ( dtdStream == null ) {
LOGGER.debug( &unable to locate [& + systemId + &] on classpath& );
if ( systemId.substring( namespace.length() ).indexOf( &2.0& ) & -1 ) {
LOGGER.error( &Don't use old DTDs, read the Hibernate 3.x Migration Guide!& );
LOGGER.debug( &located [& + systemId + &] in classpath& );
source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
protected InputStream resolveInHibernateNamespace(String path) {
return this.getClass().getClassLoader().getResourceAsStream( path );
protected InputStream resolveInLocalNamespace(String path) {
return ConfigHelper.getUserResourceAsStream( path );
catch ( Throwable t ) {
3.2编写sql文件
&?xml version=&1.0& encoding=&utf-8&?& &!DOCTYPE dynamic-hibernate-statement PUBLIC &-//Haier/HOP Hibernate Dynamic Statement DTD 1.0//EN& &/dtd/dynamic-hibernate-statement-1.0.dtd&& &dynamic-hibernate-statement&
&!-- 查询某个资源下的直接子节点 --&
&hql-query name=&resource.getChildren&&
from Resource where parent.id=${parentId} and parent.id != id
&/hql-query&
&!-- 查询系统中所有的root资源 --&
&hql-query name=&resource.getRoots&&
from Resource where parent.id = id order by orderIndex
&/hql-query&
&!-- 获取某个用户可访问的某个资源下的所有子资源 --&
&sql-query name=&resource.getDescendants&&
select distinct t.id,
t.description,
t.configuration,
t.module_name,
t.gmt_create,
t.gmt_modified,
t.create_by,
t.last_modified_by,
t.order_index,
t.parent_id
from resource_info t
inner join role_resource rr
on t.id = rr.resource_id
inner join user_role ur
on rr.role_id = ur.role_id
where ur.user_id = ${userId}
&#if type == '1'&
and t.type=1
and t.type=0
and t.type =
and t.status =
start with t.code = '${code}'
connect by nocycle prior t.id = t.parent_id
&/sql-query& &/dynamic-hibernate-statement&3.3加载动态sql文件
这里我们将加载sql/hql语句的程序独立到一个单独的类中,以便独立扩展
这里一共3个方法,分表标示获取系统中sql/hql语句的map(key:语句名称,value:具体的)
* 动态sql/hql语句组装器
* @author WangXuzheng
*/ public interface DynamicHibernateStatementBuilder {
* hql语句map
public Map&String,String& getNamedHQLQueries();
* sql语句map
public Map&String,String& getNamedSQLQueries();
* @throws IOException
public void init() throws IOE }默认的加载器-将指定配置文件中的sql/hql语句加载到内存中/**
* @author WangXuzheng
*/ public class DefaultDynamicHibernateStatementBuilder implements DynamicHibernateStatementBuilder, ResourceLoaderAware {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDynamicHibernateStatementBuilder.class);
private Map&String, String& namedHQLQ
private Map&String, String& namedSQLQ
private String[] fileNames = new String[0];
private ResourceLoader resourceL
private EntityResolver entityResolver = new DynamicStatementDTDEntityResolver();
* 查询语句名称缓存,不允许重复
private Set&String& nameCache = new HashSet&String&();
public void setFileNames(String[] fileNames) {
this.fileNames = fileN
public Map&String, String& getNamedHQLQueries() {
return namedHQLQ
public Map&String, String& getNamedSQLQueries() {
return namedSQLQ
public void init() throws IOException {
namedHQLQueries = new HashMap&String, String&();
namedSQLQueries = new HashMap&String, String&();
boolean flag = this.resourceLoader instanceof ResourcePatternR
for (String file : fileNames) {
if (flag) {
Resource[] resources = ((ResourcePatternResolver) this.resourceLoader).getResources(file);
buildMap(resources);
Resource resource = resourceLoader.getResource(file);
buildMap(resource);
//clear name cache
nameCache.clear();
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceL
private void buildMap(Resource[] resources) throws IOException {
if (resources == null) {
for (Resource resource : resources) {
buildMap(resource);
@SuppressWarnings({ &rawtypes& })
private void buildMap(Resource resource) {
InputSource inputSource =
inputSource = new InputSource(resource.getInputStream());
XmlDocument metadataXml = MappingReader.INSTANCE.readMappingDocument(entityResolver, inputSource,
new OriginImpl(&file&, resource.getFilename()));
if (isDynamicStatementXml(metadataXml)) {
final Document doc = metadataXml.getDocumentTree();
final Element dynamicHibernateStatement = doc.getRootElement();
Iterator rootChildren = dynamicHibernateStatement.elementIterator();
while (rootChildren.hasNext()) {
final Element element = (Element) rootChildren.next();
final String elementName = element.getName();
if (&sql-query&.equals(elementName)) {
putStatementToCacheMap(resource, element, namedSQLQueries);
} else if (&hql-query&.equals(elementName)) {
putStatementToCacheMap(resource, element, namedHQLQueries);
} catch (Exception e) {
LOGGER.error(e.toString());
throw new SysException(e);
} finally {
if (inputSource != null && inputSource.getByteStream() != null) {
inputSource.getByteStream().close();
} catch (IOException e) {
LOGGER.error(e.toString());
throw new SysException(e);
private void putStatementToCacheMap(Resource resource, final Element element, Map&String, String& statementMap)
throws IOException {
String sqlQueryName = element.attribute(&name&).getText();
Validate.notEmpty(sqlQueryName);
if (nameCache.contains(sqlQueryName)) {
throw new SysException(&重复的sql-query/hql-query语句定义在文件:& + resource.getURI() + &中,必须保证name的唯一.&);
nameCache.add(sqlQueryName);
String queryText = element.getText();
statementMap.put(sqlQueryName, queryText);
private static boolean isDynamicStatementXml(XmlDocument xmlDocument) {
return &dynamic-hibernate-statement&.equals(xmlDocument.getDocumentTree().getRootElement().getName());
} }配置一下 &bean id=&dynamicStatementBuilder& class=&com.haier.openplatform.dao.hibernate.support.DefaultDynamicHibernateStatementBuilder&&
&property name=&fileNames&&
&value&classpath*:/**/*-dynamic.xml&/value&&!--这里我们指定要加载某个文件夹下所有以-dynamic.xml结尾的文件 --&
&/property&
&/bean& &&& &bean id=&baseHibernateDAO& class=&com.haier.openplatform.dao.hibernate.BaseDAOHibernateImpl& abstract=&true&& && &&& &&property name=&sessionFactory&& && &&& &&& &&ref bean=&sessionFactory&/& && &&& &&/property& && &&& &&property name=&dynamicStatementBuilder& ref=&dynamicStatementBuilder&/& && &&/bean& dao层代码/**
* Hibernate实现的DAO层
* @param &T& DAO操作的对象类型
* @param &ID& 主键类型
* @author WangXuzheng
*/ public class SimpleHibernateDAO&T,ID extends Serializable& implements BaseDAO&T, ID&,InitializingBean{
private static final Logger LOGER = LoggerFactory.getLogger(SimpleHibernateDAO.class);
protected SessionFactory sessionF
protected Class&T& entityC
* 模板缓存
protected Map&String, StatementTemplate& templateC
protected DynamicHibernateStatementBuilder dynamicStatementB
* 通过子类的泛型定义取得对象类型Class.
* public class UserDao extends SimpleHibernateDao&User, Long&
public SimpleHibernateDAO() {
this.entityClass = Reflections.getSuperClassGenricType(getClass());
* 取得sessionFactory.
public SessionFactory getSessionFactory() {
return sessionF
* 采用@Autowired按类型注入SessionFactory, 当有多个SesionFactory的时候在子类重载本函数.
public void setSessionFactory(final SessionFactory sessionFactory) {
this.sessionFactory = sessionF
public void setDynamicStatementBuilder(DynamicHibernateStatementBuilder dynamicStatementBuilder) {
this.dynamicStatementBuilder = dynamicStatementB
* 取得当前Session.
public Session getSession() {
return sessionFactory.getCurrentSession();
* 保存新增或修改的对象.
public void save(final T entity) {
Validate.notNull(entity, &entity不能为空&);
getSession().save(entity);
LOGER.debug(&save entity: {}&, entity);
* 删除对象.
* @param entity 对象必须是session中的对象或含id属性的transient对象.
public void delete(final T entity) {
if(entity == null){
getSession().delete(entity);
LOGER.debug(&delete entity: {}&, entity);
* 按id删除对象.
public void delete(final ID id) {
Validate.notNull(id, &id不能为空&);
delete(get(id));
LOGER.debug(&delete entity {},id is {}&, entityClass.getSimpleName(), id);
* 按id获取对象.
@SuppressWarnings(&unchecked&)
public T get(final ID id) {
Validate.notNull(id, &id不能为空&);
return (T) getSession().get(entityClass, id);
* 按id列表获取对象列表.
public List&T& get(final Collection&ID& ids) {
return find(Restrictions.in(getIdName(), ids));
* 获取全部对象.
public List&T& getAll() {
return find();
* 获取全部对象, 支持按属性行序.
@SuppressWarnings(&unchecked&)
public List&T& getAll(String orderByProperty, boolean isAsc) {
Criteria c = createCriteria();
if (isAsc) {
c.addOrder(Order.asc(orderByProperty));
c.addOrder(Order.desc(orderByProperty));
return c.list();
* 按属性查找对象列表, 匹配方式为相等.
public List&T& findBy(final String propertyName, final Object value) {
Criterion criterion = Restrictions.eq(propertyName, value);
return find(criterion);
* 按属性查找唯一对象, 匹配方式为相等.
@SuppressWarnings(&unchecked&)
public T findUniqueBy(final String propertyName, final Object value) {
Criterion criterion = Restrictions.eq(propertyName, value);
return ((T) createCriteria(criterion).uniqueResult());
* 按HQL查询对象列表.
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findByHQL(final String hql, final Object... values) {
return createHQLQuery(hql, values).list();
* 按HQL查询对象列表,并将对象封装成指定的对象
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findByHQLRowMapper(RowMapper&X& rowMapper,final String hql, final Object... values) {
Validate.notNull(rowMapper, &rowMapper不能为空!&);
List&Object[]& result = createHQLQuery(hql, values).list();
return buildListResultFromRowMapper(rowMapper, result);
protected &X& List&X& buildListResultFromRowMapper(RowMapper&X& rowMapper, List&Object[]& result) {
List&X& rs = new ArrayList&X&(result.size());
for(Object[] obj : result){
rs.add(rowMapper.fromColumn(obj));
* 按SQL查询对象列表.
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findBySQLRowMapper(RowMapper&X& rowMapper,final String sql, final Object... values) {
Validate.notNull(rowMapper, &rowMapper不能为空!&);
List&Object[]& result = createSQLQuery(sql, values).list();
return buildListResultFromRowMapper(rowMapper, result);
* 按SQL查询对象列表,并将结果集转换成指定的对象列表
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findBySQL(final String sql, final Object... values) {
return createSQLQuery(sql, values).list();
* 按HQL查询对象列表.
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findByHQL(final String hql, final Map&String, ?& values) {
return createHQLQuery(hql, values).list();
* 按HQL查询对象列表,并将结果集封装成对象列表
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findByHQLRowMapper(RowMapper&X& rowMapper,final String hql, final Map&String, ?& values) {
Validate.notNull(rowMapper, &rowMapper不能为空!&);
List&Object[]& result = createHQLQuery(hql, values).list();
return buildListResultFromRowMapper(rowMapper, result);
* 按SQL查询对象列表.
* @param sql SQL查询语句
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findBySQL(final String sql, final Map&String, ?& values) {
return createSQLQuery(sql, values).list();
* 查询在xxx.hbm.xml中配置的查询语句
* @param queryName 查询的名称
* @param parameters 参数
public &X& List&X& findByNamedQuery(final String queryName, final Map&String, ?& parameters) {
StatementTemplate statementTemplate = templateCache.get(queryName);
String statement = processTemplate(statementTemplate,parameters);
if(statementTemplate.getType() == StatementTemplate.TYPE.HQL){
return this.findByHQL(statement);
return this.findBySQL(statement);
* 查询在xxx.hbm.xml中配置的查询语句
* @param rowMapper
* @param queryName 查询的名称
* @param parameters 参数
public &X& List&X& findByNamedQuery(RowMapper&X& rowMapper,final String queryName, final Map&String, ?& parameters) {
StatementTemplate statementTemplate = templateCache.get(queryName);
String statement = processTemplate(statementTemplate,parameters);
if(statementTemplate.getType() == StatementTemplate.TYPE.HQL){
return this.findByHQLRowMapper(rowMapper,statement);
return this.findBySQLRowMapper(rowMapper,statement);
* 按SQL查询对象列表,并将结果集封装成对象列表
* @param sql SQL查询语句
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& List&X& findBySQLRowMapper(RowMapper&X& rowMapper,final String sql, final Map&String, ?& values) {
Validate.notNull(rowMapper, &rowMapper不能为空!&);
List&Object[]& result = createSQLQuery(sql, values).list();
return buildListResultFromRowMapper(rowMapper, result);
* 按HQL查询唯一对象.
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& X findUniqueByHQL(final String hql, final Object... values) {
return (X) createHQLQuery(hql, values).uniqueResult();
* 按SQL查询唯一对象.
* @param values 数量可变的参数,按顺序绑定.
@SuppressWarnings(&unchecked&)
public &X& X findUniqueBySQL(final String sql, final Object... values) {
return (X) createSQLQuery(sql, values).uniqueResult();
* 按HQL查询唯一对象.
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& X findUniqueByHQL(final String hql, final Map&String, ?& values) {
return (X) createHQLQuery(hql, values).uniqueResult();
* 按HQL查询唯一对象.
* @param sql sql语句
* @param values 命名参数,按名称绑定.
@SuppressWarnings(&unchecked&)
public &X& X findUniqueBySQL(final String sql, final Map&String, ?& values) {
return (X) createSQLQuery(sql, values).uniqueResult();
* 执行HQL进行批量修改/删除操作.
* @param values 数量可变的参数,按顺序绑定.
* @return 更新记录数.
public int batchExecuteHQL(final String hql, final Object... values) {
return createHQLQuery(hql, values).executeUpdate();
* 执行SQL进行批量修改/删除操作.
* @param sql sql语句
* @param values 数量可变的参数,按顺序绑定.
* @return 更新记录数.
public int batchExecuteSQL(final String sql, final Object... values) {
return createSQLQuery(sql, values).executeUpdate();
* 执行HQL进行批量修改/删除操作.
* @param values 命名参数,按名称绑定.
* @return 更新记录数.
public int batchExecuteHQL(final String hql, final Map&String, ?& values) {
return createHQLQuery(hql, values).executeUpdate();
* 执行SQL进行批量修改/删除操作.
* @param values 命名参数,按名称绑定.
* @return 更新记录数.
public int batchExecuteSQL(final String sql, final Map&String, ?& values) {
return createSQLQuery(sql, values).executeUpdate();
* 根据查询HQL与参数列表创建Query对象.
* 与find()函数可进行更加灵活的操作.
* @param values 数量可变的参数,按顺序绑定.
public Query createHQLQuery(final String queryString, final Object... values) {
Query query = getSession().createQuery(queryString);
if (values != null) {
for (int i = 0; i & values. i++) {
query.setParameter(i, values[i]);
* 根据查询SQL与参数列表创建Query对象.
* 与find()函数可进行更加灵活的操作.
* @param sqlQueryString sql语句
* @param values 数量可变的参数,按顺序绑定.
public Query createSQLQuery(final String sqlQueryString, final Object... values) {
Query query = getSession().createSQLQuery(sqlQueryString);
if (values != null) {
for (int i = 0; i & values. i++) {
query.setParameter(i, values[i]);
* 根据查询HQL与参数列表创建Query对象.
* 与find()函数可进行更加灵活的操作.
* @param values 命名参数,按名称绑定.
public Query createHQLQuery(final String queryString, final Map&String, ?& values) {
Query query = getSession().createQuery(queryString);
if (values != null) {
query.setProperties(values);
* 根据查询SQL与参数列表创建Query对象.
* 与find()函数可进行更加灵活的操作.
* @param queryString SQL语句
* @param values 命名参数,按名称绑定.
public Query createSQLQuery(final String queryString, final Map&String, ?& values) {
Query query = getSession().createSQLQuery(queryString);
if (values != null) {
query.setProperties(values);
* 按Criteria查询对象列表.
* @param criterions 数量可变的Criterion.
@SuppressWarnings(&unchecked&)
public List&T& find(final Criterion... criterions) {
return createCriteria(criterions).list();
* 按Criteria查询唯一对象.
* @param criterions 数量可变的Criterion.
@SuppressWarnings(&unchecked&)
public T findUnique(final Criterion... criterions) {
return (T) createCriteria(criterions).uniqueResult();
* 根据Criterion条件创建Criteria.
* 与find()函数可进行更加灵活的操作.
* @param criterions 数量可变的Criterion.
public Criteria createCriteria(final Criterion... criterions) {
Criteria criteria = getSession().createCriteria(entityClass);
for (Criterion c : criterions) {
criteria.add(c);
* 初始化对象.
* 使用load()方法得到的仅是对象Proxy, 在传到View层前需要进行初始化.
* 如果传入entity, 则只初始化entity的直接属性,但不会初始化延迟加载的关联集合和属性.
* 如需初始化关联属性,需执行:
* Hibernate.initialize(user.getRoles()),初始化User的直接属性和关联集合.
* Hibernate.initialize(user.getDescription()),初始化User的直接属性和延迟加载的Description属性.
public void initProxyObject(Object proxy) {
Hibernate.initialize(proxy);
* Flush当前Session.
public void flush() {
getSession().flush();
* 为Query添加distinct transformer.
* 预加载关联对象的HQL会引起主对象重复, 需要进行distinct处理.
public Query distinct(Query query) {
query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
* 为Criteria添加distinct transformer.
* 预加载关联对象的HQL会引起主对象重复, 需要进行distinct处理.
public Criteria distinct(Criteria criteria) {
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
* 取得对象的主键名.
public String getIdName() {
ClassMetadata meta = getSessionFactory().getClassMetadata(entityClass);
return meta.getIdentifierPropertyName();
* 判断对象的属性值在数据库内是否唯一.
* 在修改对象的情景下,如果属性新修改的值(value)等于属性原来的值(orgValue)则不作比较.
public boolean isPropertyUnique(final String propertyName, final Object newValue, final Object oldValue) {
if (newValue == null || newValue.equals(oldValue)) {
Object object = findUniqueBy(propertyName, newValue);
return (object == null);
public void update(T object) {
getSession().update(object);
@SuppressWarnings(&unchecked&)
public T load(ID id) {
return (T) getSession().load(this.entityClass, id);
* 将list转化为数组
* @param list
protected Criterion[] list2Array(List&Criterion& list){
if(list == null){
return new Criterion[0];
Criterion[] result = new Criterion[list.size()];
for(int i = 0; i & list.size(); i++){
result[i] = list.get(i);
public void afterPropertiesSet() throws Exception {
templateCache = new HashMap&String, StatementTemplate&();
if(this.dynamicStatementBuilder == null){
this.dynamicStatementBuilder = new NoneDynamicHibernateStatementBuilder();
dynamicStatementBuilder.init();
Map&String,String& namedHQLQueries = dynamicStatementBuilder.getNamedHQLQueries();
Map&String,String& namedSQLQueries = dynamicStatementBuilder.getNamedSQLQueries();
Configuration configuration = new Configuration();
configuration.setNumberFormat(&#&);
StringTemplateLoader stringLoader = new StringTemplateLoader();
for(Entry&String, String& entry : namedHQLQueries.entrySet()){
stringLoader.putTemplate(entry.getKey(), entry.getValue());
templateCache.put(entry.getKey(), new StatementTemplate(StatementTemplate.TYPE.HQL,new Template(entry.getKey(),new StringReader(entry.getValue()),configuration)));
for(Entry&String, String& entry : namedSQLQueries.entrySet()){
stringLoader.putTemplate(entry.getKey(), entry.getValue());
templateCache.put(entry.getKey(), new StatementTemplate(StatementTemplate.TYPE.SQL,new Template(entry.getKey(),new StringReader(entry.getValue()),configuration)));
configuration.setTemplateLoader(stringLoader);
protected String processTemplate(StatementTemplate statementTemplate,Map&String, ?& parameters){
StringWriter stringWriter = new StringWriter();
statementTemplate.getTemplate().process(parameters, stringWriter);
} catch (Exception e) {
LOGER.error(&处理DAO查询参数模板时发生错误:{}&,e.toString());
throw new SysException(e);
return stringWriter.toString();
} }我们的SimpleHibernateDAO实现了InitializingBean,在其afterProperties方法中我们将调用DynamicHibernateStatementBuilder把语句缓存起来
上层方法调用示例-这个已经非常类似ibatis了 public List&Resource& getDescendants(Long userId,String code) {
Map&String, Object& values = new HashMap&String, Object&();
values.put(&userId&, String.valueOf(userId));
values.put(&code&, code);
values.put(&type&, String.valueOf(ResourceTypeEnum.URL_RESOURCE.getType()));
values.put(&status&, String.valueOf(ResourceStatusEnum.ACTIVE.getStatus()));
return this.findByNamedQuery(new ResourceRowMapper(),&resource.getDescendants&, values);
来源:/javaexam2/archive//2632493.

我要回帖

更多关于 hibernate 关联查询 的文章

 

随机推荐