一、一对多关系:插入:
“一”的一方为主表,“多”的一方为副表,主表关联副表,应该在主表中加入副表对象作为属性。
根据顾客ID插入顾客信息 (一) ,同时将顾客名下所有订单插入 (多) 。
实现思路:
- 数据库关系:
- 创建顾客实体类,存储顾客信息:
注意我们在顾客类中用List集合封装了顾客名下的订单信息。
package org.example.Entity;
import java.util.List;
public class CustomerEntity {
private int id;
private String name;
private Integer age;
//在顾客表中加入订单集合
private List<OrdersEntity> orders;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public List<OrdersEntity> getOrders() {
return orders;
}
public void setOrders(List<OrdersEntity> orders) {
this.orders = orders;
}
}
- 创建订单类,存储订单信息:
订单类中应该有顾客类,用来指明该订单属于哪个顾客。
package org.example.Entity;
public class OrdersEntity {
private int id;
private String orderNumber;
private Double orderPrice;
//订单中有外键customer_id,所以需要添加顾客类
private CustomerEntity customer;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
public Double getOrderPrice() {
return orderPrice;
}
public void setOrderPrice(Double orderPrice) {
this.orderPrice = orderPrice;
}
public CustomerEntity getCustomer() {
return customer;
}
public void setCustomer(CustomerEntity customer) {
this.customer = customer;
}
}
- 创建顾客关系类的映射文件:
<?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="org.example.Entity.CustomerEntity" table="customer" schema="ssm">
<!--主键-->
<id name="id" column="id" type="java.lang.Integer"/>
<!--非主键-->
<property name="aid" column="aid" type="java.lang.Integer"/>
<property name="cid" column="cid" type="java.lang.Integer"/>
<!--配置集合属性orders 和表名orders-->
<set name="orders" table="orders">
<!--该属性对应的外键-->
<key column="customer_id"/>
<!--该外键所属的实体类-->
<one-to-many class="org.example.Entity.OrdersEntity"/>
</set>
</class>
</hibernate-mapping>
- 创建订单实体类的映射文件:
<?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="org.example.Entity.OrdersEntity" table="orders" schema="ssm">
<!--主键,type接封装类,class接自定义类-->
<id name="id" column="id" type="java.lang.Integer"/>
<!--非主键-->
<property name="orderNumber" column="orderNumber" type="java.lang.String"/>
<property name="orderPrice" column="orderPrice" type="java.lang.Double"/>
<!--外键,class是外键对应的实体类-->
<many-to-one name="customer" column="customer_id" class="org.example.Entity.CustomerEntity"/>
</class>
</hibernate-mapping>
- 测试类:
注意要建立关联关系。
package org.example;
import org.example.Entity.CustomerEntity;
import org.example.Entity.OrdersEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class AppTest{
@Test
public void test(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//创建顾客类对象并给相应属性赋值
CustomerEntity customer = new CustomerEntity();
customer.setId(4);
customer.setName("44");
customer.setAge(18);
//创建订单类对象并给相应属性赋值
OrdersEntity order = new OrdersEntity();
order.setId(4);
order.setOrderNumber("4");
order.setOrderPrice(4.0);
//建立关联关系,若不建立关联关系order表的数据为空
order.setCustomer(customer);
//保存,所有对象都要保存
session.save(customer);
session.save(order);
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
}
- 运行结果:
二、多对多关系:插入:
多对多关系通过一个中间表来维护。
实现思路:
- 数据库关系:
- 创建Accounts实体类:
package org.example.Entity;
import java.util.Set;
public class AccountsEntity {
private int aid;
private String aname;
private Set<CoursesEntity> courses;
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public Set<CoursesEntity> getCourses() {
return courses;
}
public void setCourses(Set<CoursesEntity> courses) {
this.courses = courses;
}
}
- 创建Courses实体类:
package org.example.Entity;
import java.util.Set;
public class CoursesEntity {
private int cid;
private String cname;
private Set<AccountsEntity> accounts;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Set<AccountsEntity> getAccounts() {
return accounts;
}
public void setAccounts(Set<AccountsEntity> accounts) {
this.accounts = accounts;
}
}
- 创建中间表实体类:
package org.example.Entity;
public class AccountCourseEntity {
private int id;
private Integer aid;
private Integer cid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
}
- 创建Accounts实体类映射文件:
<?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="org.example.Entity.AccountsEntity" table="accounts" schema="ssm">
<id name="aid" column="aid" type="java.lang.Integer"/>
<property name="aname" column="aname" type="java.lang.String"/>
<set name="courses" table="account_course">
<key column="aid"/>
<!--column 属性与中间表的外键字段名对应,这里配的是CoursesEntity在中间表中对应的外键-->
<many-to-many class="org.example.Entity.CoursesEntity" column="cid"/>
</set>
</class>
</hibernate-mapping>
- 创建Courses实体类映射文件:
<?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="org.example.Entity.CoursesEntity" table="courses" schema="ssm">
<id name="cid" column="cid" type="java.lang.Integer"/>
<property name="cname" column="cname" type="java.lang.String"/>
<set name="accounts" table="account_course">
<key column="cid"/>
<!--column 属性与中间表的外键字段名对应,这里配的是AccountsEntity在中间表中对应的外键-->
<many-to-many class="org.example.Entity.AccountsEntity" column="aid"/>
</set>
</class>
</hibernate-mapping>
- 创建中间表实体类映射文件:
<?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="org.example.Entity.AccountCourseEntity" table="account_course" schema="ssm">
<id name="id" column="id" type="java.lang.Integer"/>
<property name="aid" column="aid" type="java.lang.Integer"/>
<property name="cid" column="cid" type="java.lang.Integer"/>
</class>
</hibernate-mapping>
- 测试类:
package org.example;
import org.example.Entity.AccountsEntity;
import org.example.Entity.CoursesEntity;
import org.example.Entity.CustomerEntity;
import org.example.Entity.OrdersEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
public class AppTest{
@Test
public void test2(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//创建Courses类对象并给相应属性赋值
CoursesEntity course = new CoursesEntity();
course.setCname("JAVA");
//创建Accounts类对象并给相应属性赋值
AccountsEntity account = new AccountsEntity();
account.setAname("张三");
//建立关联关系
Set<CoursesEntity> courses = new HashSet<>();
courses.add(course);
account.setCourses(courses);
//保存,所有对象都要保存
session.save(course);
session.save(account);
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
}
- 运行结果:
三、一对多关系:查询+懒加载:
懒加载条件下查询顾客信息和订单信息。
什么是懒加载?点击查看
具体配置同(一)。
需要在customer类的映射文件中为order的set集合配置 lazy="true"
,设置order的懒加载,这样在查询customer信息时会根据需求判断是否查询order。
需要在order类的映射文件中为customer的many-to-one设置lazy=proxy"
,设置customer的懒加载,这样在查询order信息时会根据需求判断是否查询customer。
- 测试类1:
@Test
public void test3(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//查询主键为4的顾客信息
CustomerEntity customer = session.get(CustomerEntity.class,4);
System.out.println(customer);
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
- 运行结果1:
因为会调用toString方法,toString会打印学生信息和订单信息,所以有两条SQL语句。
如果只打印customer.name(),则只会有第一条SQL,这就是懒加载。
- 测试类2:
@Test
public void test4(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//查询主键为4的订单信息
OrdersEntity orders = session.get(OrdersEntity.class,4);
System.out.println(orders);
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
- 运行结果2:
如果只打印order.name(),则只会有第一条SQL,这就是懒加载。
四、多对多关系:查询+懒加载:
具体配置同(二)。
需要在account类的映射文件中为account_course的set集合配置 lazy="true"
,设置account_course的懒加载,这样在查询account信息时会根据需求判断是否查询course。
需要在course类的映射文件中为account_course的set集合设置lazy="true"
,设置account_course的懒加载,这样在查询course信息时会根据需求判断是否查询account。
- 测试类1:
@Test
public void test5(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//查询主键为1的课程信息
CoursesEntity course = session.get(CoursesEntity.class,1);
System.out.println(course.toString());
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
- 测试结果1:
- 测试类2:
@Test
public void test5(){
//创建SessionFactory,从根路径下获取核心配置文件
SessionFactory factory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
//创建session
Session session = factory.openSession();
//创建事务
Transaction transaction = session.beginTransaction();
//查询主键为1的课程信息
AccountsEntity account = session.get(AccountsEntity.class,1);
System.out.println(account.toString());
//提交事务
transaction.commit();
//关闭SessionFactory
factory.close();
}
- 测试结果2: