Hibernate学习笔记

本文详细介绍了Hibernate框架的使用,包括导入依赖、配置文件设置、实体类和映射文件创建、级联操作、一対多和多对多关系映射、延迟加载以及HQL查询。通过示例代码展示了如何在Java中操作数据库,如保存、删除数据以及进行分页和条件查询。同时,还讨论了延迟加载的策略和级联操作的配置,以提高程序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hibernate学习笔记

如何使⽤

1、导⼊相关依赖
2、创建 Hibernate 配置⽂件
3、创建实体类
4、创建实体类-关系映射⽂件
5、调⽤ Hibernate API 完成操作

具体操作

1、创建 Maven ⼯程,pom.xml

<dependencies>
	 <dependency>
		 <groupId>mysql</groupId>
		 <artifactId>mysql-connector-java</artifactId>
		 <version>8.0.19</version>
	 </dependency>
	 <dependency>
		 <groupId>org.hibernate</groupId>
		 <artifactId>hibernate-core</artifactId>
		 <version>5.4.10.Final</version>
	 </dependency>
	 <dependency>
		 <groupId>org.projectlombok</groupId>
		 <artifactId>lombok</artifactId>
		 <version>1.18.10</version>
	 </dependency>
</dependencies>

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://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	 <session-factory>
		 <!-- 数据源配置 -->
		 <property name="connection.username">root</property>
		 <property name="connection.password">root</property>
		 <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
		 <property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;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>
		 
		 <!-- 数据库⽅⾔ -->
		 <property name="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.southwind.entity;
import lombok.Data;
import java.util.Set;
@Data
public class Customer {
 private Integer id;
 private String name;
 private Set<Orders> orders;
}
package com.southwind.entity;
import lombok.Data;
@Data
public class Orders {
 private Integer id;
 private String name;
 private Customer customer;
}

4、创建实体关系映射⽂件

package com.southwind.entity;
import lombok.Data;
@Data
public class People {
 private Integer id;
 private String name;
 private Double money;
}

在这里插入图片描述

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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 的配置⽂件中。

<!-- 注册实体关系映射⽂件hibernate.cfg.xml -->
<session-factory>
	...
	<mapping resource="com/southwind/entity/People.hbm.xml"></mapping>
</session-factory>

6、使⽤ Hibernate API 完成数据操作。

package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取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、⼀对多关系
客户和订单:每个客户可以购买多个产品,⽣成多个订单,但是⼀个订单只能属于⼀个客户,所以客户
是⼀,订单是多。
在这里插入图片描述
数据库中⼀的⼀⽅是主表,多的⼀⽅时候从表,通过主外键关系来维护。
⾯向对象中:

package com.southwind.entity;
import lombok.Data;
import java.util.Set;
@Data
public class Customer {
 private Integer id;
 private String name;
 private Set<Orders> orders;
}
package com.southwind.entity;
import lombok.Data;
@Data
public class Orders {
 private Integer id;
 private String name;
 private Customer customer;
}

2、多对多关系
学⽣选课:⼀⻔课程可以被多个学⽣选择,⼀个学⽣可以选择多⻔课程,学⽣是多,课程也是多。
数据库中是通过两个⼀对多关系来维护的,学⽣和课程都是主表,额外增加⼀张中间表作为从表,两张
主表和中间表都是⼀对多关系。
在这里插入图片描述
⾯向对象中:

package com.southwind.entity;
import lombok.Data;
import java.util.Set;
@Data
public class Account {
 private Integer id;
 private String name;
 private Set<Course> courses;
}
package com.southwind.entity;
import lombok.Data;
import java.util.Set;
@Data
public class Course {
 private Integer id;
 private String name;
 private Set<Account> accounts;
}

Java 和数据库对于这两种关系的体现完全是两种不同的⽅式,Hibernate 框架的作⽤就是将这两种⽅式
进⾏转换和映射。

Hibernate 实现⼀对多与多对多

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Orders"></one-to-many>
		 </set>
	 </class>
</hibernate-mapping>
  • set 标签来配置实体类中的集合属性 orders
  • name 实体类属性名
  • table 表名
  • key 外键
  • one-to-many 与集合泛型的实体类对应
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Customer" column="cid"></many-to-one>
	 </class>
</hibernate-mapping>
  • many-to-one 配置实体类对应的对象属性
  • name 属性名
  • class 属性对应的类
  • column 外键

需要在 Hibernate 配置⽂件中进⾏注册

<!-- 注册实体关系映射⽂件 -->
<mapping resource="com/southwind/entity/Customer.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Orders.hbm.xml"></mapping>

⼀对多
Hibernate API

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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("hibernate.xml");
	 //获取 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
	 session.close();
 }
}

