title: hibernate一对多,多对一注解开发

date: 2018-2-10 9:37:43

categories: Hibernate

tags: Hibernate


xl_echo编辑整理

hibernate一对多,多对一注解开发

Java测试代码

package com.echo.hibernate.Test;

import java.util.Date;

import org.hibernate.Session;
import org.junit.Test;

import com.echo.hibernate.domain.Book;
import com.echo.hibernate.domain.Customer;
import com.echo.hibernate.domain.Orders;
import com.echo.hibernate.domain.Person;
import com.echo.hibernate.utils.HibernateUtils;

public class HiberanteTest {

@Test
/**
* 级联注解开发,测试保存客户时,能不能保存订单信息,并生成外键联系
* 这是一个对多的操作,所以要保存客户信息,就需要在客户一方设置级联,链接客户。设置级联之后即可保存客户的同时保存订单信息
* 级联操作配置文件
* OneToMany(targetEntity=Orders.class,mappedBy="c")
* Cascade(CascadeType.SAVE_UPDATE)//cascade最好使用hibernate中的
* private Set<Orders> orders = new HashSet<>();
*
* 一下程序运行会产生订单表没有外键,原因是订单没有set客户,使用下面一段方法的代码即可
*/
public void saveCustomer(){
Session session = HibernateUtils.getSession();
session.beginTransaction();

Customer c = new Customer();
c.setName("echo");

Orders o = new Orders();
o.setAddress("北京");
o.setMoney(1000.0);

Orders o1 = new Orders();
o1.setAddress("深圳");
o1.setMoney(1200.0);

c.getOrders().add(o);
c.getOrders().add(o1);

session.save(c);

session.beginTransaction().commit();
session.close();
}

@Test
public void saveCustomer1(){
Session session = HibernateUtils.getSession();
session.beginTransaction();

Customer c = new Customer();
c.setName("echo");

Orders o = new Orders();
o.setAddress("北京");
o.setMoney(1000.0);

Orders o1 = new Orders();
o1.setAddress("深圳");
o1.setMoney(1200.0);

//维护外键
o.setC(c);
o1.setC(c);

c.getOrders().add(o);
c.getOrders().add(o1);

session.save(c);

session.beginTransaction().commit();
session.close();
}

@Test
/**
* 找到客户信息,并且通过客户信息,直接删除订单,并且数据库同步
* 需要配合配置文件的orphanRemoval=true
* OneToMany(targetEntity=Orders.class,mappedBy="c",orphanRemoval=true)
Cascade(CascadeType.SAVE_UPDATE)
private Set<Orders> orders = new HashSet<>();
*/
public void deleteOrphan(){
Session session = HibernateUtils.getSession();
session.beginTransaction();

Customer c = session.get(Customer.class, 1);

Orders o = session.get(Orders.class, 2);
c.getOrders().remove(o);

session.beginTransaction().commit();
session.close();
}
}

实体类的注解配置

package com.echo.hibernate.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
/**
* 客户类,注解开发一对多
* @author XL-sorry
* catalog可以省略,默认直接从核心配置文件中加载
*/
@Entity
@Table(name="t_customer",catalog="myxlsorry")
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;//主键
private String name;//客户姓名

/**
* 在关系属性上使用OnetoMany,代表的就是该类对另外一个类是一对多的映射关系
* targetEntity=Orders.class声明多的那个类是哪一个
* mappedBy="c",在orders中的属性,定义属于那个客户就是c,所以配置它,代表着由orders维护外键
*/
@OneToMany(targetEntity=Orders.class,mappedBy="c",orphanRemoval=true)
@Cascade(CascadeType.SAVE_UPDATE)
private Set<Orders> orders = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Orders> getOrders() {
return orders;
}
public void setOrders(Set<Orders> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", orders=" + orders + "]";
}
}


package com.echo.hibernate.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

/**
* 订单类,注解开发多对一
* @author XL-sorry
*
*/
@Entity
@Table(name="t_orders",catalog="myxlsorry")
public class Orders {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;//订单编号
private String address;//收货地址
private Double money;//订单金额

/**
* 指定关联哪一个类
*/
@ManyToOne(targetEntity=Customer.class)
//指定级联
// @Cascade(CascadeType.SAVE_UPDATE)
//生成外键的名字叫什么
@JoinColumn(name = "c_customer_id")
private Customer c;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public Customer getC() {
return c;
}
public void setC(Customer c) {
this.c = c;
}
@Override
public String toString() {
return "Orders [id=" + id + ", address=" + address + ", money=" + money + ", c=" + c + "]";
}
}

核心配置文件

<?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:///myxlsorry</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">20263800mq</property>
<!-- 告知hibernate我们使用的是哪种数据库 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- 设置数据库提交方式,默认false,设置为true就不用开启事务也能插入数据。注意:开启之后没法回滚数据? -->
<property name="hibernate.connection.autocommit">false</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>


<!-- 可以将操作数据库发送的sql显示出来 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化生sql 作用:让sql可读性更高,但是会提高控制台的输出信息量 -->
<property name="hibernate.format_sql">true</property>



<!-- 设置连接提供者,告知hibernate我们需要使用那个连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- c3p0连接池配置 -->
<property name="hibernate.c3p0.max_size">20</property><!-- 最大连接数 -->
<property name="hibernate.c3p0.min_size">5</property><!-- 最小连接数 -->
<property name="hibernate.c3p0.timeout">120</property><!-- 超时 -->
<property name="hibernate.c3p0.idle_test_period">3000</property><!-- 空闲链接时间 -->



<!-- 配置hibernate的映射文件所在位置 -->
<!-- <mapping resource="com/echo/hibernate/hibernatedomain/Person.hbm.xml"/> -->

<!-- 使用注解开发mapping后面直接跟class即可,class后面跟全类名 -->
<mapping class="com.echo.hibernate.domain.Customer" />
<mapping class="com.echo.hibernate.domain.Orders"/>

</session-factory>

</hibernate-configuration>