一、Hibernate框架的查询方式
1、唯一标识 OID 的检索方式。session.get(类.class,OID)
2、对象的导航的方式。做一对多的环境搭建的时候,Customer 的 JavaBean 定义了 Set集合
HQL 的检索方式 | Hibernate Query Language – Hibernate 的查询语言 |
QBC 的检索方式 | Query By Criteria – 条件查询 |
SQL 检索方式 | 本地的 SQL 检索 |
二、HQL查询方式
1、HQL 的介绍
HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似。
在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式。
2、HQL 与 SQL 的关系
HQL 查询语句是面向对象的,Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句.
HQL 查询语句中的主体是域模型中的类及类的属性(HQL 语句中使用的JavaBean 的类和类中的属性)
SQL 查询语句是与关系数据库绑定在一起的. SQL 查询语句中的主体是数据库表及表的字段
三、编写常规的JavaBean程序与映射配置文件
SQL的建库、建表
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/f1fd82196b547eb20b98b9a40042077f.jpeg)
CREATE TABLE `cst_customer` (
`cust_id` bigint(20) NOT NULL AUTO_INCREMENT,
`cust_name` varchar(255) DEFAULT NULL,
`cust_user_id` varchar(255) DEFAULT NULL,
`cust_source` varchar(255) DEFAULT NULL,
`cust_industry` varchar(255) DEFAULT NULL,
`cust_level` varchar(255) DEFAULT NULL,
`cust_linkman` varchar(255) DEFAULT NULL,
`cust_phone` varchar(255) DEFAULT NULL,
`cust_mobile` varchar(255) DEFAULT NULL,
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
/*Data for the table `cst_customer` */
insert into `cst_customer`
(`cust_id`,`cust_name`,`cust_user_id`,`cust_source`,
`cust_industry`,`cust_level`,`cust_linkman`,`cust_phone`,
`cust_mobile`) values
(1,'邓紫棋',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(2,'吴亦凡',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(3,'鹿晗',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(4,'柯震东',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(5,'杨紫',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(6,'古力娜扎',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(7,'郑秀晶',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(8,'林妙可',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(9,'昆凌',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(10,'李耐阅',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(11,'朴信惠',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(12,'林允儿',NULL,NULL,NULL,'2',NULL,NULL,NULL),
(13,'苍井优',NULL,NULL,NULL,'1',NULL,NULL,NULL),
(14,'宋茜',NULL,NULL,NULL,'2',NULL,NULL,NULL);
![cst_customer](https://i-blog.csdnimg.cn/blog_migrate/e1705c1db842ad0a83fecb98103aee4c.jpeg)
CREATE TABLE `cst_linkman` (
`lkm_id` bigint(20) NOT NULL AUTO_INCREMENT,
`lkm_name` varchar(255) DEFAULT NULL,
`lkm_gender` varchar(255) DEFAULT NULL,
`lkm_phone` varchar(255) DEFAULT NULL,
`lkm_mobile` varchar(255) DEFAULT NULL,
`lkm_email` varchar(255) DEFAULT NULL,
`lkm_qq` varchar(255) DEFAULT NULL,
`lkm_position` varchar(255) DEFAULT NULL,
`lkm_memo` varchar(255) DEFAULT NULL,
`lkm_cust_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`lkm_id`),
KEY `FKh9yp1nql5227xxcopuxqx2e7q` (`lkm_cust_id`),
CONSTRAINT `FKh9yp1nql5227xxcopuxqx2e7q` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
/*Data for the table `cst_linkman` */
insert into `cst_linkman`(`lkm_id`,`lkm_name`,`lkm_gender`,`lkm_phone`,
`lkm_mobile`,`lkm_email`,`lkm_qq`,`lkm_position`,`lkm_memo`,
`lkm_cust_id`) values
(1,'邓紫棋男友1',NULL,NULL,NULL,NULL,NULL,NULL,NULL,1),
(2,'邓紫棋男友2',NULL,NULL,NULL,NULL,NULL,NULL,NULL,1),
(3,'吴亦凡经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,2),
(4,'鹿晗麻麻',NULL,NULL,NULL,NULL,NULL,NULL,NULL,3),
(5,'柯震东经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,4),
(6,'杨紫 经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,5),
(7,'古力娜扎男朋友',NULL,NULL,NULL,NULL,NULL,NULL,NULL,6),
(8,'郑秀晶经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,7),
(9,'林妙可爸爸',NULL,NULL,NULL,NULL,NULL,NULL,NULL,8),
(10,'周杰伦',NULL,NULL,NULL,NULL,NULL,NULL,NULL,9),
(11,'李耐阅经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,10),
(12,'朴信惠经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,11),
(13,'林允儿经济人',NULL,NULL,NULL,NULL,NULL,NULL,NULL,12),
(16,'联系人1',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(17,'联系人2',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
![cst_linkman](https://i-blog.csdnimg.cn/blog_migrate/aaa9871121411bfa6b0ff451ee648f3a.jpeg)
JavaBean
/Hibernate5_d04_c01/src/hibernate/domain/Customer.java
程序代码如下:
package hibernate.domain;
public class Customer {
private Long cust_id;
private String cust_name;
private Long cust_user_id;
private Long cust_create_id;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_linkman;
private String cust_phone;
private String cust_mobile;
//set集合表示多个联系人
private Set<LinkMan> linkMans = new HashSet<>();
public Set<LinkMan> getLinkMans() {
return linkMans;
}
public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
}
public Long getCust_id() {
return cust_id;
}
public void setCust_id(Long cust_id) {
this.cust_id = cust_id;
}
public String getCust_name() {
return cust_name;
}
public void setCust_name(String cust_name) {
this.cust_name = cust_name;
}
public Long getCust_user_id() {
return cust_user_id;
}
public void setCust_user_id(Long cust_user_id) {
this.cust_user_id = cust_user_id;
}
public Long getCust_create_id() {
return cust_create_id;
}
public void setCust_create_id(Long cust_create_id) {
this.cust_create_id = cust_create_id;
}
public String getCust_source() {
return cust_source;
}
public void setCust_source(String cust_source) {
this.cust_source = cust_source;
}
public String getCust_industry() {
return cust_industry;
}
public void setCust_industry(String cust_industry) {
this.cust_industry = cust_industry;
}
public String getCust_level() {
return cust_level;
}
public void setCust_level(String cust_level) {
this.cust_level = cust_level;
}
public String getCust_linkman() {
return cust_linkman;
}
public void setCust_linkman(String cust_linkman) {
this.cust_linkman = cust_linkman;
}
public String getCust_phone() {
return cust_phone;
}
public void setCust_phone(String cust_phone) {
this.cust_phone = cust_phone;
}
public String getCust_mobile() {
return cust_mobile;
}
public void setCust_mobile(String cust_mobile) {
this.cust_mobile = cust_mobile;
}
}
/Hibernate5_d04_c01/src/hibernate/domain/LinkMan.java
程序代码如下:
package hibernate.domain;
public class LinkMan {
private Integer lkm_id;
private String lkm_name;
//lkm_cust_id 外键,不用写
private String lkm_gender;
private String lkm_phone;
private String lkm_mobile;
private String lkm_email;
private String lkm_qq;
private String lkm_position;
private String lkm_memo;
//客户类
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Integer getLkm_id() {
return lkm_id;
}
public void setLkm_id(Integer lkm_id) {
this.lkm_id = lkm_id;
}
public String getLkm_name() {
return lkm_name;
}
public void setLkm_name(String lkm_name) {
this.lkm_name = lkm_name;
}
public String getLkm_gender() {
return lkm_gender;
}
public void setLkm_gender(String lkm_gender) {
this.lkm_gender = lkm_gender;
}
public String getLkm_phone() {
return lkm_phone;
}
public void setLkm_phone(String lkm_phone) {
this.lkm_phone = lkm_phone;
}
public String getLkm_mobile() {
return lkm_mobile;
}
public void setLkm_mobile(String lkm_mobile) {
this.lkm_mobile = lkm_mobile;
}
public String getLkm_email() {
return lkm_email;
}
public void setLkm_email(String lkm_email) {
this.lkm_email = lkm_email;
}
public String getLkm_qq() {
return lkm_qq;
}
public void setLkm_qq(String lkm_qq) {
this.lkm_qq = lkm_qq;
}
public String getLkm_position() {
return lkm_position;
}
public void setLkm_position(String lkm_position) {
this.lkm_position = lkm_position;
}
public String getLkm_memo() {
return lkm_memo;
}
public void setLkm_memo(String lkm_memo) {
this.lkm_memo = lkm_memo;
}
}
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
package hibernate.test;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import hibernate.domain.Customer;
import hibernate.domain.LinkMan;
import hibernate.util.HibernateUtils;
public class TestHQL {
private Session session;
private Transaction tr;
private String hql ;
private List<Customer> list;
@Before
public void init(){
session = HibernateUtils.getCurrentSession();
tr = session.beginTransaction();
}
@After
public void destroy(){
tr.commit();
}
}
映射配置文件
/Hibernate5_d04_c01/src/hibernate/domain/Customer.hbm.xml
程序代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- javabean与表之间的对应关系 -->
<class name="hibernate.domain.Customer" table="cst_customer">
<!-- 主键对应 -->
<id name="cust_id" column="cust_id">
<!-- 主键策略(与自增长相关) -->
<generator class="native"></generator>
</id>
<!-- 其他字段 -->
<property name="cust_name" column="cust_name"></property>
<property name="cust_user_id" column="cust_user_id"></property>
<property name="cust_create_id" column="cust_create_id"></property>
<property name="cust_source" column="cust_source"></property>
<property name="cust_industry" column="cust_industry"></property>
<property name="cust_level" column="cust_level"></property>
<property name="cust_linkman" column="cust_linkman"></property>
<property name="cust_phone" column="cust_phone"></property>
<property name="cust_mobile" column="cust_mobile"></property>
<!-- 一对多配置 -->
<set name="linkMans" inverse="true" >
<!-- 外键 -->
<key column="lkm_cust_id"></key>
<!-- 一对多关系 -->
<one-to-many class="hibernate.domain.LinkMan"/>
</set>
</class>
</hibernate-mapping>
/Hibernate5_d04_c01/src/hibernate/domain/LinkMan.hbm.xml
程序代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernate.domain.LinkMan" table="cst_linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"></generator>
</id>
<property name="lkm_name" column="lkm_name"></property>
<property name="lkm_gender" column="lkm_gender"></property>
<property name="lkm_phone" column="lkm_phone"></property>
<property name="lkm_mobile" column="lkm_mobile"></property>
<property name="lkm_email" column="lkm_email"></property>
<property name="lkm_qq" column="lkm_qq"></property>
<property name="lkm_position" column="lkm_position"></property>
<property name="lkm_memo" column="lkm_memo"></property>
<!-- 多方配置 -->
<many-to-one name="customer" class="hibernate.domain.Customer"
column="lkm_cust_id" ></many-to-one>
</class>
</hibernate-mapping>
/Hibernate5_d04_c01/src/hibernate.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://127.0.0.1:3306/hibernate_day04</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--数据库方言 使用的数据库类型 -->
<property name="hibernate.dialect org.hibernate.dialect.MySQLDialect"></property>
<!-- 可选配置 -->
<!-- 在控制台输出sql语句 -->
<property name="show_sql">true</property>
<!-- 在控制台输出的sql语句格式化 -->
<property name="hibernate.format_sql">true</property>
<!-- 配置c3p0连接池 -->
<!-- C3P0 的供应商 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 最小连接 -->
<property name="hibernate.c3p0.min_size">5</property>
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">10</property>
<!-- 每 120 秒检查空闲连接 -->
<property name="hibernate.c3p0.timeout">120</property>
<!-- 自动建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 把session绑定到当前线程中,使用getCurrentSession()获取当前session -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 映射文件 -->
<mapping resource="hibernate/domain/Customer.hbm.xml"/>
<mapping resource="hibernate/domain/LinkMan.hbm.xml"/>
</session-factory>
</hibernate-configuration>
四、HQL基本的查询格式
1、基本查询
支持方法链的编程,即直接调用 list()方法
session.createQuery("from Customer").list();
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//1.HQL基本的查询格式
@Test
public void testHql1(){
//1.必须写实体类,不能写表名
//Customer 指的是 java 类,hibernate 通过 javabean 来操作数据库
hql = "from Customer";
//2.通过 session 的 createQuery 方法执行 hql语句
Query query = session.createQuery(hql);
//3.调用 list 方法获取集合值,使用泛型接收
list = query.list();
//4.遍历
for (Customer customer : list) {
System.out.println(customer.getCust_id()+"-->"+customer.getCust_name()+"-->"+customer.getCust_level());
}
}
}
![运行效果](https://i-blog.csdnimg.cn/blog_migrate/6468f80a6ecf3d4f498698be0a8514bc.jpeg)
![运行效果](https://i-blog.csdnimg.cn/blog_migrate/3b1c319611644a8d4a43ad3d29c1a488.jpeg)
![选中代码后右键](https://i-blog.csdnimg.cn/blog_migrate/0c613272fce5cabb6647b0844ea54ad3.png)
选中代码后右键
![封装成print方法](https://i-blog.csdnimg.cn/blog_migrate/54e601854c0916e920fce3218cac6cf4.jpeg)
封装成print方法
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//1.HQL基本的查询格式
@Test
public void testHql1(){
//1.必须写实体类,不能写表名
//Customer 指的是 java 类,hibernate 通过 javabean 来操作数据库
hql = "from Customer";
print();
}
private void print() {
//2.通过 session 的 createQuery 方法执行 hql语句
Query query = session.createQuery(hql);
//3.调用 list 方法获取集合值,使用泛型接收
list = query.list();
//4.遍历
for (Customer customer : list) {
System.out.println(customer.getCust_id()+"-->"+customer.getCust_name()+"-->"+customer.getCust_level());
}
}
}
2、别名查询
session.createQuery("from Customer c").list();
或session.createQuery("select c from Customer c").list();
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//2.使用别名的方式
//可以单独查询某几个字段
@Test
public void testHql2(){
//必须写实体类,不能写表名
//hql = "from Customer c";
hql = "select c from Customer c";
print();
}
private void print() {
...
}
}
3、排序查询
排序查询和 SQL 语句中的排序的语法是一样的
升序:session.createQuery("from Customer order by cust_id").list();
降序:ession.createQuery("from Customer order by cust_id desc").list();
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//3.排序查询
@Test
public void testHql3(){
//升序
//hql = "from Customer order by cust_id ";
//降序
hql = "from Customer order by cust_id desc";
print();
}
private void print() {
...
}
}
4、分页查询
Hibernate框架提供了分页的方法,可以调用方法来完成分页
两个方法如下:
setFirstResult(a) -- 从哪条记录开始,如果查询是从第一条开启,值是0
setMaxResults(b) -- 每页查询的记录条数
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//4.分页查询
@Test
public void testHql4(){
hql = "from Customer";
Query query = session.createQuery(hql);
//1.设置分页
// 设置起始索引
// 从第2条记录开始
query.setFirstResult(1);
//2.设置每页查询的记录条数
query.setMaxResults(3);
//获取的id为2、3、4的记录
//3.遍历
list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCust_id()+"-->"+customer.getCust_name()+"-->"+customer.getCust_level());
}
}
private void print() {
...
}
}
![封装成一个方法print1()](https://i-blog.csdnimg.cn/blog_migrate/c2a38eecacb58a6b1298bb164d587f0d.jpeg)
封装成一个方法print1()
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//4.分页查询
@Test
public void testHql4(){
hql = "from Customer";
Query query = session.createQuery(hql);
//1.设置分页
// 设置起始索引
// 从第2条记录开始
query.setFirstResult(1);
//2.设置每页查询的记录条数
query.setMaxResults(3);
//获取的id为2、3、4的记录
print1(query);
}
private void print1(Query query) {
//3.遍历
list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCust_id()+"-->"+customer.getCust_name()+"-->"+customer.getCust_level());
}
}
private void print() {
//2.通过 session 的 createQuery 方法执行 hql语句
Query query = session.createQuery(hql);
print1(query);
}
}
5、条件查询
setParameter("?号的位置,默认从 0 开始","参数的值"); 不用考虑参数的具体类型
按位置绑定参数的条件查询(指定下标值,默认从 0 开始)
按名称绑定参数的条件查询(HQL 语句中的 ? 号换成 :名称 的方式)
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//5.带条件的查询1
@Test
public void testHql5(){
//找出所有姓林的明星
hql = "from Customer where cust_name like ?";
Query query = session.createQuery(hql);
//设置?占位符的值
//第一个参数 ?的索引
//第二个参数 ?对应的值
query.setParameter(0, "林%");
print1(query);
}
...
private void print1(Query query) {
...
}
}
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//6.带条件的查询2
@Test
public void testHql6(){
//找出所有姓林的明星
hql = "from Customer where cust_name like :name";
Query query = session.createQuery(hql);
//设置:name占位符的值
//第一个参数:具体替换占位值
//第二个参数:替换的内容
query.setParameter("name", "林%");
print1(query);
}
...
private void print1(Query query) {
...
}
}
五、HQL的投影查询
投影查询就是想查询某一字段的值或者某几个字段的值
1、投影查询1
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//1.投影查询1
@Test
public void testHql7(){
//查找所有明星的姓名和级别
hql = "select c.cust_name,c.cust_level from Customer c";
Query query = session.createQuery(hql);
//这里不能用print(Query)方法来打印
//因为返回的是Object数组,需要使用Object数组来接收
//List data = query.list();
List<Object[]> data = query.list();
for (Object[] objects : data) {
System.out.println(objects[0]+"-->"+objects[1]);
}
}
...
private void print1(Query query) {
...
}
}
![查看返回的是什么类型的数据](https://i-blog.csdnimg.cn/blog_migrate/5d9730c6019e29801630b80c689601a2.png)
查看返回的是什么类型的数据
2、投影查询2
1、先在持久化类中提供对应字段的构造方法
2、使用下面这种HQL语句的方式
/Hibernate5_d04_c01/src/hibernate/domain/Customer.java
程序代码如下:
package hibernate.domain;
import java.util.HashSet;
import java.util.Set;
public class Customer {
...
//set集合表示多个联系人
private Set<LinkMan> linkMans = new HashSet<>();
/**
* @Title: Customer
* 需要提供一个空的构造方法,hibernate 默认使用空的构造方法来创建对象
*/
public Customer() {
// TODO Auto-generated constructor stub
}
/**
* @Title: Customer
* @param cust_name
* @param cust_level
*/
public Customer(String cust_name, String cust_level) {
this.cust_name = cust_name;
this.cust_level = cust_level;
}
...
}
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//2.投影查询2
@Test
public void testHql8(){
//如果查询两个字段,也可以把这两个字段封装到对象中
//先在持久化类中提供对应字段的构造方法
hql = "select new Customer(c.cust_name,c.cust_level) from Customer c";
Query query = session.createQuery(hql);
print1(query);
}
...
private void print1(Query query) {
...
}
}
六、HQL的聚合函数查询
uniqueResult() 唯一的结果。
如果查询的结果只包含一个对象,使用uniqueResult(),
如果查询结果包含多个对象,使用uniqueResult抛出异常。
1、聚合函数查询1
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//1.聚合函数查询1
//获取总的记录数
@Test
public void testHql9(){
hql = "select count(c) from Customer c";
Query query = session.createQuery(hql);
//因为返回的是Long类型的数,需要使用Long来接收
//Object o = (Long) query.uniqueResult();
Long o = (Long) query.uniqueResult();
System.out.println(o);
}
...
private void print1(Query query) {
...
}
}
![查看返回的是什么类型的数据](https://i-blog.csdnimg.cn/blog_migrate/b1a8ed7c9874b0a960d82c4b2ad20035.png)
查看返回的是什么类型的数据
2、聚合函数查询2
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//2.聚合函数查询2
//获取某一列数据的和
@Test
public void testHql10(){
hql = "select sum(c.cust_id) from Customer c";
Query query = session.createQuery(hql);
Long o = (Long) query.uniqueResult();
System.out.println(o);
}
...
private void print1(Query query) {
...
}
}
3、分组查询
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//3.分组查询
//对客户等级分组
@Test
public void testHql11(){
hql = "select c.cust_level from Customer c group by c.cust_level";
Query query = session.createQuery(hql);
//断点查看返回的是什么类型的数据
List<Object> data = query.list();
//System.out.println(data);
//输出[1, 2]
for (Object object : data) {
System.out.println(object);
}
//输出
//1
//2
}
...
private void print1(Query query) {
...
}
}
七、HQL的多表查询
多表的查询进来使用 HQL 语句进行查询,HQL 语句和 SQL 语句的查询语法比较类似。
内连接查询
显示内连接
select * from customers c inner join orders oon c.cid = o.cno;
隐式内连接
select * from customers c,orders o where c.cid = o.cno;
外连接查询
左外连接
select * from customers c left join orders o onc.cid = o.cno;
右外连接
select * from customers c right join orders o onc.cid = o.cno;
1、内连接查询
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//1.内连接查询
//查询所有客户及对应的联系人(有关联关系的)
@Test
public void testHql12(){
//显示内连接
hql = "from Customer c inner join c.linkMans";
Query query = session.createQuery(hql);
//断点查看返回的是什么类型的数据
//返回的是Object数组
List<Object[]> data = query.list();
for (Object[] objects : data) {
Customer c = (Customer) objects[0];
LinkMan m = (LinkMan) objects[1];
System.out.println(c.getCust_name()+"-->"+m.getLkm_name());
}
}
...
private void print1(Query query) {
...
}
}
2、迫切内连接
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//2.迫切内连接
//查询所有客户及对应的联系人(有关联关系的)
@Test
public void testHql13(){
hql = "from Customer c inner join fetch c.linkMans";
Query query = session.createQuery(hql);
//断点查看返回的是什么类型的数据
//返回的是实体对象
List<Customer> data = query.list();
for (Customer customer : data) {
System.out.println(customer.getCust_name()+"-->"+customer.getLinkMans().size());
}
}
...
private void print1(Query query) {
...
}
}
3、左外连接查询
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//3.左外连接
//查询所有客户及对应的联系人(没有关联关系+有关联关系的)
@Test
public void testHql14(){
hql = "from Customer c left join c.linkMans";
Query query = session.createQuery(hql);
//断点查看返回的是什么类型的数据
//返回的是Object数组
List<Object[]> data = query.list();
for (Object[] objects : data) {
Customer c = (Customer) objects[0];
System.out.println(c.getCust_name()+"-->"+c.getLinkMans().size());
}
}
...
private void print1(Query query) {
...
}
}
4、迫切左外连接
/Hibernate5_d04_c01/src/hibernate/test/TestHQL.java
程序代码如下:
...
public class TestHQL {
...
//4.迫切左外连接
//查询所有客户及对应的联系人(没有关联关系+有关联关系的)
@Test
public void testHql15(){
hql = "from Customer c left join fetch c.linkMans";
Query query = session.createQuery(hql);
//断点查看返回的是什么类型的数据
//返回的是实体对象
List<Customer> data = query.list();
for (Customer customer : data) {
System.out.println(customer.getCust_name()+"-->"+customer.getLinkMans().size());
}
}
...
private void print1(Query query) {
...
}
}
八、QBC查询方式(做条件查询非常合适)
1、QBC:Query By Criteria – 按条件进行查询。
2、QBC 查询方式的使用
1、先创建查询的接口
Criteria c = session.createCriteria(User.class);
2、设置查询的条件
criteria.add(Restrictions.gt("age", 10));
3、查询数据
List<User> list = criteria.list();
九、编写常规的JavaBean程序与映射配置文件
1、数据库及数据表同HQL一样
2、拷贝项目Hibernate5_d04_c01的jar包、配置、util类、domain类
十、QBC基本的查询格式
1、基本查询
简单查询:使用的是 Criteria 接口
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
package hibernate.test;
import java.util.Arrays;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import hibernate.domain.Customer;
import hibernate.util.HibernateUtils;
public class TestQBC {
private Session session;
private Transaction tr;
private String hql ;
private List<Customer> list;
@Before
public void init(){
session = HibernateUtils.getCurrentSession();
tr = session.beginTransaction();
}
@After
public void destroy(){
tr.commit();
}
//1.简单查询,使用的是Criteria接口
//查询所有客户信息
@Test
public void testQBC1(){
Criteria criteria = session.createCriteria(Customer.class);
print(criteria);
}
private void print(Criteria criteria) {
//调用list方法获取集合值,使用泛型接收
list = criteria.list();
//遍历
for (Customer customer : list) {
System.out.println(customer.getCust_id()+"-->"+customer.getCust_name()+"-->"+customer.getCust_level());
}
}
}
2、排序查询
需要使用addOrder()的方法来设置参数,
参数使用org.hibernate.criterion.Customer对象
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//2.排序查询
@Test
public void testQBC2(){
Criteria criteria = session.createCriteria(Customer.class);
//添加排序条件
criteria.addOrder(Order.desc("cust_id"));
print(criteria);
}
private void print(Criteria criteria) {
...
}
}
3、分页查询
QBC的分页查询也是使用两个方法
setFirstResult();
setMaxResults();
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//3.分页查询
@Test
public void testQBC3(){
Criteria criteria = session.createCriteria(Customer.class);
//设置分页条件
criteria.setFirstResult(1);
criteria.setMaxResults(3);
print(criteria);
}
private void print(Criteria criteria) {
...
}
}
4、条件查询
Criterion 是查询条件的接口。
Restrictions 类是 Hibernate 框架提供的工具类,用来设置查询条件。
条件查询使用 Criteria 接口的 add 方法,用来传入条件。
Restrictions.eq | 相等 |
Restrictions.gt | 大于号 |
Restrictions.ge | 大于等于 |
Restrictions.lt | 小于 |
Restrictions.le | 小于等于 |
Restrictions.between | 在之间 |
Restrictions.like | 模糊查询 |
Restrictions.in | 范围 |
Restrictions.and | 并且 |
Restrictions.or | 或者 |
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//4.条件查询
//查询所有等级为2或者姓名中带邓的客户
@Test
public void testQBC4(){
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.or(
Restrictions.eq("cust_level", "2"),
Restrictions.like("cust_name", "邓%")
));
print(criteria);
}
private void print(Criteria criteria) {
...
}
}
十一、QBC的聚合函数查询
Projection 的聚合函数的接口,
而 Projections 是 Hibernate 提供的工具类,
使用该工具类设置聚合函数查询。
使用 QBC 的聚合函数查询,
需要使用 criteria.setProjection() 方法
1、聚合函数查询1
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//1.聚合函数查询1
//查询所有客户的数量
@Test
public void testQBC5(){
Criteria criteria = session.createCriteria(Customer.class);
//使用聚合函数查询
criteria.setProjection(Projections.rowCount());
Long count = (Long) criteria.uniqueResult();
System.out.println(count);
}
private void print(Criteria criteria) {
...
}
}
2、聚合函数查询2
聚合函数的查询
criteria.setProjection(Projections.sum("cust_id"));
多次设置该方法,默认会覆盖。
解决覆盖的问题 :
ProjectionList projectionList = Projections.projectionList();
向集合中添加聚合函数的设置。
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//2.聚合函数查询2
//查询所有客户的数量以及cust_id的和
@Test
public void testQBC6(){
Criteria criteria = session.createCriteria(Customer.class);
//使用聚合函数查询
//这样写后面一个条件会覆盖前面一个条件
//criteria.setProjection(Projections.rowCount());
//criteria.setProjection(Projections.sum("cust_id"));
//使用 ProjectionList来解决这个问题
//ProjectionList可以存储多个条件
ProjectionList list = Projections.projectionList();
list.add(Projections.rowCount());
list.add(Projections.sum("cust_id"));
criteria.setProjection(list);
Object[] data = (Object[]) criteria.uniqueResult();
//System.out.println(data[0]+"-->"+data[1]);
//输出14-->105
System.out.println(Arrays.toString(data));
//输出[14, 105]
}
private void print(Criteria criteria) {
...
}
}
3、分组查询
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//3.分组查询
//分组+统计
@Test
public void testQBC7(){
Criteria criteria = session.createCriteria(Customer.class);
//使用聚合函数查询
//ProjectionList来存储多个条件
ProjectionList list = Projections.projectionList();
//添加分组条件
list.add(Projections.groupProperty("cust_level"));
//添加统计条件
list.add(Projections.rowCount());
//设置条件列表
criteria.setProjection(list);
List<Object[]> data = criteria.list();
for (Object[] objects : data) {
//System.out.println(objects[0]+"-->"+objects[1]);
//1-->7
//2-->7
System.out.println(Arrays.toString(objects));
//[1, 7]
//[2, 7]
}
}
private void print(Criteria criteria) {
...
}
}
十二、QBC的多表查询
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//多表查询
//查询每个用户对应联系人的数量(有关联关系的)
@Test
public void testQBC8(){
Criteria criteria = session.createCriteria(Customer.class);
//设置内连接查询
//第一个参数是客户类中联系人属性
//第二个参数是连接类型
criteria.createCriteria("linkMans", JoinType.INNER_JOIN);
List<Customer> customers = criteria.list();
for (Customer customer : customers) {
System.out.println(customer.getCust_name()+"-->"+customer.getLinkMans().size());
}
}
private void print(Criteria criteria) {
...
}
}
十三、SQL 查询方式
/Hibernate5_d04_c02/src/hibernate/test/TestQBC.java
程序代码如下:
...
public class TestQBC {
...
//SQL查询方式
@Test
public void testSql(){
//查询客户表中数据
String sql ="select * from cst_customer where cust_id > ?";
SQLQuery query = session.createSQLQuery(sql);
//设置条件参数
query.setParameter(0, 2L);
//把返回数据加入实体类中
query.addEntity(Customer.class);
list = query.list();
for (Customer customer : list) {
System.out.println(customer.getCust_name()+"-->"+customer.getLinkMans().size());
}
}
private void print(Criteria criteria) {
...
}
}