备注:本文有参考hibernate多对多关系配置--增删改查
==========================================================
==========================================================
1.项目结构:
========================
2.pom.xml
4.0.0
com.lin
Hibernate_ManyToMany
0.0.1-SNAPSHOT
org.hibernate
hibernate-core
3.6.10.Final
org.hibernate
hibernate-entitymanager
3.6.10.Final
mysql
mysql-connector-java
5.1.41
org.slf4j
slf4j-nop
1.7.25
test
javax.servlet
jstl
1.2
javax.servlet
javax.servlet-api
4.0.1
provided
junit
junit-dep
4.10
test
========================
3.实体类和映射文件
Person.java
package com.lin.domain;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* 人 实体类
* */
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Long personId;
private String personName;
private String password;
//一个人可以有多个地址,一个地址可以对应多个人。所以 人跟地址 是多对多的关联关系。
private Set addresss = new HashSet(0);
public Person() {
super();
}
public Person(Long personId, String personName, String password) {
super();
this.personId = personId;
this.personName = personName;
this.password = password;
}
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set getAddresss() {
return addresss;
}
public void setAddresss(Set addresss) {
this.addresss = addresss;
}
@Override
public String toString() {
return "Person [personId=" + personId + ", personName=" + personName
+ ", password=" + password + "]";
}
}
Person.hbm.xml
Address.java
package com.lin.domain;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Address implements Serializable{
private static final long serialVersionUID = 1L;
private Long addressId;
private String addressInfo;
//一个地址可以对应多个人,一个人可以有多个地址。所以 地址跟人 是多对多的关联关系。
private Set persons = new HashSet(0);
public Address() {
super();
}
public Address(Long addressId, String addressInfo) {
super();
this.addressId = addressId;
this.addressInfo = addressInfo;
}
public Long getAddressId() {
return addressId;
}
public void setAddressId(Long addressId) {
this.addressId = addressId;
}
public String getAddressInfo() {
return addressInfo;
}
public void setAddressInfo(String addressInfo) {
this.addressInfo = addressInfo;
}
public Set getPersons() {
return persons;
}
public void setPersons(Set persons) {
this.persons = persons;
}
@Override
public String toString() {
return "Address [addressId=" + addressId + ", addressInfo="
+ addressInfo + "]";
}
}
Address.hbm.xml
========================
4.Hibernate配置文件hibernate.cfg.xml
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/hibernate
root
000000
1
org.hibernate.dialect.MySQLDialect
update
true
========================
5.Hibernate工具类
package com.lin.utils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Configuration configuration;
//创建线程局部变量threadLocal,用来保存Hibernate的Session
private static final ThreadLocal threadLocal = new ThreadLocal();
//使用静态代码块初始化Hibernate
static{
try{
//如果不指定hibernate的配置文件位置,那么它会默认到classpath路径下查找名为hibernate.cfg.xml的文件
Configuration cfg = new Configuration().configure("/hibernate/hibernate.cfg.xml");
//创建SessionFactory
sessionFactory = cfg.buildSessionFactory();
}catch(Throwable ex){
throw new ExceptionInInitializerError(ex);
}
}
//获得SessionFactory
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
//获得ThreadLocal对象管理的Session实例
public static Session getSession() throws HibernateException {
Session session = (Session)threadLocal.get();
if(session == null || session.isOpen()){
if(sessionFactory == null){
rebuildSessionFactory();
}
//通过SessionFactory对象创建Session对象
session = (sessionFactory != null)?sessionFactory.openSession():null;
//将新打开的Session实例保存到线程局部变量threadLocal中
threadLocal.set(session);
}
return session;
}
//关闭Session实例
public static void closeSession() throws HibernateException {
//从线程局部变量threadLocal中获取之前存入的Session实例
Session session = (Session)threadLocal.get();
threadLocal.set(null);
if(session != null){
session.close();
}
}
//重建SessionFactory
public static void rebuildSessionFactory() {
try{
configuration.configure("/hibernate/hibernate.cfg.xml");
sessionFactory = configuration.buildSessionFactory();
}catch(Exception e){
System.out.println("Error Creating SessionFactory ");
e.printStackTrace();
}
}
//关闭缓存和连接池
public static void shutdown(){
getSessionFactory().close();
}
public static void main(String[] args){
HibernateUtil.getSession();
}
}
========================
6.测试类
①保存操作
/**
* 保存操作
* */
@Test
public void saveTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person1 = new Person();
person1.setPersonName("林1");
person1.setPassword("111111");
Person person2 = new Person();
person2.setPersonName("林2");
person2.setPassword("222222");
Address address1 = new Address();
address1.setAddressInfo("地址1");
Address address2 = new Address();
address2.setAddressInfo("地址2");
Address address3 = new Address();
address3.setAddressInfo("地址3");
//注意,这里是双向关联,所以人要添加地址,地址也要关联人
person1.getAddresss().add(address1);
person1.getAddresss().add(address2);
person2.getAddresss().add(address2);
person2.getAddresss().add(address3);
address1.getPersons().add(person1);
address2.getPersons().add(person1);
address2.getPersons().add(person2);
address3.getPersons().add(person2);
//地址或人,谁先保存都可以
session.save(address1);
session.save(address2);
session.save(address3);
session.save(person1);
session.save(person2);
tx.commit();
session.close();
}
测试结果:
②CRUD测试操作
package com.lin.test;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.lin.domain.Address;
import com.lin.domain.Person;
import com.lin.utils.HibernateUtil;
/**
* 多对多关联关系的CRUD操作
* */
public class HibernateManyToManyTest {
/**
* 保存操作。
* */
@Test
public void saveTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person1 = new Person();
person1.setPersonName("林1");
person1.setPassword("111111");
Person person2 = new Person();
person2.setPersonName("林2");
person2.setPassword("222222");
Address address1 = new Address();
address1.setAddressInfo("地址1");
Address address2 = new Address();
address2.setAddressInfo("地址2");
Address address3 = new Address();
address3.setAddressInfo("地址3");
//注意,这里是双向关联,所以人要添加地址,地址也要关联人
person1.getAddresss().add(address1);
person1.getAddresss().add(address2);
person2.getAddresss().add(address2);
person2.getAddresss().add(address3);
address1.getPersons().add(person1);
address2.getPersons().add(person1);
address2.getPersons().add(person2);
address3.getPersons().add(person2);
//地址或人,谁先保存都可以
session.save(address1);
session.save(address2);
session.save(address3);
session.save(person1);
session.save(person2);
tx.commit();
session.close();
}
/**
* 删除操作 。
* */
@Test
public void deleteTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person = (Person) session.get(Person.class, 1L);
//如果有关联关系,那么需先将关联关系删掉才行
Set addresss = person.getAddresss();
for(Address address: addresss){
address.getPersons().remove(person);
}
session.delete(person);
tx.commit();
session.close();
}
/**
* 更新操作。
* 更新本张表。
* */
@Test
public void updateTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person = (Person) session.get(Person.class, 2L);
person.setPersonName("小林111");
session.update(person);
tx.commit();
session.close();
}
/**
* 更新操作。
* 更新关联表。
* */
@Test
public void updateTest2(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person = (Person) session.get(Person.class, 2L);
//下面的这个地址跟这个人是没有关联关系的,但是我执行更新操作后还是可以正常更新地址数据
// Address address = (Address) session.get(Address.class, 1L);
// address.setAddressInfo("泉州111");
Address address = (Address) session.get(Address.class, 2L);
address.setAddressInfo("泉州222");
person.getAddresss().add(address);
session.update(person);
tx.commit();
session.close();
}
/**
* 查询操作。
* */
@Test
public void selectTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Person person = (Person) session.get(Person.class, 2L);
System.out.println(person);
Set addresss = person.getAddresss();
System.out.println(addresss);
tx.commit();
session.close();
}
}
总结:从双向的一对多,到双向的一对一、再到双向的多对多。最关键的就是实体类与数据表的映射关系xxx.hbm.xml。然后最最重要的还是双向的一对多关联映射超详细的Hibernate关联关系之双向的一对多关联关系的CRUD操作————学习至黑马程序员视频教程,这篇博文是从视屏教程上面照着代码敲出来的,这个好好理解一下应该问题就不大了。剩下的两个一对一, 多对多,这个是我自己经过百度、参看书上的内容以及参考上面提到的博文做出的测试,里面功能上大概都有涉及到,但是不管从知识点还是注解上都相对没有那么详细。所以一些写的不对的地方欢迎大神指教。。。