Hibernate实战——双向N-N关联
一 配置文件
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate-configuration是配置文件的根元素 -->
<hibernate-configuration><session-factory><!-- 指定连接数据库所用的驱动 --><property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 --><property name="connection.url">jdbc:mysql://localhost/hibernate</property><!-- 指定连接数据库的用户名 --><property name="connection.username">root</property><!-- 指定连接数据库的密码 --><property name="connection.password">32147</property><!-- 指定连接池里最大连接数 --><property name="hibernate.c3p0.max_size">20</property><!-- 指定连接池里最小连接数 --><property name="hibernate.c3p0.min_size">1</property><!-- 指定连接池里连接的超时时长 --><property name="hibernate.c3p0.timeout">5000</property><!-- 指定连接池里最大缓存多少个Statement对象 --><property name="hibernate.c3p0.max_statements">100</property><property name="hibernate.c3p0.idle_test_period">3000</property><property name="hibernate.c3p0.acquire_increment">2</property><property name="hibernate.c3p0.validate">true</property><!-- 指定数据库方言 --><property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property><!-- 根据需要自动创建数据库 --><property name="hbm2ddl.auto">update</property><!-- 显示Hibernate持久化操作所生成的SQL --><property name="show_sql">true</property><!-- 将SQL脚本进行格式化后再输出 --><property name="hibernate.format_sql">true</property><!-- 罗列所有持久化类的类名 --><mapping class="org.crazyit.app.domain.Person"/><mapping class="org.crazyit.app.domain.Address"/></session-factory>
</hibernate-configuration>
二 PO
1 Person
package org.crazyit.app.domain;import java.util.*;import javax.persistence.*;@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体所有关联的Address实体@ManyToMany(targetEntity=Address.class)// 映射连接表,指定连接表的表名为person_address@JoinTable(name="person_address",// 映射连接表中名为person_id的外键列,// 该列参照当前实体对应表的person_id主键列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),// 映射连接表中名为address_id的外键列,// 该列参数当前实体的关联实体对应表的address_id主键列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Set<Address> addresses= new HashSet<>();// id的setter和getter方法public void setId(Integer id){this.id = id;}public Integer getId(){return this.id;}// name的setter和getter方法public void setName(String name){this.name = name;}public String getName(){return this.name;}// age的setter和getter方法public void setAge(int age){this.age = age;}public int getAge(){return this.age;}// addresses的setter和getter方法public void setAddresses(Set<Address> addresses){this.addresses = addresses;}public Set<Address> getAddresses(){return this.addresses;}
}
2 Address
package org.crazyit.app.domain;import java.util.*;import javax.persistence.*;@Entity
@Table(name="address_inf")
public class Address
{// 标识属性@Id @Column(name="address_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private int addressId;// 定义地址详细信息的成员变量private String addressDetail;// 定义该Address实体所有关联的Person实体@ManyToMany(targetEntity=Person.class)// 映射连接表,指定连接表的表名为person_address@JoinTable(name="person_address",// 映射连接表中名为address_id的外键列,// 该列参照当前实体对应表的address_id主键列joinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"),// 映射连接表中名为person_id的外键列,// 该列参照当前实体对应表的person_id主键列inverseJoinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"))private Set<Person> persons= new HashSet<>();// 无参数的构造器public Address(){}// 初始化全部成员变量的构造器public Address(String addressDetail){this.addressDetail = addressDetail;}// addressId的setter和getter方法public void setAddressId(int addressId){this.addressId = addressId;}public int getAddressId(){return this.addressId;}// addressDetail的setter和getter方法public void setAddressDetail(String addressDetail){this.addressDetail = addressDetail;}public String getAddressDetail(){return this.addressDetail;}// persons的setter和getter方法public void setPersons(Set<Person> persons){this.persons = persons;}public Set<Person> getPersons(){return this.persons;}
}
三 测试
1 工具类
package lee;import org.hibernate.*;
import org.hibernate.cfg.*;
import org.hibernate.service.*;
import org.hibernate.boot.registry.*;public class HibernateUtil
{public static final SessionFactory sessionFactory;static{try{// 使用默认的hibernate.cfg.xml配置文件创建Configuration实例Configuration cfg = new Configuration().configure();// 以Configuration实例来创建SessionFactory实例ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();sessionFactory = cfg.buildSessionFactory(serviceRegistry);}catch (Throwable ex){System.err.println("Initial SessionFactory creation failed." + ex);throw new ExceptionInInitializerError(ex);}}// ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步public static final ThreadLocal<Session> session= new ThreadLocal<Session>();public static Session currentSession()throws HibernateException{Session s = session.get();// 如果该线程还没有Session,则创建一个新的Sessionif (s == null){s = sessionFactory.openSession();// 将获得的Session变量存储在ThreadLocal变量session里session.set(s);}return s;}public static void closeSession()throws HibernateException{Session s = session.get();if (s != null)s.close();session.set(null);}
}
2 测试类
package lee;import org.hibernate.Transaction;
import org.hibernate.Session;import java.util.Date;
import java.util.Set;
import java.util.HashSet;import org.crazyit.app.domain.*;public class PersonManager
{public static void main(String[] args){PersonManager mgr = new PersonManager();mgr.testPerson();HibernateUtil.sessionFactory.close();}private void testPerson(){Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();// 创建一个Person对象Person p = new Person();// 设置Person的name为crazyitp.setName("crazyit");p.setAge(20);// 持久化Person对象(对应于插入主表记录)session.save(p);// 创建一个瞬态的Address对象Address a = new Address("广州天河");// 先设置Person和Address之间的关联关系a.getPersons().add(p);// 再持久化Address对象session.persist(a);// 创建一个瞬态的Address对象Address a2 = new Address("上海虹口");// 先设置Person和Address之间的关联关系a2.getPersons().add(p);// 再持久化Address对象(对应于插入从表记录)session.persist(a2);Person p2 = new Person();p2.setName("fkit");p2.setAge(29);p2.getAddresses().add(a2);session.save(p2);tx.commit();HibernateUtil.closeSession();}
}
四 运行
Hibernate:insertintoperson_inf(age, name)values(?, ?)
Hibernate:insertintoaddress_inf(addressDetail)values(?)
Hibernate:insertintoaddress_inf(addressDetail)values(?)
Hibernate:insertintoperson_inf(age, name)values(?, ?)
Hibernate:insertintoperson_address(address_id, person_id)values(?, ?)
Hibernate:insertintoperson_address(address_id, person_id)values(?, ?)
Hibernate:insertintoperson_address(person_id, address_id)values(?, ?)
Hibernate实战——双向N-N关联相关推荐
- Hibernate双向多对多关联
一.配置双向多对多关联 以Project类(项目)和Emp类(员工)为例: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project {//编号private ...
- Hibernate 一对一外键单向关联
[align=center][size=medium]Hibernate 一对一外键单向关联[/size][/align] 基于外键关联的单向一对一关联和单向多对一关联几乎是一样的.唯一的不同就是单向 ...
- hibernate one2one 唯一外键关联(双向关联)
hibernate的一对一唯一外键关联映射(双向关联 Person <------->IdCard) 一对一唯一外键关联采用<one - to -one>标签映射,必须指定标签 ...
- Hibernate关系映射 一对一双向外键关联@OneToOne Annotation方式
首先还是来构造一个实际应用的场景,比如实体类车辆(Car),它具有以下属性:Id,品牌(brand),车牌(lisencePlate):实体类车牌(LisencePlate),它具有以下属性:Id,号 ...
- hibernate 双向一对多 关联在多端维护
作者:xyzroundo 如果在"一"一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多 的一端来维护关联关系
- Hibernate学习之一对多关联
注意事项: 1.单向一对多 只需在"一"放进行配置 2.双向一对多 需要在关联双方都加以配置,而且需要在一的一方设置inverse=true 首先是实体类: TAddress ...
- hibernate一对一外键单向关联
与上篇相对应,还是client和address是一对一的外键关联关系,address表中的主键ID与client表中的外键CLIENTADDRESSID构成一对一外键关联关系. 表结构和sql语句就不 ...
- 双向@OneToMany / @ManyToOne关联
编程的目标之一是代表现实世界中的模型. 通常,应用程序需要对实体之间的某些关系进行建模. 在上一篇有关Hibernate关联的文章中,我描述了建立"一对一"关系的规则. 今天,我将 ...
- Hibernate一对一主键单向关联
2019独角兽企业重金招聘Python工程师标准>>> 模型user,address address对user进行外键关联,意思就是address的主键是由user的主键关联生成的, ...
最新文章
- 可解释机器学习发展和常见方法!
- Java性能压测-性能监控-jvisualvm使用
- Gradle 引入本地定制 jar 包,而不使用坐标下载 jar 包的方法
- 基于计算机的控制系统,基于计算机的机械控制系统实现方式研究.pdf
- 计算机网络技术基础教学内容,计算机网络技术基础
- 计算机表格复制粘贴后不变,excel表格复制粘贴后格式不变
- linux有关信号的FAQ
- Vue给单独页面添加背景色
- WF4.0 Beta1 CancellationScope 取消容器
- Gym - 100625G Getting Through 计算几何+并查集
- 目标检测 | CVPR 2019 目标检测论文汇总
- java opts配置_JAVA_OPTS设置
- MW6MaxiCode ACX溢出
- 空间矢量数据处理 | 第一讲:矢量数据的读入与保存
- 子查询及其分类(标量子查询+列子查询+行子查询+表子查询)
- 二元置信椭圆r语言_R语言 第4章 初级绘图(6)
- pycharm 光标突然变粗,无法正常书写
- C语言常用转义字符表 和 ASCII码表完整版
- python可视化图表生成(二)
- 11月编程排行榜来了,Python依旧占据榜首
热门文章
- 【h5白鹭引擎】如何快速开发一个小游戏
- java 连接sqlserver_java如何连接sqlserver数据库
- 【渐进式:深度光谱变换】
- java程序设计方法
- 输入5个学生某门课程的成绩(用一维数组表示),分别用函数实现下列功能:
- daas 数据即服务_什么是daas
- OA系统的一些学习心得(更新中)
- 什么是算法?数据结构与算法概念
- 企业如何建立完善的管理体系
- opencv python考勤_GitHub - liqq1228/python-opencv: 基于python opencv人脸识别的员工考勤系统...