分享知识-快乐自己:Hibernate 中的 HQL 语句的实际应用

概要:

  Hibernate 支持三种查询方式: HQL查询、Criteria查询及原声 SQL (Native SQL)查询。

  HQL(Hibernate Query Language,Hibernate 查询语言)是一种面向对象的查询语言,其中没有表和字段的概念,只有类、对象和属性的概念,大家在学习中要注意。

  Criteria 查询采用面向对象的方式构造查询。原生 SQL 查询就是直接执行 SQL 语句的查询,可以在 SQL 中利用不同数据库所特有的一些特性进行查询,例如,数据库是 Oracle 可以使用 Oracle 的关键字或函数等。

  编写 HQL 语句:

  HQL 语句除了 java 类和属性的名称外,查询语句对大小写不敏感,所以 SELECT 和 select 是相同的,但是 cn.hibernate.entity.Dept 不等价于 cn.hibernate.entity.DEPT 。

  HQL 语句中的关键字建议使用小写字母,如 select。

 

1):HQL 查询语法:

1、from 子句:

Hibernate 中最简单的 HQL 语法形式如下,这几条 HQL 语句都是用来查询所有信息的。

from cn.hibernate.entity.Dept
//说明  cn.hibernate.entity.Dept 是全限定名

from Dept
//说明:类名Dept省略了包名。

from Dept as dept
from Dept dept
//说明:这两条HQL语句为持久化类Dept 指派了别名 dept,可以在HQL 语句中使用这个别名。关键字 as 是可选的。

2、select 语句:

//select 子句用于选取对象和属性
select dept.deptName from Dept as dept
//说明:select 子句选取了一个属性 deptName,也可以选取多个属性。
select dept from Dept as dept
//说明:select 后跟的是别名 dept

3、where 语句:

//where 子句用于表达查询的限制条件
from Dept where deptName='xx'
//说ing:这条HQL语句用于查询名称是 xx 的信息,where 后面直接使用属性名

from Dept dept where dept.deptName='xx' //说ing:这条HQL语句用于查询名称是 xx 的信息,并且指定了别名 //where 后面使用了完整的属性名 ddept.deptName from Dept dept where dept.location is not null //说明:这条 HQL 语句用于查询地址不为 Null 的信息

4、使用表达式:

//表达式一般用在 where字句中。以下两个HQL语句在where子句中分别使用了 lower()函数和 year()函数。
from Dept dept where lower(dept.deptName)='xx'
//说明:这条 HQL 语句用于查询名称是 xx 的部门,不区分大小写。lower()函数用于把字符串中的每个字母改为小写。

from Emp where year(hibeDate)=1980
//说明:这条 HQL 语句用于查询 1980 年入职的员工。year()函数用于获取日期字段的年份。

5、order by 子句:

//order by 字据用于按指定属性排序
from Emp order by hireDate asc 
//说明:这条 HQL 语句用于查询所有员工,并按员工入职时间升序排序。
//关键字 asc 或 desc 是可选的,用于指明按照什么方式进行排序。默认为升序排列。
from Emp order by hireDate , salary desc
//说明:这条HQL 语句用于查询所有员工,先按员工入职时间升序,然后时间相同的在按员工工资降序。

 下面我们来看实际的案例:

User 实体类:

package com.mlq.bena;
import java.io.Serializable;
public class User implements Serializable {
    private Integer uId;
    private String userName;
    private String userPwd;
    private String realName;
    @Override
    public String toString() {
        return "User{" +
                "uId=" + uId +
                ", userName='" + userName + '\'' +
                ", userPwd='" + userPwd + '\'' +
                ", realName='" + realName + '\'' +
                '}';
    }
    public Integer getuId() {
        return uId;
    }
    public void setuId(Integer uId) {
        this.uId = uId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    public String getRealName() {
        return realName;
    }
    public void setRealName(String realName) {
        this.realName = realName;
    }
}

SessionTool:连接工具类

package com.mlq.uitl;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * 读取配置信息
 */
public class SessionTool {
    private static SessionFactory sessionFactory=null;
    private static Configuration configuration=null;
    static
    {
        System.out.println("静态代码块------");
        configuration=new Configuration().configure();
        sessionFactory=configuration.buildSessionFactory();
    }
    public static Session getSession()
    {
        return sessionFactory.getCurrentSession();
        //return sessionFactory.openSession();
    }
}

BaseDao:进一步提升的打开连接类

package com.mlq.bena;
import com.mlq.uitl.SessionTool;
import org.hibernate.Session;

/**
 * 获取连接的提升封装
 * @author asus
 */
public class BaseDao {

