首先是两个Bean类,Customer用户类,Order订单类,其中Order订单中添加了外键,引用Customer的字段
Customer类
//用户
public class Customer {
//用户ID
private Integer customerId;
//用户名
private String customerName;
/**
* 1:声明集合类型时,需使用接口类型,因为Hibernate在获取
* 集合类型时,返回的是Hibernate内置的集合类型,而不是Java SE一个标准的
* 集合实现
* 2:需要把集合初始化,防止空指针异常
*/
private Set<Order> orders = new HashSet<Order>();
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public Customer() {
super();
}
public Customer(Integer customerId, String customerName) {
super();
this.customerId = customerId;
this.customerName = customerName;
}
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
@Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName="
+ customerName + "]";
}
}
Order类
//订单类
public class Order {
//订单ID
private Integer orderId;
//订单名
private String orderName;
//外键,引用Customer
private Customer customer;
public Order() {
super();
}
public Order(Integer orderId, String orderName, Customer customer) {
super();
this.orderId = orderId;
this.orderName = orderName;
this.customer = customer;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
@Override
public String toString() {
return "Order [orderId=" + orderId + ", orderName=" + orderName
+ ", customer=" + customer + "]";
}
}
然后是XML配置文件
Customer.hbm.xml
<?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="entity2">
<class name="Customer" table="customer">
<!-- id:表中的主键,name:类中的属性名 -->
<id name="customerId" type="java.lang.Integer">
<!-- name:表中的序列名 -->
<column name="customer_id"/>
<!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
<generator class="native"/>
</id>
<!-- property一般字段 -->
<property name="customerName" type="java.lang.String">
<column name="customer_name"/>
</property>
<!--
table:与Order的表名对应
key的column:与Order的外键字段名对应
inverse:true,Customer放弃维护Order的外键引用
可以减少UPDATE语句
-->
<set name="orders" table="orders" inverse="true">
<key column="customer_id"></key>
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
Order.hbm.xml
<?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="entity2">
<class name="Order" table="orders">
<!-- id:表中的主键,name:类中的属性名 -->
<id name="orderId" type="java.lang.Integer">
<!-- name:表中的序列名 -->
<column name="order_id"/>
<!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
<generator class="native"/>
</id>
<!-- property一般字段 -->
<property name="orderName" type="java.lang.String">
<column name="order_name"/>
</property>
<!-- 映射多对一的关联关系 -->
<many-to-one name="customer" class="Customer" column="customer_id"></many-to-one>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<?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">1234</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<!-- 配置Hibernate的基本信息 -->
<!-- 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="hbm2ddl.auto">update</property>
<!-- 指定 关联的关系/映射 文件,引入Bean的xml文件 -->
<!-- 注:不是打. 用/ -->
<!-- <mapping resource="entity1/Customer.hbm.xml"/>
<mapping resource="entity1/Order.hbm.xml"/> -->
<mapping resource="entity2/Customer.hbm.xml"/>
<mapping resource="entity2/Order.hbm.xml"/>
</session-factory>
</hibernate-configuration>
HibernateTest测试类
public class HibernateTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init() {
// 1.创建一个SessionFactory 对象
sessionFactory = null;
// 1.创建Configuration对象:对应Hibernate的基本配置信息和对象关系映射信息
// configure();读取配置文件,无参默认读取hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
/**
* new Configuration 的几个方法
*
* 读取的是hibernate.properties配置文件
* 1:Configuration configuration = new Configuration();
*
* 读取配置文件,无参默认读取hibernate.cfg.xml
* 2:Configuration configuration = new Configuration().configure();
*
* 读取配置文件,读取指定xml,传入一个File
* 3:Configuration configuration = new Configuration().configure(file);
*/
// 2.创建一个ServiceRegistry对象
// Hibernate 的任何配置和服务都需要在该对象中注册后才有效
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
// 3.创建一个SessionFactory
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2.创建一个Session对象
session = sessionFactory.openSession();
// 3.开启事物
transaction = session.beginTransaction();
}
@After
public void distroy() {
// 5.提交事物
transaction.commit();
// 6.关闭Session对象
session.close();
// 7.关闭SessionFactory对象
sessionFactory.close();
}
@Test
public void test1(){
Customer customer = new Customer();
customer.setCustomerName("1");
Order order1 = new Order();
Order order2 = new Order();
order1.setOrderName("1");
order2.setOrderName("2");
//设置外键关系
order1.setCustomer(customer);
order2.setCustomer(customer);
//在customer中添加引用该外键的Order订单
customer.getOrders().add(order1);
customer.getOrders().add(order2);
/**
* 先插入Customer,在插入Order
* 3条INSERT,2条UPDATE
* 因为Customer和Order都维护关联关系,所以
* Order插入后,Customer会更新(UPDATE)Order的外键
*
* 可以在Customer的配置文件Set中指定节点inverse="true"
* 放弃维护Order的外键引用,会只有3条INSERT
*/
session.save(customer);
session.save(order1);
session.save(order2);
/**
* 先插入Order,在插入Customer
* 3条INSERT,4条UPDATE
* 因为Customer和Order都维护关联关系
*
* 可以在Customer的配置文件Set中指定节点inverse="true"
* 放弃维护Order的外键引用,会只有3条INSERT,2条UPDATE
*/
//Order负责更新order1记录
session.save(order1);
//Order负责更新order2记录
session.save(order2);
//Customer负责更新order1,order2记录
session.save(customer);
}
//查
@Test
public void test2(){
/**
* 对customer里的orders List集合使用延迟加载
* 如果不使用orders的List集合,则不发生SQL查询Order语句
*/
Customer customer = (Customer) session.get(Customer.class,1);
/**
* 返回的集合为Hibernate内置的集合类型
* 该类型具有延迟加载和存放代理对象的功能
*/
Set<Order> orders = customer.getOrders();
}
//查
@Test
public void test3(){
Customer customer = (Customer) session.get(Customer.class,1);
/**
* 可能会抛出LazyInitializationException异常
* 如果customer还没有使用orders集合
* 且session.close()
* 则抛异常
*/
session.close();
System.out.println(customer.getOrders().size());
}
//改
@Test
public void test4(){
//可以利用customer里的orders Set集合更改order
Customer customer = (Customer) session.get(Customer.class,1);
//但是更改的哪个order是不确定的,因为Set集合特性:无序
customer.getOrders().iterator().next().setOrderName("GGG");
}
//删
@Test
public void test5(){
/**
* 在不设置级联关系的情况下,并且被引用的外键(Customer用户表)
* 有被Order(订单表)引用外键,不能直接删除customer
*/
Customer customer = (Customer) session.get(Customer.class,1);
session.delete(customer);
}
}