多对多

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Course" column="cid"></many-to-many>
		 </set>
	 </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Account" column="aid"></many-to-many>
		 </set>
	 </class>
</hibernate-mapping>

name 实体类对应的集合属性名
table 中间表名
key 外键
many-to-many 与集合泛型的实体类对应
column 属性与中间表的外键字段名对应

注册 Hibernate 配置⽂件中

<mapping resource="com/southwind/entity/Account.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Course.hbm.xml"></mapping>

Hibernate API

package com.southwind.test;
import com.southwind.entity.Account;
import com.southwind.entity.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("hibernate.xml");
	 //获取 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<>();
	 courses.add(course);
	 account.setCourses(courses);
	 session.save(course);
	 session.save(account);
	 session.beginTransaction().commit();
	 session.close();
 }
}

Hibernate 延迟加载

延迟加载、惰性加载、懒加载

使⽤延迟加载可以提⾼程序的运⾏效率,Java 程序与数据库交互的频次越低,程序运⾏的效率就越⾼,
所以我们应该尽量减少 Java 程序与数据库的交互次数,Hibernate 延迟加载就很好的做到了这⼀点。

客户和订单,当我们查询客户对象时,因为有级联设置,所以会将对应的订单信息⼀并查询出来,这样
就需要发送两条 SQL 语句,分别查询客户信息和订单信息。

延迟加载的思路是:当我们查询客户的时候,如果没有访问订单数据,只发送⼀条 SQL 语句查询客户信
息,如果需要访问订单数据,则发送两条 SQLL。

延迟加载可以看作是⼀种优化机制,根据具体的需求,⾃动选择要执⾏的 SQL 语句数量。

⼀对多

1、查询 Customer,对 orders 进⾏延迟加载设置,在 customer.hbm.xml 进⾏设置,延迟加载默认开
启。

<set name="orders" table="orders" lazy="true">
 <key column="cid"></key>
 <one-to-many class="com.southwind.entity.Orders"></one-to-many>
</set>

2、查询 Customer

package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 Customer customer = session.get(Customer.class,15);
	 System.out.println(customer);
	 session.close();
 }
}

在这里插入图片描述

package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 Customer customer = session.get(Customer.class,15);
	 System.out.println(customer.getOrders());  //查orders
	 session.close();
 }
}

在这里插入图片描述
false:

package com.southwind.test;
import com.southwind.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
lazy 除了可以设置 truefalse 之外,还可以设置 extra,extra 是⽐ true 更加懒惰的⼀种加载⽅式,
或者说是更加智能的⼀种加载⽅式,通过例⼦看区别:
查询 Customer 对象,打印该对象对应的 orders 集合的⻓度
public class Test4 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 Customer customer = session.get(Customer.class,15);
	 System.out.println(customer);
	 session.close();
 }
}

在这里插入图片描述
lazy 除了可以设置 true 和 false 之外,还可以设置 extra,extra 是⽐ true 更加懒惰的⼀种加载⽅式,
或者说是更加智能的⼀种加载⽅式,通过例⼦看区别:

查询 Customer 对象,打印该对象对应的 orders 集合的⻓度:

package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Customer customer = session.get(Customer.class,15);
	 System.out.println(customer.getOrders().size());
	 session.close();
 }
}

在这里插入图片描述
也可以通过 Orders 来设置 Customer 的延迟加载,orders.hbm.xml 中进⾏设置。

<many-to-one name="customer" class="com.southwind.entity.Customer" column="cid" lazy="proxy"></many-to-one>
package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 Orders orders = session.get(Orders.class,26);
	 System.out.println(orders);
	 session.close();
 }
}

在这里插入图片描述

package com.southwind.test;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Orders orders = session.get(Orders.class,26);
	 System.out.println(orders.getCustomer());
	 session.close();
 }
}

在这里插入图片描述
no-proxy:当调⽤⽅法需要访问 customer 的成员变量时,发送 SQL 语句查询 Customer,否则不查
询。
proxy:⽆论调⽤⽅法是否需要访问 customer 的成员变量,都会发送 SQL 语句查询 Customer。

多对多

查询 Course,加载对应的 Account,默认延迟加载开启。

package com.southwind.test;
import com.southwind.entity.Course;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Course course = session.get(Course.class,5);
	 System.out.println(course);
	 session.close();
 }
}

在这里插入图片描述

package com.southwind.test;
import com.southwind.entity.Course;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Course course = session.get(Course.class,5);
	 System.out.println(course.getAccounts());
	 session.close();
 }
}

在这里插入图片描述

<set name="accounts" table="account_course" lazy="false">
 <key column="cid"></key>
 <many-to-many class="com.southwind.entity.Account" column="aid"></many-tomany>
