您的位置:首页 > 其它

[Hibernate]七种关联关系配置文件和测试实例详解

2018-04-01 22:30 471 查看
用了一天整理下来。所有关系分为以下七种:
单向【1-1】
双向【1-1】
单向【1-N】
双向【1-N】
单向【N-1】
单向【N-N】
双向【N-N】

1单向【1-1】

基于外键的单向【1-1】
是【N-1】的特殊形式,要求【N】方唯一。
基于外键的单向1-1只需要在原有的<many-to-one>元素增加unique=true属性,用以表示N的一端必须唯一
===》将单向【N-1】变为基于外键的单向【1-1】关联关系。package OneToOneSingle;

public class User {
private Integer Userid;
private String username;
private String password;
private UserInfo userinfo;
public Integer getUserid() {
return Userid;
}
public void setUserid(Integer userid) {
Userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserInfo getUserinfo() {
return userinfo;
}
public void setUserinfo(UserInfo userinfo) {
this.userinfo = userinfo;
}

}
package OneToOneSingle;

public class UserInfo {
private Integer InfoId;
private String address;
private String mail;
public Integer getInfoId() {
return InfoId;
}
public void setInfoId(Integer infoId) {
InfoId = infoId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}

}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="OneToOneSingle.User" table="User">
<id name="Userid">
<generator class="native"></generator>
</id>
<property name="username" />
<property name="password"></property>

<many-to-one name="userinfo" class="OneToOneSingle.UserInfo"
column="info_id" unique="true" cascade="all" />
<!-- cascade为操作user对象时,同时联级保存 userinfo对象-->

</class>
</hibernate-mapping>

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="OneToOneSingle.UserInfo" table="userInfo">
<!-- 主键对应 -->
<id name="InfoId">
<generator class="native"></generator>
</id>
<property name="address" />
<property name="mail"></property>

</class>
</hibernate-mapping>

2双向【1-1】

基于主键的双向【1-1】
两个关联表使用相同的主键值,其中一个表的主键共享另外一个表的主键。
使用标签<one-to-one>
constrained放错位置会导致外键死锁。package OneToOneDouble;

public class Husband {
private Integer Id;
private String husbanName;
private Wife wife;
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getHusbanName() {
return husbanName;
}
public void setHusbanName(String husbanName) {
this.husbanName = husbanName;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}

}
package OneToOneDouble;

public class Wife {

private Integer Id;
private String wifeName;
private Husband husband;
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}

}

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="OneToOneDouble.Husband" table="husband">
<id name="Id">
<!-- 主键来源wife,也就是共享的主键 -->
<generator class="foreign">
<param name="property">wife</param>
</generator>
</id>
<property name="husbanName" />
<!-- constrained放错位置会导致外键死锁 -->
<one-to-one name="wife" class="OneToOneDouble.Wife"  constrained="true"/>

</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="OneToOneDouble.Wife" table="wife">
<id name="Id">
<generator class="native"></generator>
</id>
<property name="wifeName" />

<one-to-one name="husband" class="OneToOneDouble.Husband" ></one-to-one>

</class>
</hibernate-mapping>

3单向【1-N】

从N-1反过来,由Teacher对象维护多个Student对象的管理。
只需要在【1】方添加对【N】方Set集合类型属性为Student的哈希set集合。

但是【不需要!】在【N】方定义Teacher属性。
外键依然是属于【N】方的。
在持久化类中通过重写hashCode和equals方法来实现对持久化对象的比较,如果两个对象的标识符相等即对应数据库同一条记录,
那么Hibernate就会把两个对象看作同一个对象。package OneToManySingle;

public class Student {
private String studentName;
private Integer studentId;
private String studentSex;

public String getStudentName() {
return studentName;
}

public void setStudentName(String studentName) {
this.studentName = studentName;
}

public Integer getStudentId() {
return studentId;
}

public void setStudentId(Integer studentId) {
this.studentId = studentId;
}

public String getStudentSex() {
return studentSex;
}

public void setStudentSex(String studentSex) {
this.studentSex = studentSex;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((studentId == null) ? 0 : studentId.hashCode());
return result;
}

public Student() {
// TODO Auto-generated constructor stub
}

}
package OneToManySingle;

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

