(十一)Hibernate中的多表操作(1):单向一对多
一、单向一对多()
- 案例一(用XML文件配置): 一个班级有多个学生,班级可以查看所有学生的信息。
- ClassBean.java
package bean; import java.util.HashSet;
import java.util.Set; /**
* ClassBean entity. @author MyEclipse Persistence Tools
*/ public class ClassBean implements java.io.Serializable { // Fields private Integer classid;
private String classname; private Set<StudentBean> stuSet=new HashSet<StudentBean>(); // Constructors /** default constructor */
public ClassBean() {
} /** minimal constructor */
public ClassBean(Integer classid) {
this.classid = classid;
} /** full constructor */
public ClassBean(Integer classid, String classname) {
this.classid = classid;
this.classname = classname;
} // Property accessors public Integer getClassid() {
return this.classid;
} public void setClassid(Integer classid) {
this.classid = classid;
} public String getClassname() {
return this.classname;
} public void setClassname(String classname) {
this.classname = classname;
} public Set<StudentBean> getStuSet() {
return stuSet;
} public void setStuSet(Set<StudentBean> stuSet) {
this.stuSet = stuSet;
} }
StudentBean.java
package bean; /**
* StudentBean entity. @author MyEclipse Persistence Tools
*/ public class StudentBean implements java.io.Serializable { // Fields private Integer stuid;
private String stuname;
private Integer classId; // Constructors /** default constructor */
public StudentBean() {
} /** minimal constructor */
public StudentBean(Integer stuid) {
this.stuid = stuid;
} /** full constructor */
public StudentBean(Integer stuid, String stuname, Integer classId) {
this.stuid = stuid;
this.stuname = stuname;
this.classId = classId;
} // Property accessors public Integer getStuid() {
return this.stuid;
} public void setStuid(Integer stuid) {
this.stuid = stuid;
} public String getStuname() {
return this.stuname;
} public void setStuname(String stuname) {
this.stuname = stuname;
} public Integer getClassId() {
return this.classId;
} public void setClassId(Integer classId) {
this.classId = classId;
} }
- 单向一对多的映射文件 :
ClassBean.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="bean.ClassBean" table="t_class" catalog="test">
<id name="classid" type="java.lang.Integer">
<column name="classid" />
<generator class="assigned"></generator>
</id>
<property name="classname" type="java.lang.String">
<column name="classname" />
</property> <!--set元素,就是定义一个集合,它的name属性值是对应的POJO中的相关属性名称-->
<set name="stuSet" cascade="all">
<key column="class_id"></key> <!--指定“多”的一段的外键,与“一”端得主键相关联,这里的column=“class_id”是指数据库中的字段,而非bean中的属性,注意这里不会自动生成
class_id属性,所以在bean.StudentBean类中要有一个外键的映射属性-->
<one-to-many class="bean.StudentBean"/> <!--指定了“多”端对应的类-->
</set>
</class>
</hibernate-mapping>
- StudentBean.hbml.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="bean.StudentBean" table="t_student" catalog="test">
<id name="stuid" type="java.lang.Integer">
<column name="stuid" />
<generator class="assigned"></generator>
</id>
<property name="stuname" type="java.lang.String">
<column name="stuname" />
</property>
<property name="classId" type="java.lang.Integer">
<column name="class_id" />
</property>
</class>
</hibernate-mapping>
- 测试类
package action; import java.util.Set; import org.hibernate.Session;
import org.hibernate.Transaction; import bean.ClassBean;
import bean.StudentBean;
import util.HibernateUtil; /**
* 本类测试一对多的操作
* @author 半颗柠檬、
*
*/
public class Test_ManytoOne {
public static void main(String[] args) {
// Test_ManytoOne.save(); // Test_ManytoOne.select(); Test_ManytoOne.delete();
} public static void save(){
Session session = null;
Transaction tran = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
tran=session.beginTransaction(); ClassBean class1=new ClassBean();
class1.setClassid(1);
class1.setClassname("精英班"); StudentBean stu1=new StudentBean();
stu1.setClassId(class1.getClassid());
stu1.setStuid(1);
stu1.setStuname("学生1"); StudentBean stu2=new StudentBean();
stu2.setStuid(2);
stu2.setStuname("学生2");
stu2.setClassId(class1.getClassid()); session.save(class1);
session.save(stu1);
session.save(stu2); tran.commit();
} catch (Exception e) {
e.printStackTrace();
tran.rollback();
}
} /**
* 测试“一”方能够读取“多”方的信息
*/
private static void select() {
Session session = null;
Transaction tran = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
tran=session.beginTransaction(); /**
* 由“一”方得知“多”方信息
*/ ClassBean cla=(ClassBean)session.get(ClassBean.class, new Integer(1)); Set<StudentBean> stuSet=cla.getStuSet(); for(StudentBean stu:stuSet){ System.out.println(stu.getStuname());
System.out.println(stu.getClassId());
System.out.println(stu.getStuid());
} tran.commit();
} catch (Exception e) {
e.printStackTrace();
tran.rollback();
}
} /**
* 删除One一方时,默认不会级联删除Many的一方。
*
* 如果要级联删除:,一般使用代码手动级联更新
*
* A:使用代码来控制级联删除。也是推荐使用的方式,手动进行级联删除,
*
* B:配置级联关系,让Hibernate自动执行。
*
* 在关联关系中配置cascade属性。
*
* @OneToMany(cascade = { CascadeType.REMOVE, CascadeType.MERGE })
*
*/
private static void delete() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction(); /**
* B 在关联关系中配置cascade属性之后
*/
ClassBean class1 = (ClassBean) session.get(ClassBean.class,
new Integer(1));
session.delete(class1); tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
} }
案例二:使用注解测试单向一对多操作
- 一个班级有多个学生,班级可以查看所有学生的信息,但是学生不能查看班级的信息。
- ClassBean.java
package bean; import java.io.Serializable;
import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table; @Entity
@Table(name = "t_class")
public class ClassBean implements Serializable {
@Id
private Integer classId; private String className; @OneToMany
@JoinColumn(name = "class_id") //不会在本类中自动创建名为classes_id的属性因为只有“多”方有外键,Hibernate会自动把本类中的所有属性都映射为数据库中的字段,所以该属性要
//和表中的外键名一致,且Hibernate默认与StudentBean的主键相关联
private Set<StudentBean> stuSet=new HashSet<StudentBean>(); public ClassBean() { } public ClassBean(Integer classId, String className) {
super();
this.classId = classId;
this.className = className;
} public Integer getClassId() {
return classId;
} public void setClassId(Integer classId) {
this.classId = classId;
} public String getClassName() {
return className;
} public void setClassName(String className) {
this.className = className;
} public Set<StudentBean> getStuSet() {
return stuSet;
} public void setStuSet(Set<StudentBean> stuSet) {
this.stuSet = stuSet;
}
}
- StudentBean.java
package bean; import java.io.Serializable; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table; @Entity
@Table(name = "t_student")
public class StudentBean implements Serializable { @Id
@Column(name = "stuid")
private Integer studentId; @Column(name = "stuname")
private String studentName; @Column(name="class_id")
private Integer classid; public StudentBean() { } public StudentBean(Integer studentId, String studentName) {
super();
this.studentId = studentId;
this.studentName = studentName;
} public Integer getStudentId() {
return studentId;
} public void setStudentId(Integer studentId) {
this.studentId = studentId;
} public String getStudentName() {
return studentName;
} public void setStudentName(String studentName) {
this.studentName = studentName;
} public Integer getClassid() {
return classid;
} public void setClassid(Integer classid) {
this.classid = classid;
} }
- 设置总配置文件的映射关系
<mapping class="bean.ClassBean" />
<mapping class="bean.StudentBean" />
- 测试一对多的操作
package action; import java.util.List;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.OneToMany; import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction; import bean.ClassBean;
import bean.StudentBean;
import util.HibernateUtil; /**
* 本类测试一对多的操作
*
* @author 半颗柠檬、
*
*/
public class Test_ManytoOne {
public static void main(String[] args) {
// Test_ManytoOne.save(); // Test_ManytoOne.select(); Test_ManytoOne.delete();
} public static void save() {
Session session = null;
Transaction tran = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
tran = session.beginTransaction(); ClassBean class1 = new ClassBean();
class1.setClassid(1);
class1.setClassname("精英班"); StudentBean stu1 = new StudentBean();
stu1.setClassid(class1.getClassid());
stu1.setStuid(1);
stu1.setStuname("学生1"); StudentBean stu2 = new StudentBean();
stu2.setStuid(2);
stu2.setStuname("学生2");
stu2.setClassid(class1.getClassid()); session.save(class1);
session.save(stu1);
session.save(stu2); tran.commit();
} catch (Exception e) {
e.printStackTrace();
tran.rollback();
}
} /**
* 测试“一”方能够读取“多”方的信息
*/
private static void select() {
Session session = null;
Transaction tran = null;
try {
session = HibernateUtil.getSessionFactory().getCurrentSession();
tran = session.beginTransaction(); /**
* 由“一”方得知“多”方信息
*/ ClassBean cla = (ClassBean) session.get(ClassBean.class,
new Integer(1));
Set<StudentBean> stuSet = cla.getStuSet(); for (StudentBean stu : stuSet) { System.out.println(stu.getStuname() + "\t" + stu.getStuid()
+ "\t" + stu.getClassid()); }
// 过滤后的数据 ,这种方式会把排序注解忽略掉,即排序注解不会生效
System.out.println("过滤后的数据.......");
Query query = session.createFilter(stuSet,
" where stuid in (2,3)");
List<StudentBean> stuList = query.list();
for (StudentBean stu : stuList) { System.out.println(stu.getStuname() + "\t" + stu.getStuid()
+ "\t" + stu.getClassid()); } /**
* 使用HQL语句。
*/ System.out.println("使用HQL语句");
String hql = " select u from StudentBean u where stuid in(2,3) order by stuid desc ";
query = session.createQuery(hql);
stuList = query.list(); for (StudentBean stu : stuList) { System.out.println(stu.getStuname() + "\t" + stu.getStuid()
+ "\t" + stu.getClassid()); } tran.commit();
} catch (Exception e) {
e.printStackTrace();
tran.rollback();
}
} /**
* 删除one一方的时候,一般不删除多方,Hibernate会自动把多方的外键置空
*/
private static void delete() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction(); /**
* B 在关联关系中配置cascade属性之后
*/
ClassBean class1 = (ClassBean) session.get(ClassBean.class,
new Integer(1));
session.delete(class1); tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
} }
- 对于项目中大量使用@Entity注册在类头上,将一个类声明为一个实体bean(即一个持久化POJO类) , @Table注册在类头上,注解声明了该实体bean映射指定的表,来体现实体与表的这种映射关系。
对于属性字段和表的字段关系对应的注解属性的位置,一般我们采用以下两种方式:
第一种:
是把注解@Column(name ="xx")放在field上,一种是把注解放在get方法上一般放在field上看起来比较集中、清晰;
第二种:
是把注解@Column(name= "xx")放在get方法上,这种方式看起来比较散漫、不很清楚;
但是第一种方式这样做实际上破坏了Java面向对象的封装性,原因是一般我们写javaBean,成员变量通常定义为private,目的就是不让别人来直接访问的私有属性,而我们把注解放在私有成员的变量上,就是默认hibernate可以直接访问我们的私有的成员变量,所以我们定义属性为private,就实际没有多大意义,至于hibernate为什么能访问,hibernate采用java的反射机制完全可以访问私有成员变量!所以应该放在get方法上,第二种方式这个时候就显得更加合理。
- 注意 :注意的一点,在一个实体类中,要么将映射注解全部放在成员变量上,要么全部放在成员方法上,不能各放一部分
(十一)Hibernate中的多表操作(1):单向一对多的更多相关文章
- (转)Hibernate中的多表操作
http://blog.csdn.net/yerenyuan_pku/article/details/70556208 Hibernate中的多表操作 在实际开发中,我们不可能只是简简单单地去操作单表 ...
- (十五)Hibernate中的多表操作(5):双向多对多
Hibernate的双向关联. 对象之间可以相互读取. 双向只针对读取的操作.对于增.删除.改的操作没有任何影响. 案例 : 实现双向多对多 MenuBean.java package ...
- (十二)Hibernate中的多表操作(2):单向多对一
由“多”方可知“一”方的信息,比如多个员工使用同一栋公寓,员工可以知道公寓的信息,而公寓无法知道员工的信息. 案例一:使用xml配置 pojo类 Group.java package bean; // ...
- (十四)Hibernate中的多表操作(4):单向一对一
案例一: 注解方式实现一对一 UserBean.java package bean; import java.io.Serializable; import javax.persistence.Col ...
- (十三)Hibernate中的多表操作(3):单向多对多
多对多的处理方式是,有一张中间表,中间表保存两个多方之间的关系.首先来看实际应用场景:在之前开发的系统中,应用了基于角色的控制访问,也就是RBAC模型,一个用户可能存在多种角色,一种角色也可能有多个用 ...
- Hibernate中的多表查询及抓取策略
1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...
- Hibernate超简单多表操作
所谓一对多映射 在数据库中我们通常会通过添加外键的方式将表关联起来,表现一对多的关系. 而在Hibernate中,我们则要通过在一方持有多方的集合来实现,即在"一"的一端中使用元素 ...
- Hibernate框架笔记03表操作多对多配置
目录 1. 数据库表与表之间的关系 1.1 一对多关系 1.2 多对多关系 1.3 一对一关系[了解] 2. Hibernate的一对多关联映射 2.1 创建一个项目,引入相关jar包 2.2. 创建 ...
- 《Java从入门到放弃》入门篇:hibernate中的多表对应关系
hibernate中的对应关系其实就是数据库中表的对应关系, 就跟某些电影中的某些场景是一样一样滴. 比如可以是一男一女,还可以是一男多女, 更可以是多男一女,最后最后最后还可以是多男多女!!! 有些 ...
随机推荐
- Vue 相关开源项目库汇总
element ★9395 - 饿了么出品的Vue2的web UI工具套件 Vux ★6835 - 基于Vue和WeUI的组件库 vueAdmin ★569 - 基于vuejs2和element的简单 ...
- MySQL数据类型(最大值 和 最小值)
MySQL数据类型(最大值 和 最小值) 1.整型 MySQL数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-3276 ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_04-用户认证技术方案-SpringSecurityOauth2
2.3 Spring security Oauth2认证解决方案 本项目采用 Spring security + Oauth2完成用户认证及用户授权,Spring security 是一个强大的和高度 ...
- python 中 staticmethod 和 classmethod有什么区别
面试中经常会问到staticmethod 和 classmethod有什么区别? 首先看下官方的解释: staticmethod: class staticmethod staticmethod(fu ...
- 123457123456#0#-----com.threeapp.renZheDadishu02-----忍者版打地鼠
com.threeapp.renZheDadishu02-----忍者版打地鼠
- jquery图片播放插件Fancybox使用详解
今天给大家介绍的jquery图片播放插件叫Fancybox,相比LightBox来说,Fancybox相对庞大点,配置也更丰富一些,相信你会喜欢的. Fancybox的项目主页地址:http://fa ...
- iOS-条形码扫描技术SDK:ZBar(转)
ios条形码扫描技术 iOS 应用里实现条形码扫描功能,有个免费开源的 SDK:ZBar(http://zbar.sourceforge.net/iphone/sdkdoc/install.html) ...
- 数据链路层学习之LLDP
数据链路层学习之LLDP 2013年09月02日 20:38:36 goodluckwhh 阅读数 42323 一.LLDP协议概述 随着网络技术的发展,接入网络的设备的种类越来越多,配置越来越复 ...
- html转图片网页截屏(二)PhantomJS
关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS ...
- Fakes里的stub和shim的区别
stub常用于虚拟接口.类.方法,无法重写静态方法(stub需要传递到具体调用代码中) shim常用于重写静态方法(在ShimsContext.Create()作用域内,拦截Runtime动态修改方法 ...