    public Session getSession()
    {
        return SessionTool.getSession();
    }
}

UserMapper 接口:

package com.mlq.mapper;

import com.mlq.bena.User;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * @author asus
 */
public interface UserMapper {

    /**
     * 编写第一个HQL语句:查询所有 list()方法
     * @return
     */
    public List<User> listUser();
    /**
     * 编写第二个HQL语句:查询所有 iterate()方法
     * @return
     */
    public Iterator<User> iterateUser();
    /**
     * 编写第三个HQL语句:带条件查询:uniqueResult()方法
     */
    public User dUser();

    /**
     * 编写第四个HQL语句:查询总数量:uniqueResult()方法
     * @return
     */
    public Long countUser();
}

UserMapperImpl 实现:

package com.mlq.mapper.impl;
import com.mlq.bena.BaseDao;
import com.mlq.bena.User;
import com.mlq.mapper.UserMapper;
import org.hibernate.Query;
import org.hibernate.Session;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * @author asus
 */
public class UserMapperImpl extends BaseDao implements UserMapper {

    @Override
    public List<User> listUser() {
        Query query = super.getSession().createQuery("from com.mlq.bena.User");
        List list = query.list();
        return list;
    }

    @Override
    public Iterator<User> iterateUser() {
        Query query = super.getSession().createQuery("from com.mlq.bena.User");
        Iterator iterate = query.iterate();
        return iterate;
    }
    @Override
    public User dUser() {
        Query query = super.getSession().createQuery("from com.mlq.bena.User where userName='原来的模样'");
        User user = (User)query.uniqueResult();
        return user;
    }

    @Override
    public Long countUser() {
        Query query = super.getSession().createQuery("select count(id) from com.mlq.bena.User");
        Long aLong =(Long) query.uniqueResult();
        return aLong;
    }

}

UserService 接口:

package com.mlq.seivice;
import com.mlq.bena.User;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
/**
 * @author asus
 */
public interface UserService {

    /**
     * 编写第一个HQL语句:查询所有
     * @return
     */
    public List<User> listUser();
    /**
     * 编写第二个HQL语句:查询所有 iterate()方法
     * @return
     */
    public Iterator<User> iterateUser();
    /**
     * 编写第三个HQL语句:带条件查询:uniqueResult()方法
     * uniqueResult()返回单个结果集
     */
    public User dUser();
    /**
     * 编写第四个HQL语句:查询总数量:uniqueResult()方法
     * uniqueResult()返回单个结果集
     * @return
     */
    public Long countUser();
}

UserServiceImpl 实现:

package com.mlq.seivice.impl;

import com.mlq.bena.User;
import com.mlq.mapper.impl.UserMapperImpl;
import com.mlq.seivice.UserService;
import com.sun.xml.internal.ws.handler.HandlerException;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * 实现数据查询
 * @author asus
 */
public class UserServiceImpl implements UserService {

    Transaction transaction=null;
    private UserMapperImpl userMapper=null;

    @Override
    public List<User> listUser() {
        List<User> list=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            list = userMapper.listUser();
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常-相爱相杀一场!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return list;
    }

    @Override
    public Iterator<User> iterateUser() {
        Iterator<User> iterator=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            iterator= userMapper.iterateUser();
            while (iterator.hasNext())
            {
                User next = iterator.next();
                System.out.println(next);
            }
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常-相爱相杀一场!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return iterator;
    }

    @Override
    public User dUser() {
        User user=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            user= userMapper.dUser();
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常-相爱相杀一场!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return user;
    }

