ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # HQL HQL是我们在hibernate中是常用的一种检索方式。 HQL(Hibernate Query Language)提供更加丰富灵活、更为强大的查询能力 因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语 句的查询方式,同时也提供了更加面向对象的封装。 完整的HQL语句形式如下: ~~~ Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc ~~~ 其中的update/delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。 基本步骤: 1. 得到Session 2. 编写HQL语句 3. 通过session.createQuery(hql)创建一个Query对象 4. 为Query对象设置条件参数 5. 执行list查询所有,它反胃的是List集合 uniqueResut()返回一个查询结果 ## 数据准备 ~~~ //准备数据(2个 Customer,每一个 Customer有10个 Order) //操作 Customer c= new Customer(); c. setName("张三丰"); for (int i=8; i<10; i++){ Order order = new Order(); order.setReceiverInto("上海"); order.setMoney(2000d +i*10); order.setC(c); session.save(order); } ~~~ ## 基本检索 `form 类名` ~~~ //基本检索 //1.编写HQL String hq1="from Customer";//from是关键字,后面是类名,关键字是不区分大小写,但是类名是区分 //2.通过session.createQuery(hql); //Query query = session.createQuery(hql); //3.通过1ist方法得到数据 //List<Customer> list= query.list(); List<customer> list = session.createQuery(hq1).list(); System.out.println (list. get(o)); ~~~ ## 排序检索 ~~~ //排序检索--//查询订单,根据订单的价格进行排序 //1. 定义hql String hql="from Order order by money desc";//desc降序,默认是asc升序 //2.执行加q查询订单,根据价格进行排序 List<order> list = session.createQuery(hql).list(); System.out.println(list); ~~~ ## 条件检索 ~~~ //1.根据位置来绑定参数 //1.1创建hql // String hql = "from Order where money>?"; //1.2.执行hq1 / List<Order> list= session.createQuery(hql).setParameter(0 //200d).1ist(); //可以使用例如setstring() setDouble这样的方法去添加参数,参数的序号是从开始 //2.根据名称来绑定 //1.1创健建hql String hql= "from Order where money >: mymoney "; //1.2.执行hql List<order> list = session.createQuery(hql).setParameter("mymoney ", 2000d).list(); //可以使用例如setString() setDouble这样的方法去添加参数 System.out.println(list) ~~~ ## 分页检索 ~~~ Query query = session.createQuery("from Order"); //每页显示6条件,我们要得到第二页数据 query.setFirstResult((2-1)*6);//设定开始位置 query.setMaxResults(6);//设置条数 List<order> list = query.list(); System.out.println(list); ~~~ ## 分组统计检索 分组 group by 统计 count max min avg sum ~~~ //统计操作----统计一共有多少订单 count // String hql = "select count(*) from Order"; // Object count = session.createQuery(hql).uniqueResult(); // System.out.println(count); //分组统计---每一个人的订单总价 String hql = "select sum(money) from Order group by c"; List list= session.createQuery(hql).list(); System.out.println(list); ~~~ ## 投影检索 使用投影将部分属性封装到对象中 ~~~ //1.查询出所有的 Customer的name // String hal="select name from Customer"; // List list= session.createQuery(hql).list(); // System.out. println(list);//[张龙,张三丰] //如果只查询一个列,得到的结果List<Object> //2.查询所有的 Customer的id,name // String hql="select id, name from Customer"; // List<object[]> list = session.createQuery(hql).list(); // for(Object[] objs: list) { // for(object obj: objs) { // System.out.print(obj+" "); //} // System. out. println() //} //如果是查询多列,得到的结果是List< Object[]> //3.使用投影将查询的结果封装到 Customer对象 String hql="select new Customer(id,name) from Customer";//必须在PO类中提供对应的构造方法 List<customer> cs = session.createQuery(hql).list(); System. out. println(cs); ~~~ 注意: 我们要在po类中提供对应属性的构造方法,也要有无参数构造 ## 命名检索 我们可以将hql语句先定义出来,在使用时通过`session.getNamedQuery(hqlName);`得到一个Query,在执行. 问题: hql定义在什么位置? 1. 如果你有hbm配置文件,那么当前的hql操作是对哪一个实体进行操作,就在哪一个 实体的配置文件中声明。 ~~~ <query name="myHql"> from Customer </query> ~~~ 2. 如果是使用注解来描述PO的配置,我们直接在PO类中使用 ~~~ @NamedQuery(name="myHql", query="from Customer") public class Customer { ~~~ # HQL多表操作 Hql多表操作分类: 1. 交叉连接 2. 内连接 * a) 显示内连接 * b) 隐式内连接 * c) 迫切内连接 * 3. 外连接 左外连接 迫切左外连接 右外连接 注意:在hibernate中有迫切连接的概念,而sql中没有。 ## 内连接 显示内连接 显示内连接使用的是`inner join with` ~~~ //sql连接 select * from t_customer inner join t_order on 条件 String hql = "from Customer c inner join c.orders with c.id = 1"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); //结果是List<Object[]>.而Object[]中装入的是Customer与Order对象 for (Object[] objs : list) { for (Object obj : objs) { System.out.print(obj + "\t"); } System.out.println(); } ~~~ ## 隐式内连接 隐式内连接也我们在sql中操作不一样,它是通过”.”运算符来关联 ~~~ //sql连接 select * from t_customer, t_order where 条件 String hql = "from Order o where o.c.id=1"; Query query = session.createQuery(hql); List list = query.list(); System.out.println(list); ~~~ ## 迫切内连接 迫切内连接得到的结果是直接封装到PO类中,而内连接得到的是Object\[\]数组,数组中封装的是PO类对象。 ~~~ //迫切内连接inner join fetch 注意: 使用迫切内连接结果可能出现重复,所以要使用distinct来去重复 String hql = "select distinct c from Customer c inner join fetch c.orders"; //底层也是执行的inner join 只不过结果封装到对象中 Query query = session.createQuery(hql); List<Customer> list = query.list(); //结果是List<>,集合中装入的是From后面的对象 for(Customer o:list) { System.out.println(o); } ~~~ ## 外连接 **外连接** ~~~ //左外连接 List<Object[]> list = session.createQuery("from Customer c left outer join c.orders").list(); for(Object[] objs:list) { for(Object obj:objs) { System.out.print(obj + "\t"); } System.out.println(); } ~~~ **迫切外连接** ~~~ //注意:fetch不可以与单独条件的with一起使用 List<Customer> list = session.createQuery("select distinct c from Customer c left join fetch c.orders where c.id=1").list(); for (Customer c : list) { System.out.println(c); } ~~~