hibernate多对一双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接。
本系列将介绍Hibernate中主要的几种关联映射
Hibernate一对一主键单向关联
Hibernate一对一主键双向关联
Hibernate一对一外键单向关联
Hibernate一对一外键双向关联
Hibernate多对一单向关联
Hibernate多对一双向关联
Hibernate多对多关联
代码都写有注释,主要包括(核心配置文件,实体映射文件,实体类,测试类,数据库)主要操作有增删改查。
本篇主要介绍Hibernate多对一单向关联:
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.driver_class">com.mysql.jdbc.Driver</property>
<!-- 配置数据库连接字符串 -->
<property name="connection.url"><![CDATA[jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8]]></property>
<!-- 配置数据库连接用户名 -->
<property name="connection.username">root</property>
<!-- 配置数据库连接密码 -->
<property name="connection.password">123456</property>
<!-- 配置数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置数据库表生成策略 -->
<!--<property name="hibernate.hbm2ddl.auto">update</property> -->
<!-- 配置是否打印显示SQL语句 -->
<property name="show_sql">true</property>
<!-- 配置是否格式化显示SQL语句 -->
<property name="format_sql">true</property>
<!-- 配置hibernate是否自动提交事务 -->
<!--<property name="hibernate.connection.autocommit">true</property> -->
<!-- 配置实体类对应的映射文件 -->
<!-- 多对一双向关联配置 -->
<mapping resource="com/great/entity/Class.hbm.xml"></mapping>
<mapping resource="com/great/entity/Student.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
Student.hbm.xml
<?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 package="com.great.entity">
<!-- 配置实体类与数据库表的映射关系 -->
<class name="Student" table="student">
<!-- 配置主键映射关系 -->
<id name="id" column="sId" type="int">
<!-- 配置主键生成策略 -->
<generator class="identity">
</generator>
</id>
<!-- 配置属性和表字段映射关系 -->
<property name="sName" column="sName" type="string"></property>
<!-- 多对一关联关系配置 -->
<!-- many-to-one标签声明多对一关联关系,name指定多方所维护的一方的实例名 -->
<many-to-one name="classes" class="com.great.entity.Class"
cascade="save-update">
<!-- column标签指定关联外键,还是子表的外键列名 -->
<column name="cId"></column>
</many-to-one>
</class>
</hibernate-mapping>
Class.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="com.great.entity">
<class name="Class" table="class">
<!-- 配置主键映射关系 -->
<id name="cId" column="cId" type="int">
<!-- 配置主键生成策略 -->
<generator class="identity">
</generator>
</id>
<!-- 配置属性和表字段映射关系 -->
<property name="cName" column="cName" type="string"></property>
<!-- 一对多关联关系配置 -->
<!-- inverse属性设置为true代表一的一方不在拥有关联关系的控制权,而把控制权交给多的一方 -->
<!-- fetch属性用来指定子表数据的抓取策略,默认值为"select",代表对主表子表进行单独查询 ,对主表子表单独发select语句 -->
<!-- fetch属性用来指定子表数据的抓取策略,设置为"join"时,代表对主表子表进行关联查询,对主表子表发出关联查询语句 -->
<!-- lazy属性用来指定子表数据是否延迟加载,fetch="select"时起作用,fetch="join"时不起作用 -->
<!-- fetch="select" lazy="true" -->
<set name="students" cascade="all" inverse="true">
<!-- key配置的是子表的外键列名 -->
<key column="cId"></key>
<!-- one-to-many标签声明关联关系是一对多,class指定多方的实体类类型 -->
<one-to-many class="com.great.entity.Student" />
</set>
</class>
</hibernate-mapping>
Student.java
package com.great.entity;
import com.great.entity.Class;
public class Student {
private int id;
private String sName;
// 多对一映射时,因为要维护一的一方的实例,所以外键不需要映射
// private int cId;
private Class classes;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public Class getClasses() {
return classes;
}
public void setClasses(Class classes) {
this.classes = classes;
}
}
Class.java
package com.great.entity;
import java.util.HashSet;
import java.util.Set;
import com.great.entity.Student;
public class Class {
// 班级id
private int cId;
// 班级名字
private String cName;
// 注意点:必须new一个Set的实现类的实例
// 原因:子表不一定有主表的关联数据,所以可能取出空集合,引发空指针异常
private Set<Student> students = new HashSet<Student>();
public int getcId() {
return cId;
}
public void setcId(int cId) {
this.cId = cId;
}
public String getcName() {
return cName;
}
public void setcName(String cName) {
this.cName = cName;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Class [cId=" + cId + ", cName=" + cName + ", students="
+ students + "]";
}
}
TestManyToOneBoth.java
package com.great.test;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.great.entity.Class;
import com.great.entity.Student;
public class TestManyToOneBoth {
static Session session;
// 多对一双向关联
@BeforeClass
public static void setUpBeforeClass() throws Exception {
// 加载hibernate主配置文件
Configuration cfg = new Configuration().configure();
// 构建session工厂
SessionFactory sf = cfg.buildSessionFactory();
// 打开session
session = sf.openSession();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
// 关闭session,释放资源
session.close();
}
// select1, 通过class查询到student
@Test
public void testManyToOneBothSelect1() {
Class c = (Class) session.get(Class.class, 5);
System.out.println("班级为:" + c.getcName());
System.out.println("cId:" + c.getcId());
Set<Student> students = c.getStudents();
Iterator<Student> it = students.iterator();
while (it.hasNext()) {
Student student = (Student) it.next();
System.out.println("学生姓名:" + student.getsName());
}
}
// select2, 通过student查询到class
@Test
public void testManyToOneBothSelect2() {
Student s = (Student) session.get(Student.class, 3);
System.out.println("学生名字为:" + s.getsName());
System.out.println("班级为:" + s.getClasses().getcName());
}
// insert1,通过class保存数据,一条insert class.两条insert student
@Test
public void testManyToOneBothSave1() {
Transaction ts = session.beginTransaction();
Class c = new Class();
c.setcName("通信2班");
Student s1 = new Student();
Student s2 = new Student();
s1.setsName("学员1");
s2.setsName("学员2");
c.getStudents().add(s1);// 必须加
c.getStudents().add(s2);// 必须加
s1.setClasses(c);
s2.setClasses(c);
session.save(c);
ts.commit();
}
// insert2,通过student保存数据,一条insert class.两条insert student
@Test
public void testManyToOneBothSave2() {
Transaction ts = session.beginTransaction();
Class c = new Class();
c.setcName("硬件3班");
Student s1 = new Student();
Student s2 = new Student();
s1.setsName("学员3");
s2.setsName("学员4");
c.getStudents().add(s1);// 可加可不加
c.getStudents().add(s2);// 可加可不加
s1.setClasses(c);
s2.setClasses(c);
session.save(s1);
session.save(s2);
ts.commit();
}
// delete1数据,仅仅删除student,cascade="save-update"[因为是多对一] 发出一条select ,一条delete
@Test
public void testManyToOneDelete1() {
Transaction ts = session.beginTransaction();
Student student = (Student) session.get(Student.class, 17);
session.delete(student);
ts.commit();
}
/*
* delete2数据,通过删除class,把与class以及class相关的student全部删除,先删student,再删class,发出两条select
* ,两条delete,在class配置文件中配置cascade="all"
*/
@Test
public void testManyToOneDelete2() {
Transaction ts = session.beginTransaction();
Class classes = (Class) session.get(Class.class, 2);
session.delete(classes);
ts.commit();
}
// 更新数据1,通过student进行更新
@Test
public void testManyToOneUpdate1() {
Transaction ts = session.beginTransaction();
Student student = (Student) session.get(Student.class, 2);
student.setsName("小哥");
student.getClasses().setcName("设计二班");
session.saveOrUpdate(student);
ts.commit();
}
// 更新数据2,通过class进行更新
@Test
public void testOneToOneUpdate2() {
Transaction ts = session.beginTransaction();
Class classes = (Class) session.get(Class.class, 11);
classes.setcName("工业设计五班");
Set<Student> students = classes.getStudents();
Iterator<Student> it = students.iterator();
while (it.hasNext()) {
Student student = (Student) it.next();
System.out.println("学生姓名:" + student.getsName());
if ("吴邪".equals(student.getsName())) {
student.setsName("吴小邪");
}
}
ts.commit();
}
}
数据库:
student表
三个字段 sId sName cId(外键)
class表
两个字段 cId cName
注意:在student表的cId上建立外键关系。
hibernate多对一双向关联的更多相关文章
- Java进阶知识12 Hibernate多对多双向关联(Annotation+XML实现)
1.Annotation 注解版 1.1.应用场景(Student-Teacher):当学生知道有哪些老师教,老师也知道自己教哪些学生时,可用双向关联 1.2.创建Teacher类和Student类 ...
- Hibernate多对多双向关联的配置
Hibernate的双向多对多关联有两种配置方法:那我们就来看看两种方案是如何配置的. 一.创建以各自类为类型的集合来关联 1.首先我们要在两个实体类(雇员<Emploee>.工程< ...
- Hibernate多对多双向关联
以Student和Course为例,一个学生可以选多门课程,一门课程也可以被多个学生选取: 持久化类Student: package bean; import java.util.Set; publi ...
- Hibernate多对多双向关联需要注意的问题(实例说话)
以Student和Course为例,一个学生可以选多门课程,一门课程也可以被多个学生选取: 持久化类Student: package bean; import java.util.Set; publi ...
- hibernate 多对多双向关联
package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax.persistenc ...
- Java进阶知识10 Hibernate一对多_多对一双向关联(Annotation+XML实现)
本文知识点(目录): 1.Annotation 注解版(只是测试建表) 2.XML版 的实现(只是测试建表) 3.附录(Annotation 注解版CRUD操作)[注解版有个问题:插入值时 ...
- hibernate多对一单向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Java进阶知识11 Hibernate多对多单向关联(Annotation+XML实现)
1.Annotation 注解版 1.1.应用场景(Student-Teacher):当学生知道有哪些老师教,但是老师不知道自己教哪些学生时,可用单向关联 1.2.创建Teacher类和Student ...
- Java进阶知识08 Hibernate多对一单向关联(Annotation+XML实现)
1.Annotation 注解版 1.1.在多的一方加外键 1.2.创建Customer类和Order类 package com.shore.model; import javax.persisten ...
随机推荐
- IE10、IE11 User-Agent 导致的 ASP.Net 网站无法写入Cookie 问题
你是否遇到过当使用一个涉及到Cookie操作的网站或者管理系统时,IE 6.7.8.9下都跑的好好的,唯独到了IE10.11这些高版本浏览器就不行了?好吧,这个问题码农连续2天内遇到了2次.那么,我们 ...
- System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
在NHibernate数据库查询中出现了这个错误,由于是数据库是mysql的,当定义的字段为char(36)的时候就会出现这个错误. [解决方法] 将char(36) 改成varchar(40)就行了 ...
- 一篇文章看懂TPCx-BB(大数据基准测试工具)源码
TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...
- OpenGL超级宝典笔记----框架搭建
自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...
- iOS UITableView 与 UITableViewController
很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名.项目地址. UITab ...
- nodejs操作arduino入门(javascript操作底层硬件)
用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...
- C#关于分页显示
---<PS:本人菜鸟,大手子还请高台贵手> 以下是我今天在做分页时所遇到的一个分页显示问题,使用拼写SQL的方式写的,同类型可参考哦~ ------------------------- ...
- 在你的ASP.NET MVC中使用查找功能
在程序中,使用查找功能是少之不了.今天在ASP.NET环境下演示一回. 在cshtml视图中,有三个文本框,让用户输入关键词,然后点击最右连的“搜索”铵钮,如果有结果将显示于下面. Html: 表格放 ...
- WEB安全隐患
org.apache.commons.lang.StringEscapeUtils 进行输入框内容处理 [StringEscapeUtils.escapeSql(str);StringEscapeUt ...
- 一些关于Linux入侵应急响应的碎碎念
近半年做了很多应急响应项目,针对黑客入侵.但疲于没有时间来总结一些常用的东西,寄希望用这篇博文分享一些安全工程师在处理应急响应时常见的套路,因为方面众多可能有些杂碎. 个人认为入侵响应的核心无外乎四个 ...