public class Teacher {
private Integer teacherId;
private String teacherName;
private Integer teacherAge;

private Set<Student> students = new HashSet<Student>();

public Integer getTeacherId() {
return teacherId;
}

public void setTeacherId(Integer teacherId) {
this.teacherId = teacherId;
}

public String getTeacherName() {
return teacherName;
}

public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}

public Integer getTeacherAge() {
return teacherAge;
}

public void setTeacherAge(Integer teacherAge) {
this.teacherAge = teacherAge;
}

public Set<Student> getStudents() {
return students;
}

public void setStudents(Set<Student> students) {
this.students = students;
}

}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- javabean与表的映射关系 -->
<hibernate-mapping>
<class name="OneToManySingle.Student" table="student">
<!-- 主键对应 -->
<id name="studentId">
<generator class="native"></generator>
</id>
<property name="studentName" />
<property name="studentSex"></property>

</class>
</hibernate-mapping>
<?xml version='1.0' encodin
4000
g='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- javabean与表的映射关系 -->
<hibernate-mapping>
<class name="OneToManySingle.Teacher" table="teacher">
<!-- 主键对应 -->
<id name="teacherId">
<generator class="native"></generator>
</id>
<property name="teacherName" />
<property name="teacherAge"></property>

<set name="students">
<key column="teache_id"></key><!-- 外键 -->
<one-to-many class="OneToManySingle.Student"/>
</set>

</class>
</hibernate-mapping>

4双向【1-N】

就是【单向1-N】和【单向N-1】的整合。
【N】方存在【1】方属性,【1】放存放【N】方的set集合。

在实际开发中经常使用。package OneToManyDouble;

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

/*与Linkman建立一对多关系.
* 一个客户可以有多个联系人
* linkman表的外键是cus_id;
* */

public class Customer {
private Integer cus_id;
private String cus_name;
private String cus_phone;

private Set<Linkman> linkmans = new HashSet<Linkman>();

public Set<Linkman> getLinkmans() {
return linkmans;
}

public void setLinkmans(Set<Linkman> linkmans) {
this.linkmans = linkmans;
}

public Integer getCus_id() {
return cus_id;
}

public void setCus_id(Integer cus_id) {
this.cus_id = cus_id;
}

public String getCus_name() {
return cus_name;
}

public void setCus_name(String cus_name) {
this.cus_name = cus_name;
}

public String getCus_phone() {
return cus_phone;
}

public void setCus_phone(String cus_phone) {
this.cus_phone = cus_phone;
}

}
package OneToManyDouble;

public class Linkman {
private Integer link_id;
private String link_name;
private String link_sex;

private Customer customer;

public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Integer getLink_id() {
return link_id;
}
public void setLink_id(Integer link_id) {
this.link_id = link_id;
}
public String getLink_name() {
return link_name;
}
public void setLink_name(String link_name) {
this.link_name = link_name;
}
public String getLink_sex() {
return link_sex;
}
public void setLink_sex(String link_sex) {
this.link_sex = link_sex;
}

}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- javabean与表的映射关系 -->
<hibernate-mapping>
<class name="OneToManyDouble.Customer" table="customer">
<!-- 主键对应 -->
<id name="cus_id">
<generator class="native"></generator>
</id>
<property name="cus_name" />
<property name="cus_phone"></property>

<!-- 设置与多方的关系 -->
<set name="linkmans">
<key column="link_cus_id"></key>
<one-to-many class="OneToManyDouble.Linkman" />
</set>

</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="OneToManyDouble.Linkman" table="linkman">
<!-- 主键对应 -->
<id name="link_id">
<generator class="native"></generator>
</id>
<property name="link_name" />
<property name="link_sex"></property>
<!-- 建立多方 和 指定外键 -->
<many-to-one name="customer" class="OneToManyDouble.Customer"
column="link_cus_id" />
</class>
</hibernate-mapping>

5单向【N-1】

单向的【N-1】关联只能从【N】的一端访问【1】的一端。
一个买家对应多个订单。
只需要在Order中定义一个Buyer类型的属性,而不需要在Buyer中定义存放Order对象的集合属性。
注意mysql里order属于关键字,最好改名。
package ManyToOneSingle;