    @Override
    public Long countUser() {
        Long aLong=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            aLong= userMapper.countUser();
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常-相爱相杀一场!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return aLong;
    }
}

核心配置文件:hibernate.cfg.xml (后缀必须以 .cfg.xml 结尾)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"  >
<hibernate-configuration>
    <session-factory>
        <!--配置连接数据库的四要素-->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://39.105.105.186:3306/MyBatisCode?useUnicode=true&amp;characterEncoding=UTF-8</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <!--是否显示底层生成的sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--是否格式化sql语句-->
        <property name="hibernate.format_sql">true</property>
        <!--方言设置-->
        <!--MySql 驱动程序 eg. mysql-connector-java-5.0.4-bin.jar-->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!--当前会话上下文-->
        <property name="current_session_context_class">thread</property>
        <!--hbm2ddl   就是把xx.hbm.xml文件中的配置生成数据库中DDL(数据定义语言)
        create:  每次运行都会删除 上次生成的表,还会创建新的!
        update: 没有表会自动创建,有表就增加数据!
        validate: 如果hbm文件和数据库中的字段对应 就会新增,
                  否则抛出异常!
       create-drop:  每次运行都会删除 上次生成的表,前提是sessionFactory关闭
        -->
        <property name="hbm2ddl.auto">update</property>
        <!--加载需要的hbm.xml映射文件 现阶段还没有 -->
        <mapping resource="mapping/user.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

映射文件:user.hbm.xml (后缀必须以 .hbm.xml 结尾)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
package: 需要映射的实体类所在包
class节点:
name:对应的是实体类的类名,如果没有书写package,则必须是完整限定类名

table:数据库中的表名,如果表名和实体类名一致,可以省略
id节点:表中的主键
generator:主键生成策略 ,主键由谁去创建?程序猿?Hibernate?数据库
name:  必须和实体类中的属性名一致
column : 必须和数据库中的列名一致,如果列名和属性名一致,可以省略
-->
<!--dynamic-update="false":默认非动态更新-->
<hibernate-mapping package="com.mlq.bena">
    <class name="com.mlq.bena.User" table="`user`" dynamic-update="true">
        <id name="uId" column="uId">
            <!--<generator class="assigned"/>&lt;!&ndash;主键生成策略&ndash;&gt;-->
            <generator class="increment"></generator>
        </id>
        <property name="userName" column="userName"/>
        <property name="userPwd" column="userPwd"/>
        <property name="realName" column="realName"/>
    </class>
</hibernate-mapping>
<!--Oracle序列增长-->
<!--<generator class="squence">-->
<!--<param name="squence">SEQ_DEPTNO</param>-->
<!--</generator>-->
<!--数据库中查询最大值+1-->
<!--<generator class="increment"></generator>-->
<!--没有制定使用那种方式:需要结合数据库方言自增-->
<!--<generator class="native"></generator>-->
<!--uuid:生成32位字符串-->
<!--<generator class="uuid"></generator>-->

测试类 HibernateDemo:

package com.mlq;
import com.mlq.bena.User;
import com.mlq.seivice.UserService;
import com.mlq.seivice.impl.UserServiceImpl;
import org.junit.Test;

import java.util.Iterator;
import java.util.List;

/**
 * 提取工具类的测试
 */
public class HibernateDemo {
    private UserService userService=null;
    //第一个HQL测试:查询所有 list()方法
    @Test
    public void list_User()
    {
        userService=new UserServiceImpl();
        List<User> users = userService.listUser();
        for (User temp:users)
        {
            System.out.println(temp);
        }
    }
    //第二个HQL测试:查询所有 iterate()方法:该输出在业务逻辑层
    @Test
    public void iterate_User()
    {
        userService=new UserServiceImpl();
        userService.iterateUser();
    }
    //第三个HQL测试:查询单个 uniqueResult()方法
    @Test
    public void dUser()
    {
        userService=new UserServiceImpl();
        User user = userService.dUser();
        System.out.println(user);
    }
    //第四个HQL测试:查询总数量 uniqueResult()方法:
    @Test
    public void uniqueResultCount()
    {
        userService=new UserServiceImpl();
        Long aLong = userService.countUser();
        System.out.println("用户数量为:"+aLong);
    }
}

 对以上的实际案例提出以下注意事项:

 1、查询所有信息有两种方式:分别是 list()、iterate()

  iterate():不能在测试类输出返回结果。会报当前连接已断开,我们的输出写在了 service层的实现类中

  uniqueResult():用于查询返回单个结果集。

 

