OID和对象导航方式
例:
HQL
HQL查询方式
- 介绍
HQL(Hibernate Query Language) 是面向对000000象的查询语言, 它和SQL 查询语言有些相似,在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。 - HQL与SQL的关系
- HQL查询语句是面向对象的,Hibernate负责解析HQL查询语句,然后根据对象-关系映射文件中的映射信息, 把HQL查询语句翻译成相应的SQL语句.
- HQL查询语句中的主体是域模型中的类及类的属性
- SQL查询语句是与关系数据库绑定在一起的
- SQL查询语句中的主体是数据库表及表的字段
HQL的简单查询
基本查询
123456789101112131415/*** 基本查询*/@Testpublic void run1(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建HQL查询的接口Query query = session.createQuery("from Customer");List<Customer> list = query.list();for (Customer customer : list) {System.out.println(customer);}tr.commit();}支持方法链的编程查询
可以在createQuery方法后面跟多个方法传入参数如list()1234567891011121314/*** 支持方法链的编程*/@Testpublic void run2(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//支持方法链,在后面接.listList<Customer> list = session.createQuery("from Customer").list();for (Customer customer : list) {System.out.println(customer);}tr.commit();}支持别名方式查询
123456789101112131415/*** 支持别名方式* 同SQL*/@Testpublic void run3(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//select c可省略,千万不要加*List<Customer> list = session.createQuery("select c from Customer c where c.cust_id=1").list();for (Customer customer : list) {System.out.println(customer);}tr.commit();}排序查询
1234567891011121314151617/*** 排序查询* order by 属性名 asc/desc*/@Testpublic void run4(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();/* //升序排列List<LinkMan> list = session.createQuery("from LinkMan l order by lkm_id asc").list();*///降序排列List<LinkMan> list = session.createQuery("from LinkMan l order by lkm_id desc").list();for (LinkMan linkman : list) {System.out.println(linkman);}tr.commit();}分页查询
123456789101112131415161718/*** 分页查询* 起始页:setFirstResult(a)* 页大小:setMaxResults(b)*/@Testpublic void run5(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();/*//第一页,设置起始页为0,每页记录3条数据List<LinkMan> list = session.createQuery("from LinkMan l order by lkm_id desc").setFirstResult(0).setMaxResults(3).list();*///第二页,设置起始页为3,每页记录3条数据List<LinkMan> list = session.createQuery("from LinkMan l order by lkm_id desc").setFirstResult(3).setMaxResults(3).list();for (LinkMan linkman : list) {System.out.println(linkman);}tr.commit();}带条件的查询
12345678910111213141516171819202122/*** 条件查询查询*/@Testpublic void run6(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();/*//按位置绑定参数?的条件查询(指定下标值,默认从0开始)List<LinkMan> list = session.createQuery("from LinkMan l where lkm_id > ?").setLong(0,3L).list();*//*//按名称绑定参数的条件查询(HQL语句中的 ? 号换成 :名称 的方式)List<LinkMan> list = session.createQuery("from LinkMan l where lkm_id > :id").setLong("id", 2L).list();*///不用考虑参数的具体类型setParameter("?号的位置,默认从0开始","参数的值")List<LinkMan> list = session.createQuery("from LinkMan l where lkm_id > ? and lkm_name = ?").setParameter(0, 2L).setParameter(1, "四号").list();for (LinkMan linkman : list) {System.out.println(linkman);}tr.commit();}
投影查询
投影查询就是想查询某一字段的值或者某几个字段的值直接查询
12345678910111213141516/*** 投影查询:只查询几个字段,不是所有字段* 相当于sql的"select id,name from LinkMan"* 直接查询*/@Testpublic void run8(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();List<Object[]> list = session.createQuery("select lkm_name,lkm_id from LinkMan").list();for (Object[] objects : list) {System.out.println(Arrays.toString(objects));}tr.commit();}封装到对象中查询
1234567891011121314/***在LinkMan中添加以下构造函数*///投影查询,空的构造函数不能省略public LinkMan(){}//投影查询,传入要查询字段对应的参数public LinkMan(long lkm_id, String lkm_name) {super();this.lkm_id = lkm_id;this.lkm_name = lkm_name;}12345678910111213141516171819/*** 投影查询:只查询几个字段 ,不是所有字段* 相当于sql的"select id, name from LinkMan"* 封装到对象中查询* 第一步:需要在JavaBean 类提供对应的构造方法* 第二步:修改HQL语句*/@Testpublic void run7(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();List<LinkMan> list = session.createQuery("select new LinkMan(lkm_id,lkm_name) from LinkMan").list();for (LinkMan linkman : list) {System.out.println(linkman);}tr.commit();}
聚合函数查询
123456789101112131415/*** 聚合函数* sum() count() avg() max() min()* 查询联系人的数量*/@Testpublic void run9(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//count(别名) = count(*)List<Number> list = session.createQuery("select count(l) from LinkMan l").list();//通过下标取值,longValue()改变类型System.out.println(list.get(0).longValue());tr.commit();}123456789101112131415/*** 聚合函数* sum() count() avg() max() min()* 查询联系人id的和*/@Testpublic void run10(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//count(别名) = count(*)List<Number> list = session.createQuery("select sum(lkm_id) from LinkMan l").list();//通过下标取值,longValue()改变类型System.out.println(list.get(0).longValue());tr.commit();}
HQL多表查询
内连接
简介:查询两表之间的交集(有关联)部分,默认返回object[]数组
代码实例:
迫切内连接
简介:查询两表之间的交集(有关联)部分,返回对应的实体对象
代码实例:
左(右)外连接
简介:查询左(右)表和两表之间交集(关联)部分,默认返回object[]数组
代码实例:
迫切左(右)外连接
简介:查询左(右)表和两表之间交集(关联)部分,返回实体对象
代码实例:
QBC
QBC查询方式
- 简介
QBC查询即Query By Criteria,按条件查询 简单查询
1234567891011121314151617/*** 基本查询*/@Testpublic void run1(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建QBC查询接口Criteria criteria = session.createCriteria(LinkMan.class);//查询所有值List<LinkMan> list = criteria.list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}排序查询
1234567891011121314151617181920/*** 排序查询* 使用addOrder()设置参数*/@Testpublic void run2(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建QBC查询接口Criteria criteria = session.createCriteria(LinkMan.class);//添加排序desc orcriteria.addOrder(Order.desc("lkm_id"));criteria.addOrder(Order.asc("lkm_id"));//查询所有值List<LinkMan> list = criteria.list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}分页查询
123456789101112131415161718192021/*** 分页查询* setFirstResult()和setMaxResult()* 起始页和页的大小*/@Testpublic void run3(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建QBC查询接口Criteria criteria = session.createCriteria(LinkMan.class);//设置每一页三条数据criteria.setFirstResult(0);criteria.setMaxResults(3);//查询所有值List<LinkMan> list = criteria.list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}条件查询
- 简介:Criterion是查询条件的接口,Restrictions类是Hibernate框架提供的工具类,使用该工具类来设置查询条件
- 条件查询使用Criterion接口的add方法,用来传入条件
- 使用Restrictions的添加条件的方法来添加条件
- 常见的条件
- Restrictions.eq – 相等
- Restrictions.gt – 大于号
- Restrictions.ge – 大于等于
- Restrictions.lt – 小于
- Restrictions.le – 小于等于
- Restrictions.between – 在之间
- Restrictions.like – 模糊查询
- Restrictions.in – 范围
- Restrictions.and – 并且
- Restrictions.or – 或者
- Restrictions.isNull – 是否等于null
- 代码实例 1234567891011121314151617181920212223/*** 条件查询* 使用Criterion接口的add方法,用来传入条件* 多个条件就用多个add添加条件* 使用Restrictions的添加条件的方法来添加条件*/@Testpublic void run4(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建QBC查询接口Criteria criteria = session.createCriteria(LinkMan.class);//查询lkm_id=1L的值或lkm_id>4L的值criteria.add(Restrictions.or(Restrictions.gt("lkm_id", 4L), Restrictions.eq("lkm_id", 1L)));//查询3-5之间的值criteria.add(Restrictions.between("lkm_id", 3L, 5L));//查询所有值List<LinkMan> list = criteria.list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}
聚合函数查询
- 简介:Projection的聚合函数的接口,而Projections是Hibernate提供的工具类,使用该工具类设置聚合函数查询。
- 使用QBC的聚合函数查询,需要使用criteria.setProjection()方法。
- 代码实例 12345678910111213141516171819202122/*** 聚合函数查询* 注:在查询完聚合函数后,要继续查询其他字段的话要设置回默认*/@Testpublic void run5(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建QBC查询接口Criteria criteria = session.createCriteria(LinkMan.class);//设置聚合函数的方式List<Number> list = criteria.setProjection(Projections.count("lkm_id")).list();Long count = list.get(0).longValue();System.out.println(count);//继续查询其他字段的话要设置回默认criteria.setProjection(null);List<LinkMan> list2 = criteria.list();for (LinkMan linkMan : list2) {System.out.println(linkMan);}tr.commit();}
离线条件查询
- 简介:离线条件查询使用的是DetachedCriteria接口进行查询,离线条件查询对象在创建的时候,不需要使用Session对象,只是在查询的时候使用Session对象即可
- 代码实例12345678910111213141516171819/*** 离线条件查询* 注:脱离session,可以不使用session来创建离线查询对象,只在查询的时候需要Session对象*/@Testpublic void run6(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建离线查询接口DetachedCriteria criteria = DetachedCriteria.forClass(LinkMan.class);//添加条件criteria.add(Restrictions.gt("lkm_id", 3L));//查询数据List<LinkMan> list = criteria.getExecutableCriteria(session).list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}
SQL
- 简介
直接使用SQL语句进行查询 - 代码实例 1234567891011121314151617181920/*** SQL基本查询* 把数据封装到对象*/@Testpublic void run(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();String sql = "select * from cst_linkman where lkm_id = ?";//创建SQL的查询接口SQLQuery query = session.createSQLQuery(sql);query.setParameter(0, 1L);//设置数据封装对象query.addEntity(LinkMan.class);List<LinkMan> list = query.list();for (LinkMan linkMan : list) {System.out.println(linkMan);}tr.commit();}
延迟加载
延迟加载先获取到代理对象,当真正使用到该对象中的属性的时候,才会发送SQL语句,是Hibernate框架提升性能的方式。
类级别的延迟加载
- Session对象的load方法默认就是延迟加载
只有在使用该对象属性时才发送SQL语句
- 代码实例 1234567891011121314/*** 类级别的延迟加载* 只有在使用该对象属性时才发送SQL语句*/@Testpublic void run() {Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//开启类级别的延迟加载Customer c = session.load(Customer.class,1L);System.out.println("-----------");System.out.println(c.getCust_name());tr.commit();}
- 代码实例
使类级别的延迟加载失效
- 在该类的配置文件的
标签添加lazy=”false” - 添加语句Hibernate.initialize(Object proxy);
- 代码实例 1234567891011121314151617/*** 使类级别的延迟加载失效的两种方式* 1.在该类的配置文件的<class>标签添加lazy="false"* 2.添加语句Hibernate.initialize(Object proxy);*/@Testpublic void run2() {Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//开启类级别的延迟加载Customer c = session.load(Customer.class,1L);//直接初始化c对象,使其延迟加载失效Hibernate.initialize(c); //在这会有SQL语句System.out.println("-----------");System.out.println(c.getCust_name());tr.commit();}
- 在该类的配置文件的
关联级别的延迟加载
- 默认为延迟加载
- 查询客户时,不会把联系人信息查询出来,而是在用到客户中的联系人时才会发送SQL语句
- 代码实例 12345678910111213141516/*** 关联级别的延迟加载* 默认就是延迟加载* 客户中的联系人信息只有在用到的时候才会发送SQL语句*/@Testpublic void run3() {Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();Customer c = session.get(Customer.class, 1L);Set<LinkMan> mans = c.getLinkMans();for (LinkMan linkMan : mans) {System.out.println(linkMan);}tr.commit();}
配置查询策略
- 使用Hibernate查询一个对象的时候,查询其关联对象应该如何查询是Hibernate的一种优化手段!
- lazy属性解决查询的时机的问题,需要配置是否采用延迟加载
- fetch属性就解决查询语句的形式问题
在set标签上配置策略
- fetch的取值:控制SQL语句生成的格式
- select:默认值,发送基本select语句查询
- join:连接查询,发送的是一条迫切左外连接,配置了join会使lazy属性失效!
- subselect:子查询,发送一条子查询查询其关联对象。(需要使用list()方法进行测试)
- lazy的取值 :查找关联对象的时候是否采用延迟!
- true:默认值,延迟加载
- false:不延迟加载
- extra :及其懒惰,sql语句会精简化
- fetch的默认值为:select,lazy的默认值为true
- 在开发中基本上使用默认值,特殊情况除外
在标签上配置策略
- fetch的取值:控制SQL语句生成的格式
- select:默认值,发送基本select语句查询
- join:连接查询,发送迫切左外连接查询,配置了join会使lazy属性失效!
- lazy的取值:控制加载关联对象是否采用延迟。
- false:不采用延迟加载。
- proxy:默认值,代理。由另一端的
上的lazy值来确定是否延迟加载,如果那端的class上的lazy=”true”则proxy相当于true(延迟加载),如果那端class上的lazy=”false”,则proxy相当于false(不延迟加载)
最后更新: 2020年07月27日 03:38
原始链接: https://www.lousenjay.top/2018/07/18/Hibernate框架入门学习(四)/