Hibernate4和Hibernate5在HQL和SQL查询数据库上的区别

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();
    }

}

猜你喜欢

转载自blog.csdn.net/qq_15329947/article/details/86353564