 HQL 语句中的绑定参数:

为什么要使用绑定参数那:因为我们之前使用的参数都是写死在 HQL 中的。性能肯定不良好,拼接的方式很容易造成 SQL 注入的攻击目标。

下面我们使用 ?、:xx 占位方式实现入参:

提示:这里只对修改的部分做出展示:其余结构与上述一致。

按参数位置绑定 和  按参数名称绑定:

UserMapper:

package com.mlq.mapper;
import com.mlq.bena.User;

import java.util.Iterator;
import java.util.List;
/**
 * 占位符方式
 * @author asus
 */
public interface UserMapper {
    /**
     * 使用参数位置占位符 ? 定方式实现单个用户查询
     */
    public User dUser(String id);
    /**
     * 使用参数位置占位符 :xx 的方式实现单个用户查询
     */
    public User dUser1(String id);
    /**
     * setParameter()用法:对象入参
     */
    public User setParameter1(Object[] objects);
    /**
     * setProperties()用法:对象作为入参
     */
    public User setProperties1(User user);
}

UserMapperImpl:

package com.mlq.mapper.impl;
import com.mlq.bena.BaseDao;
import com.mlq.bena.User;
import com.mlq.mapper.UserMapper;
import org.hibernate.Query;

import java.util.Iterator;
import java.util.List;
/**
 * @author asus
 */
public class UserMapperImpl extends BaseDao implements UserMapper {

    /**
     * 使用参数位置占位符 ? 的方式实现单个用户查询
     */
    @Override
    public User dUser(String id) {
        User user =(User) super.getSession().createQuery("from com.mlq.bena.User where userName=?")
                .setString(0, id).uniqueResult();
        return user;
    }
    /**
     * 使用参数位置占位符 :id 的方式实现单个用户查询
     */
    @Override
    public User dUser1(String id) {
        User user =(User) super.getSession().
                createQuery("from com.mlq.bena.User where userName= :id").setString("id",id)
                .uniqueResult();
        return user;
    }
    /**
     * setParameter()用法:
     */
    @Override
    public User setParameter1(Object[] objects) {
        Query query = super.getSession().
                createQuery("from com.mlq.bena.User where userName=? and uId=?");
        for (int i = 0; i <objects.length ; i++) {
            query.setParameter(i,objects[i]);
        }
        User user = (User)query.uniqueResult();
        return user;
    }
    /**
     * setParameter()用法:对象入参
     */
    @Override
    public User setProperties1(User user) {
        Query query = super.getSession().
                createQuery("from com.mlq.bena.User where userName=:userName and uId=:uId");
        query.setProperties(user);
        User info = (User)query.uniqueResult();
        return info;
    }
}

UserService:

package com.mlq.seivice;
import com.mlq.bena.User;

import java.util.Iterator;
import java.util.List;
/**
 * @author asus
 */
public interface UserService {
    /**
     * 使用参数位置占位符 ? 的方式实现单个用户查询
     */
    public User dUser(String id);
    /**
     * 使用参数位置占位符 :id 的方式实现单个用户查询
     */
    public User dUser1(String id);
    /**
     * setParameter()用法:
     */
    public User setParameter1(Object[] objects);
    /**
     * setProperties()用法:对象作为入参
     */
    public User setProperties1(User user);
}

UserServiceImpl:

package com.mlq.seivice.impl;
import com.mlq.bena.User;
import com.mlq.mapper.impl.UserMapperImpl;
import com.mlq.seivice.UserService;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;

import java.util.Iterator;
import java.util.List;
/**
 * 实现数据查询
 * @author asus
 */
public class UserServiceImpl implements UserService {