</set>
package com.southwind.test;
import com.southwind.entity.Course;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Course course = session.get(Course.class,5);
	 System.out.println(course);
	 session.close();
 }
}

在这里插入图片描述

<set name="courses" table="account_course" lazy="true">
 <key column="aid"></key>
 <many-to-many class="com.southwind.entity.Course" column="cid"></many-tomany>
</set>
package com.southwind.test;
import com.southwind.entity.Account;
import com.southwind.entity.Course;
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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Account account = session.get(Account.class,5);
	 System.out.println(account);
	 session.close();
 }
}

在这里插入图片描述

Hibernate 配置⽂件

  • hibernate.xml
  • hbm.xml

Hibernate.xml

hibernate.xml 配置 Hibernate 的全局环境。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	 <session-factory>
		 <!-- 数据源配置 -->
		 <property name="connection.username">root</property>
		 <property name="connection.password">root</property>
		 <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
		 <property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;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>
		 
		 <!-- 数据库⽅⾔ -->
		 <property name="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>
		 
		 <!-- 注册实体关系映射⽂件 -->
		 <mapping resource="com/southwind/entity/People.hbm.xml"></mapping>
		 <mapping resource="com/southwind/entity/Customer.hbm.xml"></mapping>
		 <mapping resource="com/southwind/entity/Orders.hbm.xml"></mapping>
		 <mapping resource="com/southwind/entity/Account.hbm.xml"></mapping>
		 <mapping resource="com/southwind/entity/Course.hbm.xml"></mapping>
	 </session-factory>
</hibernate-configuration>

1、数据库的基本信息。

<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8</property>

2、集成 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 基本信息。

<!-- 数据库⽅⾔ -->
<property name="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:动态创建表,如果表存在,则直接使⽤,如果表不存在,则创建。<property name="hibernate.hbm2ddl.auto" value="update" />
create:⽆论表是否存在,都会重新创建。
create-drop:初始化创建表,程序结束时删除表。
validate:校验实体关系映射⽂件和数据表是否对应,不能对应直接报错。

4、注册实体关系映射⽂件。

<!-- 注册实体关系映射⽂件 -->
<mapping resource="com/southwind/entity/People.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Customer.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Orders.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Account.hbm.xml"></mapping>
<mapping resource="com/southwind/entity/Course.hbm.xml"></mapping>

实体关系映射⽂件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.southwind.entity">
	 <class name="com.southwind.entity.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="false">
			 <key column="cid"></key>
			 <many-to-many class="com.southwind.entity.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:动态添加

<class name="com.southwind.entity.People" table="people" dynamicinsert="true">

where:查询时给 SQL 添加 where 条件

package com.southwind.test;
import com.southwind.entity.Account;
import com.southwind.entity.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 Test8 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 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.southwind.entity.People" table="people" dynamic-insert="true" dynamic-update="true" where="id = 6">

在这里插入图片描述

id 属性

  • name:实体类属性名
  • type:实体类属性数据类型

此处可以设置两种类型的数据:Java 数据类型或者 Hibernate 映射类型。
实体类的属性数据类型必须与数据表对应的字段数据类型⼀致:
int 对应 int,String 对应 varchar
如何进⾏映射?
Java 数据类型映射到 Hibernate 映射类型,再由 Hibernate 映射类型映射到 SQL 数据类型

Java ====》Hibernate ====》SQL

  • column:数据表的主键字段名
  • generator:主键⽣成策略
    1、hilo 算法
    2、increment:Hibernate ⾃增
    3、identity:数据库⾃增
    4、native:本地策略,根据底层数据库⾃动选择主键的⽣成策略
    5、uuid.hex 算法
    6、select 算法

property 属性

name:实体类的属性名
column:数据表字段名
type:数据类型
update:该字段是否可以修改,默认为 true
insert:该字段是否可以添加,默认为 true
lazy:延迟加载策略

实体关系映射⽂件属性

1、inverse
Customer 和 Orders 是⼀对多关系,⼀个 Customer 对应多个 Orders,实体类中⽤⼀个 set 集合来表
示对应的 Orders。

package com.southwind.entity;
import lombok.Data;
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"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Orders"></one-to-many>
		 </set>
	 </class>
</hibernate-mapping>
package com.southwind.entity;
import lombok.Data;
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"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	 <class name="com.southwind.entity.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.southwind.entity.Customer" column="cid" lazy="proxy"></many-to-one>
	 </class>
</hibernate-mapping>
package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.Orders;
import com.southwind.entity.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 Test9 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Customer customer = new Customer();
	 customer.setName("张三");
	 Orders orders1 = new Orders();
	 orders1.setName("订单1");
	 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.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.Orders;
