作者:何征天
课程视频地址:https://ke.qq.com/course/273907
1.1. 准备工作:
1.把今天的课前资料\sql\db.sql导入数据库hibernate_day04
2.新建web项目hibernate5_day04
3.拷贝第三天hibernate项目的jar包及配置文件
4.修改hibernate.cfg.xml中配置的数据库信息
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day04</property> |
packagecom.igeek.demo1;
import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set;
import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.After; import org.junit.Before; import org.junit.Test;
importcom.igeek.util.HibernateUtils;
publicclass TestHQL {
private Session session; private Transaction tr;
@Before publicvoid init(){ session = HibernateUtils.getCurrentSession(); tr = session.beginTransaction(); }
@After publicvoid destroy(){ tr.commit(); } } |
1.2. HQL基本的查询格式
* 支持方法链的编程,即直接调用list()方法* 简单的代码如下
* session.createQuery("fromCustomer").list();
//查询所有客户信息 ,使用list方法 @Test publicvoid run1(){ //1.通过session的createQuery方法执行hql语句 //Customer指的是java类,hibernate通过javabean来操作数据库 Query query = session.createQuery("from Customer"); print(query); }
privatevoid print(Query query) { //2.调用list方法获取集合值,使用泛型接收 List<Customer> data = query.list(); //3.遍历 for (Customer customer : data) { System.out.println(customer.getCust_name()+"-->"+customer.getCust_level()); } } |
1.3. 使用别名的方式
* 可以使用别名的方式
* session.createQuery("fromCustomer c").list();
* session.createQuery("selectc from Customer c").list();
//使用别名 @Test publicvoid run2(){ // Query query = session.createQuery("from Customer c"); Query query = session.createQuery("select c from Customer c"); print(query); } |
1.4 排序查询
* 排序查询和SQL语句中的排序的语法是一样的
* 升序
* session.createQuery("from Customer order bycust_id").list();
* 降序
* session.createQuery("fromCustomer order by cust_id desc").list();
//排序 @Test publicvoid run3(){ //升序 // Query query = session.createQuery("from Customer order by cust_id"); //降序 Query query = session.createQuery("from Customer order by cust_id desc"); print(query); } |
1.5. 分页查询
* Hibernate框架提供了分页的方法,咱们可以调用方法来完成分页
* 两个方法如下
* setFirstResult(a) --从哪条记录开始,如果查询是从第一条开启,值是0
* setMaxResults(b) -- 每页查询的记录条数
* 演示代码如下
//分页 @Test publicvoid run4(){ Query query = session.createQuery("from Customer"); //设置记录开始索引,从0开始 query.setFirstResult(0); //设置每页查询的记录条数 query.setMaxResults(3); print(query); } |
1.6. 带条件的查询
* setParameter("?号的位置,默认从0开始","参数的值"); 不用考虑参数的具体类型
* 按位置绑定参数的条件查询(指定下标值,默认从0开始)
* 按名称绑定参数的条件查询(HQL语句中的 ? 号换成 :名称 的方式)
* 例如代码如下
//条件查询 @Test publicvoid run5(){ //找出所有姓林的明星 Query query = session.createQuery("from Customer where cust_name like ?"); //设置占位符参数 //第一个参数是?的索引,从0开始 //第二个参数是占位符的值 query.setParameter(0, "%林%"); print(query); } |
//条件查询 @Test publicvoid run51(){ //找出所有姓林的明星 Query query = session.createQuery("from Customer where cust_name like :name"); query.setParameter("name", "%林%"); print(query); } |
1.7. HQL的投影查询
1.投影查询就是想查询某一字段的值或者某几个字段的值
2. 投影查询的案例
* 如果查询多个字段,例如下面这种方式
//投影查询就是想查询某一字段的值或者某几个字段的值 @Test publicvoid run6(){ //查找所有明星的姓名和级别 Query query = session.createQuery("select c.cust_name,c.cust_level from Customer c"); //这里不能用 print(query)方法来打印,因为返回的是Object数组,需要使用Object数组来接收 List<Object[]> data = query.list(); for (Object[] o : data) { System.out.println(o[0]+"-->"+o[1]); } } |
* 如果查询两个字段,也可以把这两个字段封装到对象中
* 先在持久化类中提供对应字段的构造方法
* 使用下面这种HQL语句的方式
/** * 需要提供一个空的构造方法,hibernate默认使用空的构造方法来创建对象 */ public Customer() { }
public Customer(String cust_name, String cust_level) { this.cust_name = cust_name; this.cust_level = cust_level; } |
//投影查询:如果查询两个字段,也可以把这两个字段封装到对象中 //先在持久化类中提供对应字段的构造方法 @Test publicvoid run7(){ //把姓名和级别传入构造方法 Query query = session.createQuery("select new Customer(c.cust_name,c.cust_level) from Customer c"); print(query); } |
1.8. 技术分析之聚合函数查询
1.uniqueResult() 唯一的结果。如果查询的结果只包含一个对象,使用uniqueResult(),如果查询结果包含多个对象,使用uniqueResult抛出异常
2. 获取总的记录数
//获取总记录数 @Test publicvoid run8(){ Query query = session.createQuery("select count(c) from Customer c"); Long count = (Long) query.list().get(0); System.out.println(count); } |
//获取某一列数据的和 @Test publicvoid run9(){ Query query = session.createQuery("select sum(c.cust_id) from Customer c"); Long sum = (Long) query.uniqueResult(); System.out.println(sum); } |
* 使用group by 属性 进行分组
//对客户等级分组 @Test publicvoid run10(){ Query query = session.createQuery("select c.cust_level from Customer c group by c.cust_level"); List<Object> data = query.list(); for (Object object : data) { System.out.println(object); } } |
1.9. 技术分析之HQL多表查询
1. 多表的查询进来使用HQL语句进行查询,HQL语句和SQL语句的查询语法比较类似。
* 内连接查询
* 显示内连接
* select* from customers c inner join orders o on c.cid = o.cno;
* 隐式内连接
* select* from customers c,orders o where c.cid = o.cno;
* 外连接查询
* 左外连接
* select* from customers c left join orders o on c.cid = o.cno;
* 右外连接
* select* from customers c right join orders o on c.cid = o.cno;
2. 内连接查询
* 内连接使用 inner join ,默认返回的是Object数组
添加Customer类的构造方法
public Customer() { // TODO Auto-generated constructor stub } |
//内连接 //查询所有客户及对应的联系人 @Test publicvoid run11(){ //显示内连接 Query query = session.createQuery("from Customer c inner join c.linkmans"); List<Object[]> data = query.list(); for (Object[] object : data) { System.out.println(Arrays.toString(object)); Customer c = (Customer) object[0]; Linkman m = (Linkman) object[1]; System.out.println(c.getCust_name()+"-->"+m.getLkm_name()); } } |
//迫切内连接 //查询所有客户及对应的联系人 @Test publicvoid run12(){ //显示内连接 Query query = session.createQuery("from Customer c inner join fetch c.linkmans"); List<Customer> data = query.list(); for (Customer customer : data) { System.out.println(customer.getCust_name()+"-->"+customer.getLinkmans().size()); } } |
* 左外连接: 封装成List<Object[]>
* 迫切左外连接
//迫切左外连接 @Test publicvoid run13(){ //显示客户表所有数据及联系人表中与客户关联的数据 Query query = session.createQuery("from Customer c left join fetch c.linkmans"); List<Customer> data = query.list(); for (Customer customer : data) { System.out.println(customer.getCust_name()+"-->"+customer.getLinkmans().size()); } } |