分享知识-快乐自己: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&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"/><!–主键生成策略–>--> <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 语句使用的总结:若有不足之处,或者不明白;评论区等着你哦!