import com.southwind.entity.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("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Customer customer = new Customer();
	 customer.setName("张三");
	 Orders orders1 = new Orders();
	 orders1.setName("订单1");
	 orders1.setCustomer(customer);
	 Orders orders2 = new Orders();
	 orders2.setName("订单2");
	 orders2.setCustomer(customer);
	 Set<Orders> orders = new HashSet<>();
	 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 都在维护⼀对多关系,所以会重复设置主外键约束关系。
如何避免这种情况?
1、在 Java 代码中去掉⼀⽅维护关系代码。
2、通过配置来解决。

<set name="orders" table="orders" lazy="extra" inverse="true">
 <key column="cid"></key>
 <one-to-many class="com.southwind.entity.Orders"></one-to-many>
</set>

inverse 属性是⽤来设置是否将维护权交给对⽅,默认是 false,不交出维护权,双⽅都在维护,将它设
置为 true,表示 Customer 放弃维护。

cascade:⽤来设置级联操作

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Test10 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 Customer customer = session.get(Customer.class,18);
	 
	 Iterator<Orders> iterator = customer.getOrders().iterator();
	 while(iterator.hasNext()){
	 	session.delete(iterator.next());
	 }
	
	 session.delete(customer);
	
	 session.beginTransaction().commit();
	 session.close();
 }
}

实体关系映射⽂件中设置 cascade 值完成级联删除。

<set name="orders" table="orders" lazy="extra" inverse="true"
cascade="delete">
 <key column="cid"></key>
 <one-to-many class="com.southwind.entity.Orders"></one-to-many>
</set>
package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Test10 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 Customer customer = session.get(Customer.class,19);
	 session.delete(customer);
	 session.beginTransaction().commit();
	 session.close();
 }
}

Hibernate HQL

HQL:Hibernate Query Language,是 Hibernate 框架提供的⼀种查询机制,它和 SQL 类似,不同的
是 HQL 是⾯向对象的查询语句,让开发者能够以⾯向对象的思想来编写查询语句,对 Java 编程是⼀种
好友好的⽅式。
HQL 不能直接参与数据库的交互,中间层语⾔。
Java ====》 HQL ====》Hibernate ====》SQL ====》DB
HQL 只能完成查询、修改、删除,新增是⽆法操作的。

1、查询对象

查询表中所有数据,⾃动完成对象的封装,返回 List 集合。
HQL 进⾏查询,from 关键字后⾯不能写表名,必须写表对应的实体类名。

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 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 的⽅法来完成。
1、setFirstResult() 设置起始下标
2、setMaxResults() 设置截取⻓度

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 String hql = "from People";
	 Query query = session.createQuery(hql);
	 query.setFirstResult(1);
	 query.setMaxResults(3);
	 List<People> list = query.list();
	 for(People people:list){
	 	System.out.println(people);
	 }
	 session.close();
 }
}

3、where 条件查询

HQL 直接追加 where 关键字作为查询条件,与 SQL 没有区别。

import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 String hql = "from People where id = 6";
	 Query query = session.createQuery(hql);
	 People people = (People) query.list().get(0);
	 System.out.println(people);
	 session.close();
 }
}

query.list() 返回⼀个集合,此时集合中只有⼀个对象,通过下标 0 取出该对象。

String hql = "from People where id = 0";
Query query = session.createQuery(hql);
People people = (People) query.uniqueResult();
System.out.println(people);

不会抛出异常。

4、模糊查询

查询名称包含 “三” 的所有记录

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 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

按照 id 进⾏排序

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	 
	 String hql = "from People order by id asc ";
	 Query query = session.createQuery(hql);
	 List<People> list = query.list();
	 for(People people:list){
	 	System.out.println(people);
	 }
	 session.close();
 }
}

asc 是⽣序排列,desc 是降序排列。

6、查询实体对象的属性

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 SessionFactory
	 SessionFactory sessionFactory = configuration.buildSessionFactory();
	 //获取 Session
	 Session session = sessionFactory.openSession();
	
	 String hql = "select name from People where id = 6";
	 Query query = session.createQuery(hql);
	 String name = (String) query.uniqueResult();
	 System.out.println(name);
	 session.close();
 }
}

7、占位符

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.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 Test11 {
 public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 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(people);
	 }
	 session.close();
 }
}

8、级联查询

package com.southwind.test;
import com.southwind.entity.Customer;
import com.southwind.entity.Orders;
import com.southwind.entity.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 Test11 {
  public static void main(String[] args) {
	 //创建 Configuration
	 Configuration configuration = new Configuration().configure("hibernate.xml");
	 //获取 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();
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值