    Transaction transaction=null;
    private UserMapperImpl userMapper=null;
    /**
     * 使用参数位置占位符 ? 的方式实现单个用户查询
     */
    @Override
    public User dUser(String id) {
        User user=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            user = userMapper.dUser(id);
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return user;
    }
    /**
     * 使用参数位置占位符 :id 的方式实现单个用户查询
     */
    @Override
    public User dUser1(String id) {
        User user=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            user = userMapper.dUser1(id);
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return user;
    }
    /**
     * setParameter()用法:
     */
    @Override
    public User setParameter1(Object[] objects) {
        User user=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            user = userMapper.setParameter1(objects);
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return user;
    }
    /**
     * setParameter()用法:对象入参
     */
    @Override
    public User setProperties1(User user) {
        User info=null;
        try{
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            info = userMapper.setProperties1(user);
            transaction.commit();
        }catch (HibernateException e)
        {
            System.out.println("进入异常!!!");
            e.printStackTrace();
            transaction.rollback();
        }
        return info;
    }
}

测试类:

package com.mlq;
import com.mlq.bena.User;
import com.mlq.seivice.UserService;
import com.mlq.seivice.impl.UserServiceImpl;
import org.junit.Test;

import java.util.List;

/**
 * 提取工具类的测试
 */
public class HibernateDemo {
    private UserService userService=null;
    /**
     * 使用参数位置占位符 ? 的方式实现单个用户查询
     * 使用参数名称占位符 :xx 的方式实现单个用户查询
     */
    @Test
    public void dUser()
    {
        userService=new UserServiceImpl();
        User user = userService.dUser("原来的模样");
        User user1 = userService.dUser1("原来的模样");
        System.out.println("参数位置查询》:"+user);
        System.out.println("参数名称绑定》:"+user1);
    }
    /**
     * setParameter()用法:
     */
    @Test
    public void setParameter1()
    {
        userService=new UserServiceImpl();
        Object[] objects={"原来的模样",42183};
        User user = userService.setParameter1(objects);
        System.out.println(user);
    }
    /**
     * setProperties1()用法:
     */
    @Test
    public void setProperties1()
    {
        userService=new UserServiceImpl();
        User info=new User();
        info.setuId(42183);
        info.setUserName("原来的模样");
        User user = userService.setProperties1(info);
        System.out.println(user);
    }
}

对以上案例做出以下注意事项:

1、使用 setProperties()方法时 入参的名称必须与 对象中的属性名一致;

2、setParameter()下标从 0 开始的,

3、setString()下标从 0 开始的

 

实现动态查询和分页:

提示:这里只对修改的部分做出展示:其余结构与上述一致。

UserMapper:

package com.mlq.mapper;
import com.mlq.bena.User;

import java.util.List;
import java.util.Map;
/**
 * @author asus
 */
public interface UserMapper {

    /**
     * 动态实现查询:入参为对象类型
     */
    public User ydUser(String hq, User user);
    /**
     * 动态实现查询:入参为Map 集合类型
     */
    public User ydUser(String hq, Map<String,Object> map);
    /**
     * 分页查询
     */
    public List<User> pageListUser(Integer pageNo, Integer size);
    /**
     * 查询前最大数的前三条
     */
    public List<User> pageListUser(Integer size);
}

UserMapperImpl:

package com.mlq.mapper.impl;
import com.mlq.bena.BaseDao;
import com.mlq.bena.User;
import com.mlq.mapper.UserMapper;
import org.hibernate.Query;

import java.util.List;
import java.util.Map;
/**
 * @author asus
 */
public class UserMapperImpl extends BaseDao implements UserMapper {
    /**
     * 动态实现查询
     */
    @Override
    public User ydUser(String hq, User user) {
        User user1 = (User) super.getSession().createQuery(hq)
                .setProperties(user).uniqueResult();
        return user1;
    }

    @Override
    public User ydUser(String hq, Map<String, Object> map) {
        User user1 = (User) super.getSession().createQuery(hq)
                .setProperties(map).uniqueResult();
        return user1;
    }

    @Override
    public List<User> pageListUser(Integer pageNo, Integer size) {
        List list = super.getSession().createQuery("from com.mlq.bena.User")
                .setFirstResult((pageNo - 1) * size).setMaxResults(size).list();
        return list;
    }

