文章目录
对象导航查询: 根据id查询某个客户,再查询这个客户里面所有的联系人
OID查询: 根据id查询某一条记录,返回对象
HQL查询: Query对象,写HQL语句实现查询
QBC查询: Criteria对象
本地SQL查询: SQLQuery对象,使用普通SQL实现查询
实体类的实现
- 客户实体类
package com.ycom1024.hernate.po;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Integer id;
private String name;
private String level;
private String source;
private String phone;
private String mobile;
private Set<LinkMan> linkMans = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public Set<LinkMan> getLinkMans() {
return linkMans;
}
public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
}
/**
* 注意: 没有打印linkMans的信息
*/
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", level=" + level + ", source=" + source + ", phone=" + phone
+ ", mobile=" + mobile + "]";
}
}
- 联系人实体类
package com.ycom1024.hernate.po;
public class LinkMan {
private Integer id;
private String name;
private String gender;
private String phone;
private Customer customer;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
/**
* 注意: 没有打印customer的信息
*/
@Override
public String toString() {
return "LinkMan [id=" + id + ", name=" + name + ", gender=" + gender + ", phone=" + phone + "]";
}
}
对象导航查询
- 代码实现
@Test
public void testQuery1() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 对象导航查询
Customer customer = session.get(Customer.class, 11);
Set<LinkMan> linkMans = customer.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_0_,
customer0_.name as name2_0_0_,
customer0_.level as level3_0_0_,
customer0_.source as source4_0_0_,
customer0_.phone as phone5_0_0_,
customer0_.mobile as mobile6_0_0_
from
t_customer customer0_
where
customer0_.id=?
Hibernate:
select
linkmans0_.fk_limlman_customer as fk_limlm5_1_0_,
linkmans0_.id as id1_1_0_,
linkmans0_.id as id1_1_1_,
linkmans0_.name as name2_1_1_,
linkmans0_.gender as gender3_1_1_,
linkmans0_.phone as phone4_1_1_,
linkmans0_.fk_limlman_customer as fk_limlm5_1_1_
from
t_linkman linkmans0_
where
linkmans0_.fk_limlman_customer=?
LinkMan [id=23, name=M3, gender=null, phone=null]
LinkMan [id=22, name=M1, gender=male, phone=123456]
OID查询
- 根据id查询就是OID查询
- 代码实现:
@Test
public void testQuery2() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// OD查询
Customer customer = session.get(Customer.class, 11);
System.out.println(customer);
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_0_,
customer0_.name as name2_0_0_,
customer0_.level as level3_0_0_,
customer0_.source as source4_0_0_,
customer0_.phone as phone5_0_0_,
customer0_.mobile as mobile6_0_0_
from
t_customer customer0_
where
customer0_.id=?
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
HQL查询
- HQL:Hibernate Query Language:Hibernate提供一种查询语言,HQ;语言和普通的SQL很相似:区别:普通的SQL操作数据库的表与字段;HQL操作的是实体类与属性
- 常用的HQL语句
(1) 查询所有
(2) 条件查询
(3) 排序查询
(4) 分页查询
(5) 投影查询
(6) 聚合函数使用 - 使用HQL查询操作的时候使用Query对象
(1) 创建Query对象:使用HQL语句来创建Query对象
(2) 调用Query对象里面的方法得到结果
查询所有
HQL语法
:from 实体类名- 代码实现
@Test
public void testQuery3() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 查询所有
Query query = session.createQuery("from Customer");
List<Customer> customers = query.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_,
customer0_.name as name2_0_,
customer0_.level as level3_0_,
customer0_.source as source4_0_,
customer0_.phone as phone5_0_,
customer0_.mobile as mobile6_0_
from
t_customer customer0_
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456], Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null]]
条件查询
HQL语法
:from 实体类名称 where 实体类属性名称 = ? and 实体类属性名称 = ?HQL语法
:from 实体类名称 where 实体类属性名称 like ?- 代码实现:
@Test
public void testQuery4() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 条件查询
Query query = session.createQuery("from Customer where id = ? and phone = ?");
query.setParameter(0, 11);
query.setParameter(1, "110");
List<Customer> customers = query.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
---------------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_,
customer0_.name as name2_0_,
customer0_.level as level3_0_,
customer0_.source as source4_0_,
customer0_.phone as phone5_0_,
customer0_.mobile as mobile6_0_
from
t_customer customer0_
where
customer0_.id=?
and customer0_.phone=?
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
排序查询
HQL语法
:from 实体类名称 order by 实体类属性名称 asc/desc
- 代码实现:
@Test
public void testQuery5() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 排序查询
Query query = session.createQuery("from Customer order by id desc");
List<Customer> customers = query.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_,
customer0_.name as name2_0_,
customer0_.level as level3_0_,
customer0_.source as source4_0_,
customer0_.phone as phone5_0_,
customer0_.mobile as mobile6_0_
from
t_customer customer0_
order by
customer0_.id desc
[Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null], Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
分页查询
- MySQL数据库实现分页查询:使用关键字limit
- 在HQL中实现分页就不能写limit!Hibernate的Query对象封装了两个方法实现分页操作
- 代码实现
@Test
public void testQuery6() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 分页查询
Query query = session.createQuery("from Customer");
// 设置分页的起始位置
query.setFirstResult(0);
// 设置分页查询的每页记录数
query.setMaxResults(1);
List<Customer> customers = query.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
---------------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_,
customer0_.name as name2_0_,
customer0_.level as level3_0_,
customer0_.source as source4_0_,
customer0_.phone as phone5_0_,
customer0_.mobile as mobile6_0_
from
t_customer customer0_ limit ?
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
投影查询
- 投影查询:查询的不是所有字段,而是部分字段
HQL语法
:select 实体类属性名称1, 实体类属性名称2 from 实体类名称;注意
:HQL查询中的select语句是不能写*
的,即不支持select *
写法- 代码实现
@Test
public void testQuery7() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 投影查询:查询部分字段
Query query = session.createQuery("select name from Customer");
List<Customer> customers = query.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------------
Hibernate:
select
customer0_.name as col_0_0_
from
t_customer customer0_
[AAAAA, BBBBB]
聚合函数查询
- 常用的聚合函数:count、sum、avg、max、min
HQL语法
:select count(*) from 实体类名称- 代码实现
@Test
public void testQuery8() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// HQL查询: 聚合函数的使用
Query query = session.createQuery("select count(*) from Customer");
Object result = query.uniqueResult(); //Query#uniqueResult()方法返回值为Long
int cnt = ((Long)result).intValue();
System.out.println(cnt);
tx.commit();
session.close();
sessionFactory.close();
}
-----------------------------------------------------------------------
Hibernate:
select
count(*) as col_0_0_
from
t_customer customer0_
2
QBC查询
- 使用HQL查询需要些HQL语句实现,但是使用QBC查询的时候就不需要再写语句了。使用方法实现
- 使用QBC操作的时候操作的是实体类及其属性
- 使用QBC查询使用的是Criteria对象实现
查询所有
@Test
public void testQuery9() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 调用Criteria对象的方法得到结果
List<Customer> customers = criteria.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------
Hibernate:
select
this_.id as id1_0_0_,
this_.name as name2_0_0_,
this_.level as level3_0_0_,
this_.source as source4_0_0_,
this_.phone as phone5_0_0_,
this_.mobile as mobile6_0_0_
from
t_customer this_
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456], Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null]]
条件查询
@Test
public void testQuery10() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 添加条件
criteria.add(Restrictions.eq("id", 11));
criteria.add(Restrictions.eq("name", "AAAAA"));
// 调用Criteria对象的方法得到结果
List<Customer> customers = criteria.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
--------------------------------------------------------------------------------
Hibernate:
select
this_.id as id1_0_0_,
this_.name as name2_0_0_,
this_.level as level3_0_0_,
this_.source as source4_0_0_,
this_.phone as phone5_0_0_,
this_.mobile as mobile6_0_0_
from
t_customer this_
where
this_.id=?
and this_.name=?
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
短语 | 含义 |
---|---|
Restrictions.eq | 等于= |
Restrictions.allEq | 使用Map,使用key:value进行多个等于的判断 |
Restrictions.gt | 大于> |
Restrictions.ge | 大于等于>= |
Restrictions.lt | 小于< |
Restrictions.le | 小于等于<= |
Restrictions.between | 对应SQL语句的between子句 |
Restrictions.like | 对应SQL语句的like子句 |
Restrictions.in | 对应SQL语句的in子句 |
Restrictions.and | and关系 |
Restrictions.or | or关系 |
Restrictions.sqlRestriction | SQL限定查询 |
Order.asc | 根据传入的字段升序排列 |
Order.desc | 根据传入的字段降序排列 |
排序查询
@Test
public void testQuery11() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 添加条件
criteria.addOrder(Order.desc("name"));
// 调用Criteria对象的方法得到结果
List<Customer> customers = criteria.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
--------------------------------------------------------------------------------
Hibernate:
select
this_.id as id1_0_0_,
this_.name as name2_0_0_,
this_.level as level3_0_0_,
this_.source as source4_0_0_,
this_.phone as phone5_0_0_,
this_.mobile as mobile6_0_0_
from
t_customer this_
order by
this_.name desc
[Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null], Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
分页查询
@Test
public void testQuery12() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(1);
// 调用Criteria对象的方法得到结果
List<Customer> customers = criteria.list();
System.out.println(customers);
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------------------
Hibernate:
select
this_.id as id1_0_0_,
this_.name as name2_0_0_,
this_.level as level3_0_0_,
this_.source as source4_0_0_,
this_.phone as phone5_0_0_,
this_.mobile as mobile6_0_0_
from
t_customer this_ limit ?
[Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]]
统计查询
@Test
public void testQuery13() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
// 调用Criteria对象的方法得到结果
Long ret = (Long)criteria.uniqueResult();
System.out.println(ret.intValue());
tx.commit();
session.close();
sessionFactory.close();
}
---------------------------------------------------------------------------------
Hibernate:
select
count(*) as y0_
from
t_customer this_
2
离线查询
HQL多表查询
- 内连接查询
- 左外连接查询
- 右外连接查询
- 迫切内连接查询
- 迫切左外连接查询
HQL内连接查询
HQL语法
:from Customer c inner join c.linkMans:连接条件:外键
@Test
public void testQuery14() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c inner join c.linkMans");
List objs = query.list(); // List集合的元素是数组
for (int i = 0; i < objs.size(); i++) {
Object[] obj = (Object[])(objs.get(i));
for (Object o : obj) {
System.out.println(o);
}
System.out.println("------------------------------");
}
tx.commit();
session.close();
sessionFactory.close();
}
----------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_0_,
linkmans1_.id as id1_1_1_,
customer0_.name as name2_0_0_,
customer0_.level as level3_0_0_,
customer0_.source as source4_0_0_,
customer0_.phone as phone5_0_0_,
customer0_.mobile as mobile6_0_0_,
linkmans1_.name as name2_1_1_,
linkmans1_.gender as gender3_1_1_,
linkmans1_.phone as phone4_1_1_,
linkmans1_.fk_limlman_customer as fk_limlm5_1_1_
from
t_customer customer0_
inner join
t_linkman linkmans1_
on customer0_.id=linkmans1_.fk_limlman_customer
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
LinkMan [id=22, name=M1, gender=male, phone=123456]
------------------------------
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
LinkMan [id=23, name=M3, gender=null, phone=null]
------------------------------
Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null]
LinkMan [id=21, name=M2, gender=female, phone=12345678]
------------------------------
迫切内连接查询
- 迫切内连接查询和内连接查询的底层实现是一样的
- 区别:使用内连接查询返回的List集合中的元素是数组;而使用迫切内连接查询返回的List集合的元素是对象
HQL语法
:from Customer c inner joinfetch
c.linkMans:连接条件:外键
@Test
public void testQuery15() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer c inner join fetch c.linkMans");
List<Customer> customers = query.list();
System.out.println("----------------------------");
for (Customer customer : customers) {
System.out.println(customer);
System.out.println(customer.getLinkMans());
System.out.println("----------------------------");
}
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_0_,
linkmans1_.id as id1_1_1_,
customer0_.name as name2_0_0_,
customer0_.level as level3_0_0_,
customer0_.source as source4_0_0_,
customer0_.phone as phone5_0_0_,
customer0_.mobile as mobile6_0_0_,
linkmans1_.name as name2_1_1_,
linkmans1_.gender as gender3_1_1_,
linkmans1_.phone as phone4_1_1_,
linkmans1_.fk_limlman_customer as fk_limlm5_1_1_,
linkmans1_.fk_limlman_customer as fk_limlm5_1_0__,
linkmans1_.id as id1_1_0__
from
t_customer customer0_
inner join
t_linkman linkmans1_
on customer0_.id=linkmans1_.fk_limlman_customer
----------------------------
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
[LinkMan [id=22, name=M1, gender=male, phone=123456], LinkMan [id=23, name=M3, gender=null, phone=null]]
----------------------------
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
[LinkMan [id=22, name=M1, gender=male, phone=123456], LinkMan [id=23, name=M3, gender=null, phone=null]]
----------------------------
Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null]
[LinkMan [id=21, name=M2, gender=female, phone=12345678]]
----------------------------
HQL左外连接查询 vs HQL迫切左外连接
HQL左外连接语法
:from Customer c left outer join c.linkMansHQL迫切左外连接语法
:from Customer c left outer joinfetch
c.linkMans- 左外连接查询返回的List集合中的元素是数组;迫切左外连接查询返回的List集合元素是对象
HQL右外连接查询
- 没有HQL迫切右外连接查询
HQL右外连接查询语法
:from Customer c right outer join c.linkMans
Hibernate检索策略
- Hibernate的检索策略分为两类:立即查询 vs 延迟查询
- 立即查询:根据id查询,调用get方法,一调用get方法立马发送SQL语句查询数据库
- 延迟查询:根据id查询,还有load方法,调用load方法不会马上发送SQL语句查询数据,只有得到对象里面的值的时候才会发送查询数据库的SQL语句
立即查询
延迟查询
- 延迟查询分为两类:
(1) 类级别延迟查询:根据id查询返回实体类对象,调用load方法不会马上发送SQL语句
(2) 关联界别延迟查询
批量抓取
- 查询所有的客户,返回List集合,遍历List集合,得到每个客户,得到每个客户的所有联系人
@Test
public void testQuery18() {
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Customer");
// 得到所有的客户
List<Customer> customers = query.list();
for (Customer customer : customers) {
System.out.println(customer);
Set<LinkMan> linkMans = customer.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
System.out.println("-----------------------------------------");
}
tx.commit();
session.close();
sessionFactory.close();
}
------------------------------------------------------------------------------------
Hibernate:
select
customer0_.id as id1_0_,
customer0_.name as name2_0_,
customer0_.level as level3_0_,
customer0_.source as source4_0_,
customer0_.phone as phone5_0_,
customer0_.mobile as mobile6_0_
from
t_customer customer0_
Customer [id=11, name=AAAAA, level=Vip, source=??, phone=110, mobile=123456]
Hibernate:
select
linkmans0_.fk_limlman_customer as fk_limlm5_1_0_,
linkmans0_.id as id1_1_0_,
linkmans0_.id as id1_1_1_,
linkmans0_.name as name2_1_1_,
linkmans0_.gender as gender3_1_1_,
linkmans0_.phone as phone4_1_1_,
linkmans0_.fk_limlman_customer as fk_limlm5_1_1_
from
t_linkman linkmans0_
where
linkmans0_.fk_limlman_customer=?
LinkMan [id=22, name=M1, gender=male, phone=123456]
LinkMan [id=23, name=M3, gender=null, phone=null]
-----------------------------------------
Customer [id=12, name=BBBBB, level=null, source=null, phone=null, mobile=null]
Hibernate:
select
linkmans0_.fk_limlman_customer as fk_limlm5_1_0_,
linkmans0_.id as id1_1_0_,
linkmans0_.id as id1_1_1_,
linkmans0_.name as name2_1_1_,
linkmans0_.gender as gender3_1_1_,
linkmans0_.phone as phone4_1_1_,
linkmans0_.fk_limlman_customer as fk_limlm5_1_1_
from
t_linkman linkmans0_
where
linkmans0_.fk_limlman_customer=?
LinkMan [id=21, name=M2, gender=female, phone
- 楼上的代码会导致多次查询数据库
- 解决方案:在用户的映射配置文件中的set标签增加batch-size属性,该属性值越大,发送的SQL语句就越少