public class Buyer {
private Integer buyerId;
private String buyerName;
private String password;

public Buyer() {

}

public Integer getBuyerId() {
return buyerId;
}

public void setBuyerId(Integer buyerId) {
this.buyerId = buyerId;
}

public String getBuyerName() {
return buyerName;
}

public void setBuyerName(String buyerName) {
this.buyerName = buyerName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

}
package ManyToOneSingle;

public class Order {

private Integer orderId;
private String orderNo;
private Buyer buyer;

public Integer getOrderId() {
return orderId;
}

public void setOrderId(Integer orderId) {
this.orderId = orderId;
}

public String getOrderNo() {
return orderNo;
}

public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}

public Buyer getBuyer() {
return buyer;
}

public void setBuyer(Buyer buyer) {
this.buyer = buyer;
}

}

6单向【N-N】

每个N-N的实质都存在一个中间表。
只有主动方对象关联被动方对象,而被动方对象没有关联主动方对象。
此例子中Form是主动发,product是被动方。
一个Form对象可以包含一个或者多个不同的Product对象,
而同一个Product对象可以被0个或者多个不同的Order对象所包含。
主动方的配置中:
set的table属性指明了两个对象间连接表的表名。
key用于连接表中这只关于form【主动方】的外键和外键名。
manytomany中的column属性用于设置连接表引用自【被动方】product的外键和外键名。
package ManyToManySingle;

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

public class Form {
private Integer formId;
private String formName;
private Set<Product> products = new HashSet<Product>();

public Integer getFormId() {
return formId;
}

public void setFormId(Integer formId) {
this.formId = formId;
}

public String getFormName() {
return formName;
}

public void setFormName(String formName) {
this.formName = formName;
}

public Set<Product> getProducts() {
return products;
}

public void setProducts(Set<Product> products) {
this.products = products;
}

}
package ManyToManySingle;

public class Product {
private Integer productId;
private String productName;
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}

}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="ManyToManySingle.Form" table="form">
<id name="formId">
<generator class="native"></generator>
</id>
<property name="formName" />

<!-- table表示中间表 -->
<set name="products" table="formitem">
<key column="form_id"/>
<!-- 设置了连接表中引用Product的外键名为product_id -->
<many-to-many class="ManyToManySingle.Product" column="product_id"></many-to-many>
</set>

</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="ManyToManySingle.Product" table="product">
<id name="productId">
<generator class="native"></generator>
</id>
<property name="productName" />

</class>
</hibernate-mapping>

7双向【N-N】

主动方和被动方相互关联。
两方都有set集合。
要任选一方放弃外键维护防止冲突。
package ManyToManyDouble;

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

public class People {
private Integer peopleId;
private String peopleName;
private Set<Role> roles = new HashSet<Role>();//这里一定要new出来。
public Integer getPeopleId() {
return peopleId;
}
public void setPeopleId(Integer peopleId) {
this.peopleId = peopleId;
}
public String getPeopleName() {
return peopleName;
}
public void setPeopleName(String peopleName) {
this.peopleName = peopleName;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}

}

package ManyToManyDouble;

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

public class Role {
private Integer roleId;
private String roleName;
private Set<People> peoples = new HashSet<People>();

public Integer getRoleId() {
return roleId;
}

public void setRoleId(Integer roleId) {
this.roleId = roleId;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public Set<People> getPeoples() {
return peoples;
}

public void setPeoples(Set<People> peoples) {
this.peoples = peoples;
}

}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="ManyToManyDouble.People" table="People">
<id name="peopleId">
<generator class="native"></generator>
</id>
<property name="peopleName" />

<set name="roles" table="roleitem" inverse="true">
<key column="people_id" />
<many-to-many class="ManyToManyDouble.Role" column="role_id" />
</set>

</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="ManyToManyDouble.Role" table="Role">
<id name="roleId">
<generator class="native"></generator>
</id>
<property name="roleName" />

<set name="peoples" table="roleitem">
<key column="role_id" />
<many-to-many class="ManyToManyDouble.People" column="people_id" />
</set>

</class>
</hibernate-mapping>

所有测试用例

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yiki.util.Utils;

import OneToOneDouble.Husband;
import OneToOneDouble.Wife;

public class Double_1_1 {

public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();
Husband husband = new Husband();
Wife wife = new Wife();

husband.setHusbanName("o");
wife.setWifeName("w");

husband.setWife(wife);
wife.setHusband(husband);

session.save(wife);
session.save(husband);

tr.commit();

session.close();

}

}
package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yiki.util.Utils;

