Hibernate4
Dao层代码
package com.jake.rfcrabbitmvc.dao.impl;
import com.jake.rfcrabbitmvc.dao.BaseDao;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@SuppressWarnings("unchecked")
@Repository
@Transactional
public class BaseDaoImpl<T> implements BaseDao<T> {
@Autowired
private SessionFactory sessionFactory;
public Session getSession() {
return sessionFactory.getCurrentSession();
}
@Override
public List<T> queryHQL(String hql, Object... params) {
Query query = getSession().createQuery(hql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
}
return query.list();
}
@Override
public List<T> executeJDBCSqlQuery(String sql, Class clazz, List<String> params) {
SQLQuery sqlQuery = getSession().createSQLQuery(sql);
for(int i = 0; i < params.size(); i++){
sqlQuery.setParameter(i, params.get(i));
}
return sqlQuery.addEntity(clazz).list();
}
}
Hibernate5
如果在Hibernate5中依然采用上述写法,那么会出现两处错误:
(1)EntityManagerFactory must not be null
解决方法
参考我的博客:《SpringBoot2 + Hibernate5注入SessionFactory的正确方法》
(2)解决了上述问题后,依然报占位符警告:use named parameters or JPA-style positional parameters instead.
解决方法参考博客:https://fanshuyao.iteye.com/blog/2318916
该博客中还提供了Hibernate5的HQL冒号占位符,类似于MyBatis的@Param + #占位符的形式:
Hibernate5中的冒号占位符:
String hql = "select t from t_usert where t.name=:name";
Query query = getSession().createQuery(hql);
query.setParameter("name", "李四");
类似于Mybatis:
Dao层interface
List<UserInfo> findUserInfoByUsernameAndCname(@Param("username") String username, @Param("cname") String cname);
Mapper.xml
<select id="findUserInfoByUsernameAndCname" resultMap="UserInfoBaseResultMap">
SELECT
*
FROM
USER AS u
LEFT JOIN company AS c
ON u.`company_id` = c.`cid`
LEFT JOIN address AS a
ON c.`address_id` = a.`aid`
<where>
<if test="username != null">
u.username = #{username}
</if>
<if test="cname != null">
AND c.cname = #{cname}
</if>
</where>
</select>
所以,改造后的适用于Hibernate5的Dao层代码如下:
package com.jake.rabbitrfc.dao.impl;
import com.jake.rabbitrfc.dao.BaseDao;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.NativeQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManagerFactory;
import java.util.List;
@SuppressWarnings("unchecked")
@Repository
public class BaseDaoImpl<T> implements BaseDao<T> {
@Autowired
private EntityManagerFactory entityManagerFactory;
public Session getSession() {
return entityManagerFactory.unwrap(SessionFactory.class).openSession();
}
@Override
public List<T> queryHQL(String hql, Object... params) {
Query query = getSession().createQuery(hql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i + 1, params[i]);
}
}
return query.list();
}
@Override
public List<T> executeJDBCSqlQuery(String sql, Class clazz, List<String> params) {
NativeQuery nativeQuery = getSession().createNativeQuery(sql, clazz);
for(int i = 0; i < params.size(); i++) {
nativeQuery.setParameter(i + 1, params.get(i));
}
return nativeQuery.getResultList();
}
}