    @Override
    public List<User> pageListUser(Integer size) {
        List list = super.getSession().createQuery("from com.mlq.bena.User order by uId desc")
                .setMaxResults(size).list();
        return list;
    }
}

UserService:

package com.mlq.seivice;
import com.mlq.bena.User;

import java.util.List;
import java.util.Map;
/**
 * @author asus
 */
public interface UserService {
    /**
     * 动态实现查询:入参为对象类型
     */
    public User ydUser(User user);
    /**
     * 动态实现查询:入参为Map 集合类型
     */
    public User ydUser(Map<String,Object> map);
    /**
     * 分页查询
     */
    public List<User> pageListUser(Integer pageNo, Integer size);
    /**
     * 查询前最大数的前三条
     */
    public List<User> pageListUser(Integer size);
}

UserServiceImpl:

package com.mlq.seivice.impl;

import com.mlq.bena.User;
import com.mlq.mapper.impl.UserMapperImpl;
import com.mlq.seivice.UserService;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;

import java.util.List;
import java.util.Map;

/**
 * 实现数据查询
 * @author asus
 */
public class UserServiceImpl implements UserService {

    Transaction transaction=null;
    private UserMapperImpl userMapper=null;
    /**
     * 动态实现查询
     */
    @Override
    public User ydUser(User user) {
        User user1=null;
        try {
            StringBuilder hq = new StringBuilder("from com.mlq.bena.User where 1=1");
            if (user.getUserName() != null && user.getUserName() != "") {
                hq.append(" and userName=:userName");
            }
            if (user.getuId() != null) {
                hq.append(" and uId=:uId");
            }
            userMapper = new UserMapperImpl();
            transaction = userMapper.getSession().beginTransaction();
            user1=userMapper.ydUser(hq.toString(),user);
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return user1;
    }

    @Override
    public User ydUser(Map<String, Object> map) {
        User user1=null;
        try {
            StringBuilder hq = new StringBuilder("from com.mlq.bena.User where 1=1");
            if (map.get("userName") != null && map.get("userName")  != "") {
                hq.append(" and userName=:userName");
            }
            if (map.get("uId")!="") {
                hq.append(" and uId=:uId");
            }
            userMapper = new UserMapperImpl();
            transaction = userMapper.getSession().beginTransaction();
            user1=userMapper.ydUser(hq.toString(),map);
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return user1;
    }

    @Override
    public List<User> pageListUser(Integer pageNo, Integer size) {
        List<User> list=null;
        try {
            userMapper=new UserMapperImpl();
            transaction = userMapper.getSession().beginTransaction();
            list=userMapper.pageListUser(pageNo,size);
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return list;
    }

    @Override
    public List<User> pageListUser(Integer size) {
        List<User> list=null;
        try {
            userMapper=new UserMapperImpl();
            transaction = userMapper.getSession().beginTransaction();
            list=userMapper.pageListUser(size);
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return list;
    }
}

对以上案例做出以下注意事项:

首先对 HQL编写的语句做出了一个提升。要想实现动态查询 肯定就需要拼接 HQL 语句。很显然在 Mapper层去拼接肯定不符合要求,因为Mapper只需要执行,不需要逻辑上的处理。所以我们把 拼接的方式 写在 service 层。

1、动态拼接 我们使用的是 按名称进行占位入参 :xx

2、入参的为 Map 集合时,集合中的key 就是 占位的名称。

3、分页:setFirstResult((pageNo - 1) * size)开始位置检索,setMaxResults()最大检索的数量

4、也可以单个使用查询前几条数据。例如先倒序排列,使用 setMaxResults()进行检索。

 

使用投影查询+通过构造方式封装成对象:

投影查询一听很高大上,实际上就是使用了 select 语句进行了字段的筛选查询。

投影查询分为两种:包含一个结果列、包含多个结果列。

下面展示案例:

UserMapper:

package com.mlq.mapper;
import com.mlq.bena.User;

import java.util.List;
import java.util.Map;
/**
 * @author asus
 */
public interface UserMapper {
    /**
     * 查询单个字段:返回Object类型 list集合
     */
    public List<Object> dList();
    /**
     * 查询多个字段:返回Object数组类型 list集合
     */
    public List<Object[]> objectStu();
    /**
     * 通过构造方法:封装成对象
     * 对象不是持久化状态,只限于封装结果
     */
    public List<User> findUser();
}

UserMapperImpl:

package com.mlq.mapper.impl;

import com.mlq.bena.BaseDao;
import com.mlq.bena.User;
import com.mlq.mapper.UserMapper;
import java.util.List;
import java.util.Map;

/**
 * @author asus
 */
public class UserMapperImpl extends BaseDao implements UserMapper {
    /**
     * 查询单个字段:返回Object类型 list集合
     */
    @Override
    public List<Object> dList() {
        List list = super.getSession().createQuery("select uId from com.mlq.bena.User").list();
        return list;
    }
    /**
     * 查询多个字段:返回Object数组类型 list集合
     */
    @Override
    public List<Object[]> objectStu() {
        List list = super.getSession().createQuery("select uId,userName from com.mlq.bena.User").list();
        return list;
    }
    /**
     * 通过构造方法:封装成对象
     * 对象不是持久化状态,只限于封装结果
     */
    @Override
    public List<User> findUser() {
        List list = super.getSession().createQuery("select new User(uId,userName) from com.mlq.bena.User").list();
        return list;
    }
}

UserService:

package com.mlq.seivice;
import com.mlq.bena.User;

import java.util.List;
import java.util.Map;
/**
 * @author asus
 */
public interface UserService {

    /**
     * 查询单个字段:返回Object类型 list集合
     */
    public List<Object> dList();
    /**
     * 查询多个字段:返回Object数组类型 list集合
     */
    public List<Object[]> objectStu();
    /**
     * 通过构造方法:封装成对象
     * 对象不是持久化状态,只限于封装结果
     */
    public List<User> findUser();
}

UserServiceImpl:

package com.mlq.seivice.impl;
import com.mlq.bena.User;
import com.mlq.mapper.impl.UserMapperImpl;
import com.mlq.seivice.UserService;
import org.hibernate.HibernateException;
import org.hibernate.Transaction;

import java.util.List;
import java.util.Map;
/**
 * 实现数据查询
 * @author asus
 */
public class UserServiceImpl implements UserService {

    Transaction transaction=null;
    private UserMapperImpl userMapper=null;
    /**
     * 查询单个字段:返回Object类型 list集合
     */
    @Override
    public List<Object> dList() {
        List<Object> list=null;
        try {
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            list=userMapper.dList();
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return list;
    }
    /**
     * 查询多个字段:返回Object数组类型 list集合
     */
    @Override
    public List<Object[]> objectStu() {
        List<Object[]> list=null;
        try {
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            list=userMapper.objectStu();
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return list;
    }
    /**
     * 通过构造方法:封装成对象
     * 对象不是持久化状态,只限于封装结果
     */
    @Override
    public List<User> findUser() {
        List<User> list=null;
        try {
            userMapper=new UserMapperImpl();
            transaction=userMapper.getSession().beginTransaction();
            list=userMapper.findUser();
            transaction.commit();
        }catch (HibernateException ex)
        {
            System.out.println("进入异常!!!");
            ex.printStackTrace();
            transaction.rollback();
        }
        return list;
    }
}

测试类 HibernateDemo:

package com.mlq;
import com.mlq.bena.User;
import com.mlq.seivice.UserService;
import com.mlq.seivice.impl.UserServiceImpl;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 提取工具类的测试
 */
public class HibernateDemo {
    private UserService userService=null;
    /**
     * 查询多个字段:返回Object数组类型 list集合
     */
    @Test
    public void listUser()
    {
        userService=new UserServiceImpl();
        List<Object> list = userService.dList();
        for (Object o:list)
        {
            System.out.println(o);
        }
    }
    /**
     * 查询多个字段:返回Object[]类型 list集合
     */
    @Test
    public void listUserStu()
    {
        userService=new UserServiceImpl();
        List<Object[]> objects = userService.objectStu();
        for (Object[] o:objects)
        {
            System.out.println(o[0]+"=="+o[1]);
        }
    }
    /**
     * 通过构造方法:封装成对象
     * 对象不是持久化状态,只限于封装结果
     */
    @Test
    public void findUser()
    {
        userService=new UserServiceImpl();
        List<User> user = userService.findUser();
        for (User u:user)
        {
            System.out.println(u);
        }
    }
}

对以上的案例做出以下注意事项:

1、通过构造封装成的对象符合面向对象的风格。但是这也样查询到的对象不是持久状态的,不能借助 Hibernate 的缓存机制实现与数据库同步,仅用于封装本次查询结果。

 

以上就是对 HQL 语句使用的总结:若有不足之处,或者不明白;评论区等着你哦!

posted @ 2018-09-21 14:56  GDBD  阅读(455)  评论(0编辑  收藏  举报