import OneToManyDouble.Customer;
import OneToManyDouble.Linkman;

public class Double_1_N {

public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();
Customer c1 = new Customer();
Linkman link1 = new Linkman();
link1.setLink_name("联系人1");
Linkman link2 = new Linkman();
link2.setLink_name("联系人2");
c1.setCus_name("cus1");
c1.setCus_phone("3333333");

//双向关联
c1.getLinkmans().add(link1);
c1.getLinkmans().add(link2);
link1.setCustomer(c1);
link2.setCustomer(c1);

session.save(c1);
session.save(link1);
session.save(link2);

tr.commit();

session.close();

}

}

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.yiki.util.Utils;

import ManyToManyDouble.People;
import ManyToManyDouble.Role;

public class Double_N_N {

public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();

People p1 = new People();
p1.setPeopleName("tiffany");
People p2 = new People();
p2.setPeopleName("yiki");
People p3 = new People();
p3.setPeopleName("penny");

Role r1 = new Role();
r1.setRoleName("engineer");
Role r2 = new Role();
r2.setRoleName("girl");
Role r3 = new Role();
r3.setRoleName("singer");

p1.getRoles().add(r2);
r2.getPeoples().add(p1);
r2.getPeoples().add(p1);

p2.getRoles().add(r3);
r3.getPeoples().add(p2);

p3.getRoles().add(r2);
r2.getPeoples().add(p3);

session.save(p1);
session.save(p2);
session.save(p3);
session.save(r1);
session.save(r2);
session.save(r3);
tr.commit();
session.close();
}

}

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yiki.util.Utils;

import OneToOneSingle.User;
import OneToOneSingle.UserInfo;

public class single_1_1 {
public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();

User user = new User();
UserInfo info = new UserInfo();
info.setAddress("Chongqin");
info.setMail("2222@ffff.com");
user.setUsername("tiffany");
user.setPassword("22222");
user.setUserinfo(info);

session.save(user);
session.save(info);

tr.commit();
session.close();

}

}
package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.yiki.util.Utils;
import OneToManySingle.Student;
import OneToManySingle.Teacher;

public class Single_1_N {

public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();

Teacher teacher = new Teacher();
Student s1 = new Student();
Student s2 = new Student();

teacher.setTeacherName("老师1");
teacher.setTeacherAge(34);
s1.setStudentName("yi");
s1.setStudentSex("male");
s2.setStudentName("ki");
s2.setStudentSex("female");

teacher.getStudents().add(s1);
teacher.getStudents().add(s2);

session.save(s1);
session.save(s2);
session.save(teacher);
tr.commit();
session.close();
}

}

package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.yiki.util.Utils;
import ManyToOneSingle.Buyer;
import ManyToOneSingle.Order;
public class Single_N_1 {

public static void main(String[] args) {
addBuyerAndOrder();

}
public static void addBuyerAndOrder(){
Buyer buyer = new Buyer();
buyer.setBuyerName("tiffany");
buyer.setPassword("123344");
addBuyer(buyer);

Order order = new Order();
order.setBuyer(buyer);
order.setOrderNo("2");
addOrder(order);

}

private static void addOrder(Order order) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();
session.save(order);
tr.commit();
session.close();

}
private static void addBuyer(Buyer buyer) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();
session.save(buyer);
tr.commit();
session.close();

b05c

}

}
package Test;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.yiki.util.Utils;
import ManyToManySingle.Form;
import ManyToManySingle.Product;
public class Single_N_N {

public static void main(String[] args) {
Session session = Utils.openSession();
Transaction tr = session.beginTransaction();

Product p1 = new Product();
Product p2 = new Product();

Form f1 = new Form();
Form f2 = new Form();

p1.setProductName("产品1");
p2.setProductName("产品2");
f1.setFormName("订单1");
f2.setFormName("订单2");

f1.getProducts().add(p1);
f1.getProducts().add(p2);
f2.getProducts().add(p1);

session.save(p1);
session.save(p2);
session.save(f1);
session.save(f2);
tr.commit();
session.close();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: