Hibernate
如何使用
1、导入相关依赖
2、创建 Hibernate 配置文件
3、创建实体类
4、创建实体类–关系映射文件
5、调用 Hibernate API 完成操作
具体操作
1、创建Maven工程,pom.xml
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!--Hibernate-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
2、创建配置文件 hibernate.cfg.xml
核心配置:session-factory
SessionFactory:针对单个数据库映射经过编译的内存镜像文件,将数据库转化为一个java可以是别的镜像文件
构建SessionFactory非常耗费资源,所以通常一个工厂只需要创建一个SessionFactory。
<?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="connection.username">root</property>
<property name="connection.password">123.com</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3307/bdqn?useUnicode=true&characterEncoding=utf-8</property>
<!--连接池 C3P0 -->
<property name="hibernate.c3p0.acquire_increment">10</property>
<property name="hibernate.c3p0.idle_test_period">10000</property>
<property name="hibernate.c3p0.timeout">5000</property>
<property name="hibernate.c3p0.max_size">30</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_statements">10</property>
<!--数据库方言 MySQL-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--打印sql语句-->
<property name="show_sql">true</property>
<!--格式化sql-->
<property name="format_sql">true</property>
<!--是否自动生成数据表-->
<property name="hibernate.hbm2ddl.auto"></property>
</session-factory>
</hibernate-configuration>
3、创建实体类
package com.kai.pojo;
import lombok.Data;
import java.util.Set;
@Data
public class Customer {
private Integer id;
private String name;
private Set<Orders> orders;
}
package com.kai.pojo;
import lombok.Data;
@Data
public class Orders {
private Integer id;
private String name;
private Customer customer;
}
4、创建实体关系映射文件 xxx.hbm.xml
package com.kai.pojo;
import lombok.Data;
@Data
public class People {
private Integer id;
private String name;
private Double money;
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.People" table="people">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<property name="money" type="java.lang.Double">
<column name="money"></column>
</property>
</class>
</hibernate-mapping>
5、实体关系映射文件需要注册到 Hibernate 配置文件中
<!--注册实体关系映射文件-->
<mapping resource="com/kai/pojo/People.hbm.xml"></mapping>
6、使用 Hibernate API 完成数据操作
package com.kai.test;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取sessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session对象
Session session = sessionFactory.openSession();
People people = new People();
people.setName("张三");
people.setMoney(1000.0);
session.save(people);
session.beginTransaction().commit();
session.close();
}
}
7、pom.xml中需要配置resource
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
Hibernate级联操作
1、一对多关系
客户和订单:每个客户可以生成多个订单,但是一个订单只能属于一个客户,客户是一,订单是多
数据库中一的一方是主表,多的一方是从表,通过主外键关系来维护
2、多对多关系
学生选课:一门课程可以被多个学生选择,一个学生可以选择多门课程,学生是多,课程也是多。
数据库中是通过两个一对多关系来维护的,学生和课程都是主表,额外增加一张中间表作为从表,两张主表和中间表都是一对多关系
Java和数据库对于这两种关系的体现完全是两种不同的方式,Hibernate 框架的作用就是将这两种方式进行转换和映射。
Hibernate 实现一对多
Customer
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.Customer" table="customer">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<set name="orders" table="orders">
<key column="cid"></key>
<one-to-many class="com.kai.pojo.Orders"></one-to-many>
</set>
</class>
</hibernate-mapping>
- set 标签来配置实体类中的集合属性 orders
- name 实体类中的属性名
- table 表名
- key 外键
- one-to-many 与集合泛型的实体类对应
Orders
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.Orders" table="orders">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<many-to-one name="customer" class="com.kai.pojo.Customer" column="cid"></many-to-one>
</class>
</hibernate-mapping>
- many-to-one 配置实体类对应的对象属性
- name 属性名
- class 属性对应的类
- column 外键
需要在 Hibernate 配置文件中进行注册
<!--注册实体关系映射文件-->
<mapping resource="com/kai/pojo/Customer.hbm.xml"></mapping>
<mapping resource="com/kai/pojo/Orders.hbm.xml"></mapping>
Hibernate API 调用
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test2 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
// 创建Customer对象
Customer customer = new Customer();
customer.setName("张三");
//创建Orders对象
Orders orders = new Orders();
orders.setName("订单1");
//建立关联关系
orders.setCustomer(customer);
//保存
session.save(customer);
session.save(orders);
//提交事务
session.beginTransaction().commit();
session.close();
}
}
Hibernate 实现多对多
Account
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.Account" table="t_account">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<set name="courses" table="account_course">
<key column="aid"></key>
<many-to-many class="com.kai.pojo.Course" column="cid"></many-to-many>
</set>
</class>
</hibernate-mapping>
Course
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.Course" table="t_course">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<set name="accounts" table="account_course">
<key column="cid"></key>
<many-to-many class="com.kai.pojo.Account" column="aid"></many-to-many>
</set>
</class>
</hibernate-mapping>
- name 实体类对应的集合属性名
- table 中间表名
- key 外键
- many-to-many 集合泛型的实体类对应
- column 属性与中间表的外键字段名对应
注册到 Hibernate 配置文件中
<!--注册实体关系映射文件-->
<mapping resource="com/kai/pojo/Account.hbm.xml"></mapping>
<mapping resource="com/kai/pojo/Course.hbm.xml"></mapping>
Hibernate API 调用
package com.kai.test;
import com.kai.pojo.Account;
import com.kai.pojo.Course;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Set;
public class Test3 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Course course = new Course();
course.setName("Java");
Account account = new Account();
account.setName("张三");
//建立关联关系
Set<Course> courses = new HashSet<Course>();
courses.add(course);
account.setCourses(courses);
session.save(course);
session.save(account);
session.beginTransaction().commit();
session.close();
}
}
Hibernate 延迟加载
延迟加载、惰性加载、懒加载
使用延迟加载可以提高程序的运行效率,Java程序与数据库的交互频次越低,程序运行的效率越高,所以我们应该尽量减少Java程序与数据库的交互次数,Hibernate 延迟加载就很好的做到了这一点。
客户和订单,当我们查询客户对象的时候,因为有级联设置,所以会将对应的订单信息一并查出,这样的话就需要发送两条SQL语句,分别查询客户信息和订单信息。
延迟加载的思路是:当我们查询客户的时候,如果没有访问订单数据的话,那么就只发送一条SQL语句,来查询客户信息,如果需要访问订单数据的时候,则发送两条SQL。
延迟加载可以看做是一种优化机制,根据具体的需求,自动选择SQL语句数量。
一对多
1、查询 Customer,对 Orders 进行延迟加载设置,在 Customer.hbm.xml 中进行设置,延迟加载默认开启。
<set name="orders" table="orders" lazy="true">
<key column="cid"></key>
<one-to-many class="com.kai.pojo.Orders"></one-to-many>
</set>
2、查询 Customer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QDD59dO-1635998091452)(C:\Users\23578\AppData\Roaming\Typora\typora-user-images\image-20211012115423449.png)]
package com.kai.test;
import com.kai.pojo.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test4 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Customer customer = session.get(Customer.class,5);
System.out.println(customer);
session.close();
}
}
3、查询 Orders
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i2dJBGXj-1635998091454)(C:\Users\23578\AppData\Roaming\Typora\typora-user-images\image-20211012115505902.png)]
package com.kai.test;
import com.kai.pojo.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test4 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Customer customer = session.get(Customer.class,5);
System.out.println(customer.getOrders());
session.close();
}
}
lazy除了可以设置 true 和 false 之外,还可以设置 extra,extra 是比 true 更加懒惰的一种加载方式,或者说是更加智能的一种加载方式,通过例子看区别:
查询 customer 对象,打印该对象对应的 orders 集合的长度
使用 true
使用 extra
使用聚合函数 count 来统计,不需要封装成对象,再把对象装到集合里,在获取集合 size
也可以通过 Orders 来设置 Customer 的延迟加载,Orders.hbm.xml 中设置,lazy 默认 false
<many-to-one name="customer" class="com.kai.pojo.Customer" column="cid" lazy="proxy"></many-to-one>
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test5 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Orders orders = session.get(Orders.class,8);
System.out.println(orders);
session.close();
}
}
- No-proxy : 当调用方法需要访问 customer 成员变量时,发送 SQL 语句查询Customer,否则不查询
- proxy : 无论调用的方法是否需要访问 customer 的成员变量,都会发送 SQL 语句去查询 customer
多对多
查询 Course,加载对应的Account,默认延迟加载开启
package com.kai.test;
import com.kai.pojo.Course;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test6 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Course course = session.get(Course.class,4);
System.out.println(course);
session.close();
}
}
package com.kai.test;
import com.kai.pojo.Course;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test6 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Course course = session.get(Course.class,4);
System.out.println(course.getAccounts());
session.close();
}
}
Hibernate 配置文件
-
hibernate.cfg.xml
-
配置 Hibernate 的全局环境
-
1、数据库的基本信息
<!--数据源配置--> <property name="connection.username">root</property> <property name="connection.password">123.com</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3307/bdqn?useUnicode=true&characterEncoding=utf-8</property>
-
2、集成 C3P0,设置数据库连接池信息
<!--连接池 C3P0 --> <property name="hibernate.c3p0.acquire_increment">10</property> <property name="hibernate.c3p0.idle_test_period">10000</property> <property name="hibernate.c3p0.timeout">5000</property> <property name="hibernate.c3p0.max_size">30</property> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_statements">10</property>
-
3、Hibernate 基本信息
<!--数据库方言 MySQL--> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!--打印sql语句--> <property name="show_sql">true</property> <!--格式化sql--> <property name="format_sql">true</property> <!--是否自动生成数据表--> <property name="hibernate.hbm2ddl.auto"></property>
- update:动态创建表,如果表存在,则直接适用,如果不存在,则创建。
- create:无论表是否存在,都会重新创建。
- create-drop:初始化创建表,程序结束时删除表。
- validate:效验实体关系映射文件和数据表是否对应,不能对应直接报错。
-
4、注册实体关系映射文件
<!--注册实体关系映射文件--> <mapping resource="com/kai/pojo/People.hbm.xml"></mapping> <mapping resource="com/kai/pojo/Customer.hbm.xml"></mapping> <mapping resource="com/kai/pojo/Orders.hbm.xml"></mapping> <mapping resource="com/kai/pojo/Account.hbm.xml"></mapping> <mapping resource="com/kai/pojo/Course.hbm.xml"></mapping>
-
-
hbm.xml 实体关系映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.kai.pojo">
<class name="Course" table="t_course">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<set name="accounts" table="account_course" lazy="true">
<key column="cid"></key>
<many-to-many class="Account" column="aid"></many-to-many>
</set>
</class>
</hibernate-mapping>
hibernate-mapping 属性
-
package:给 class 节点对应的实体类统一设置包名,此处设置了包名,class 的 name 属性就可以省略包名
-
schema:数据库 schema 的名称
-
catalog:数据库 catalog 的名称
-
default-cascade:默认的级联关系,默认为 none
-
default-access:Hibernate 用来访问属性的策略
-
default-lazy:指定了未明确注明 lazy 属性的 Java 属性和集合类,Hibernate 会采用什么样的加载风格,默认为 True
-
auto-import:指定我们是否可以在查询语句中使用非全限定类名,默认为 True,如果项目中有两个同名的持久化类,最好在两个类的对应映射文件中配置为 false
class 属性
- name:实体类名
- table:数据表名
- schema:数据库 schema 的名称,会覆盖 hibernate-mapping 的 schema
- catalog:数据库 catalog 的名称,会覆盖 hibernate-mapping 的 catalog
- proxy:指定一个接口,在延迟加载时作为代理使用
- dynamic-update:动态更新
- dynamic-insert:动态添加
package com.kai.test;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test7 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
People people = new People();
people.setName("张三");
session.save(people);
session.close();
}
}
<class name="com.kai.pojo.People" table="people" dynamic-insert="true">
动态修改
package com.kai.test;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test7 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
People people = session.get(People.class,3);
people.setMoney(2000.0);
session.saveOrUpdate(people);
session.beginTransaction().commit();
session.close();
}
}
<class name="com.kai.pojo.People" table="people" dynamic-insert="true" dynamic-update="true">
- where:查询时给 SQL 语句添加 where 条件
package com.kai.test;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.List;
public class Test7 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People";
Query query = session.createQuery(hql);
List<People> list = query.list();
for (People people: list){
System.out.println(people);
}
session.beginTransaction().commit();
session.close();
}
}
<class name="com.kai.pojo.People" table="people" dynamic-insert="true" dynamic-update="true" where="id = 1">
id 属性
- name:实体类的属性名
- type:实体类属性的数据类型
此处可以设置两种类型的数据:Java数据类型 或者 Hibernate 映射类型
实体类的属性数据类型必须与数据表对应的字段数据类型一致:
int 对应 int,String 对应 varchar
如何进行映射?
Java数据类型映射到 hibernate 映射类型,再由 hibernate 映射类型映射到 SQL 的数据类型
Java —》 Hibernate —》 SQL
- column:数据表的主键字段名
- generator:主键的生成策略
- hilo 算法
- increment:Hibernate 自增
- identity:数据库自增
- native:本地策略,根据底层数据库自动选择主键的生成策略
- uuid.hex 算法
- select 算法
property 属性
- name:实体类的属性名
- column:数据表的字段名
- type:数据类型
- update:该字段是否可以修改,默认为 true
- insert:该字段是否可以添加,默认为 true
- lazy:延迟加载策略
实体关系映射文件属性
-
inverse
-
Customer 和 Orders 是一对多的关系,一个Customer 对应多个 Orders,实体类当中用一个集合来表示对应的 Orders
package com.kai.pojo; import lombok.Getter; import lombok.Setter; import java.util.Set; @Getter @Setter public class Customer { private Integer id; private String name; private Set<Orders> orders; @Override public String toString() { return "Customer{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
-
Customer.hbm.xml 中使用 set 标签来配置映射关系
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.kai.pojo.Customer" table="customer"> <!--主键映射--> <id name="id" type="java.lang.Integer"> <column name="id"></column> <!--自增--> <generator class="identity"></generator> </id> <property name="name" type="java.lang.String"> <column name="name"></column> </property> <set name="orders" table="orders" lazy="extra"> <key column="cid"></key> <one-to-many class="com.kai.pojo.Orders"></one-to-many> </set> </class> </hibernate-mapping>
-
package com.kai.pojo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Orders {
private Integer id;
private String name;
private Customer customer;
@Override
public String toString() {
return "Orders{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.kai.pojo.Orders" table="orders">
<!--主键映射-->
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<!--自增-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<many-to-one name="customer" class="com.kai.pojo.Customer" column="cid" lazy="proxy"></many-to-one>
</class>
</hibernate-mapping>
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test8 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Customer customer = new Customer();
customer.setName("李四");
Orders orders1 = new Orders();
orders1.setName("订单2");
orders1.setCustomer(customer);
Orders orders2 = new Orders();
orders2.setName("订单2");
orders2.setCustomer(customer);
session.save(customer);
session.save(orders1);
session.save(orders2);
session.beginTransaction().commit();
session.close();
}
}
~~===================================================================================~~
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Set;
public class Test8 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
Customer customer = new Customer();
customer.setName("李四");
Orders orders1 = new Orders();
orders1.setName("订单2");
orders1.setCustomer(customer);
Orders orders2 = new Orders();
orders2.setName("订单2");
orders2.setCustomer(customer);
Set<Orders> orders = new HashSet<Orders>();
orders.add(orders1);
orders.add(orders2);
customer.setOrders(orders);
session.save(customer);
session.save(orders1);
session.save(orders2);
session.beginTransaction().commit();
session.close();
}
}
因为 Customer 和 Orders 都在维护一对多的关系,所以会重复设置主外建约束关系
如何避免这种情况?
- 在Java代码中去掉一方维护关系代码
- 通过配置来解决
<!-- inverse="true" 放弃维护-->
<set name="orders" table="orders" lazy="extra" inverse="true">
<key column="cid"></key>
<one-to-many class="com.kai.pojo.Orders"></one-to-many>
</set>
inverse 属性是用来设置是否将维护权交给对方,默认是 false,不交出维护权,双方都在维护,将它设置为 true,表示 Customer 放弃维护。
cascade:用来设置级联操作
实体关系映射文件中设置 cascade 值完成级联删除
<!--cascade="delete" 级联删除-->
<set name="orders" table="orders" lazy="extra" inverse="true" cascade="delete">
<key column="cid"></key>
<one-to-many class="com.kai.pojo.Orders"></one-to-many>
</set>
Hibernate HQL
HQL: Hibernate Query Language,是 Hibernate框架提供的一种查询机制,它和SQL类似,不同的是HQL是面向对象的查询语句,让开发者能够以面向对象的思想来编写查询语句,对Java编程是一种很友好的方式。
HQL 不能直接参与数据库的交互,中间层语言
Java --》HQL --》hibernate --》SQL --》DB
HQL 只能完成查询、修改、删除,新增是无法操作的
1、查询对象
查询表中所有数据,自动完成对象的封装,返回List集合
HQL 进行查询,from 关键字后面不能有表名,必须写表对应的实体类名
from People
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People";
Query query = session.createQuery(hql);
List<People> list = query.list();
for(People people:list){
System.out.println(people);
}
session.close();
}
}
2、分页查询
HQL 分页查询可以通过调用query的方法来完成。
- setFirstResult() 设置起始下标
- setMaxResult() 设置截取长度
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(2);
List<People> list = query.list();
for(People people:list){
System.out.println(people);
}
session.close();
}
}
3、where 条件查询
HQL 直接追加 where 关键字作为条件查询,与 SQL 没有区别
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People where id = 1";
Query query = session.createQuery(hql);
People people = (People) query.list().get(0);
System.out.println(people);
session.close();
}
}
query.list()返回一个集合,通过.get(0) 取出结果
4、模糊查询
查询名称包含三的记录
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People where name like '%三%'";
Query query = session.createQuery(hql);
List<People> list = query.list();
for(People people:list){
System.out.println(people);
}
session.close();
}
}
5、order by
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People order by id desc";
Query query = session.createQuery(hql);
List<People> list = query.list();
for(People people:list){
System.out.println(people);
}
session.close();
}
}
6、查询实体对象的属性
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "select name from People where id = 1";
Query query = session.createQuery(hql);
String name = (String)query.uniqueResult();
System.out.println(name);
session.close();
}
}
7、占位符
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People where name = :name";
Query query = session.createQuery(hql);
query.setString("name","张三");
List<People> list = query.list();
for(People people:list){
System.out.println(list);
}
session.close();
}
}
8、级联查询
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql1 = "from Customer where name = :name";
Query query1 = session.createQuery(hql1);
query1.setString("name","张三");
Customer customer = (Customer)query1.uniqueResult();
String hql2 = "from Orders where customer = :customer";
Query query2 = session.createQuery(hql2);
query2.setEntity("customer",customer);
List<Orders> list = query2.list();
for(Orders orders:list){
System.out.println(orders);
}
session.close();
}
}
query.setString("name","张三");
List<People> list = query.list();
for(People people:list){
System.out.println(list);
}
session.close();
}
}
[外链图片转存中...(img-XEvW1AGO-1635998091470)]
### 8、级联查询
```java
package com.kai.test;
import com.kai.pojo.Customer;
import com.kai.pojo.Orders;
import com.kai.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test9 {
public static void main(String[] args) {
// 创建Configuration
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql1 = "from Customer where name = :name";
Query query1 = session.createQuery(hql1);
query1.setString("name","张三");
Customer customer = (Customer)query1.uniqueResult();
String hql2 = "from Orders where customer = :customer";
Query query2 = session.createQuery(hql2);
query2.setEntity("customer",customer);
List<Orders> list = query2.list();
for(Orders orders:list){
System.out.println(orders);
}
session.close();
}
}
[外链图片转存中…(img-sCikVujn-1635998091471)]