(十二)Hibernate中的多表操作(2):单向多对一
- 由“多”方可知“一”方的信息,比如多个员工使用同一栋公寓,员工可以知道公寓的信息,而公寓无法知道员工的信息。
案例一:使用xml配置
- pojo类 Group.java
package bean; // default package /**
* Group entity. @author MyEclipse Persistence Tools
*/ public class Group implements java.io.Serializable { // Fields private Integer groupid;
private String groupname; //省略get和set方法
//省略空的和满的构造方法 }
GroupUser.java
package bean; // default package /**
* GroupUser entity. @author MyEclipse Persistence Tools
*/ public class GroupUser implements java.io.Serializable { // Fields private Integer userid;
private String username; private Group group; //省略get和set方法
//省略构造方法 }
- 实体映射文件 Group.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"> <hibernate-mapping>
<class name="bean.Group" table="t_group" catalog="test">
<id name="groupid" type="java.lang.Integer">
<column name="groupid" />
<generator class="assigned"></generator>
</id>
<property name="groupname" type="java.lang.String">
<column name="groupname" />
</property>
</class>
</hibernate-mapping>
GroupUser.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.GroupUser" table="t_groupuser" catalog="test">
<id name="userid" type="java.lang.Integer">
<column name="userid" />
<generator class="assigned"></generator>
</id>
<property name="username" type="java.lang.String">
<column name="username" />
</property>
<!-- name的值要与本类的属性名一致,这里指定这个bean映射的表的外键为group_id属性且该属性是自动生成的,所以必须与数据库中的外键字段一致,
//所以该bean就不需要设置表中外键的映射了。
// hibernate默认该外键关联group映射的表的主键, -->
<many-to-one name="group" class="bean.Group" column="group_id" cascade="all"></many-to-one> <!-- class值指定了“一”方的类 -->
</class>
</hibernate-mapping>
<many-to-one >元素建立了department属性和employee表的外键depart_id之间的映射.
<many-to-one name="group" class="bean.Group" column="group_id" cascade="all">
- <many-to-one name="group" class="bean.Group" column="group_id" cascade="all">这种情况,hibernate会默认去group对象中查找主键值,因为hibernate默认的是外键对应另一个表中的主键的,如果想对应group中的其它属性,如”name”,则可以使用<many-to-one name=”group” column=”group_id” property-ref=”name”/>
name: 设定待映射的持久化类的属性名,此外为employee类的department属性.
column: 设定和持久化类的属性对应的表的外键,此外为employee表的外键depart_id.
class(可选):设定持久化类的属性的类型,此处设定department的类型是Department类.
not-null(可选):如果为true,表示department属性不能为null,该属性的默认值为false.当为true时,生成的employee表中depart_id外键会设置not-null约束,所以当Hibernate保存Employee对象时,会先检查它的department属性是否为null,如果为null,则会抛出异常.
案例二:使用注解配置
- 多个用户对应一个组,一个组有多个用户。且多个用户可以知道组的信息,但是组不能知道用户的信息。
- 数据库中表结构:


- 建议pojo持久化类: Group.java
package bean; import java.io.Serializable; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity
@Table(name = "t_group")
public class Group implements Serializable { @Id
@GeneratedValue(generator="a")
@GenericGenerator(name="a",strategy="assigned")
private Integer groupid;
@Column(name="groupname")
private String groupName; //省略get和set方法
//省略空的构造方法和满构造方法 }
- GroupUser.java
package bean; import java.io.Serializable; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity
@Table(name = "t_groupuser")
public class GroupUser implements Serializable { @Id
@GeneratedValue(generator = "designed")
@GenericGenerator(name = "designed", strategy = "assigned")
private Integer userid; private String username; @ManyToOne(cascade = { CascadeType.REMOVE, CascadeType.MERGE }) // 设置关联关系和级联类型
@JoinColumn(name = "group_id") // 该注解表示指定外键,这里指定这个bean映射的表的外键为group_id属性且该属性是自动生成的,所以必须与数据库中的外键字段一致,所以该bean就不需要设置表中外键的映射了。
// hibernate默认该外键关联group映射的表的主键, private Group group; public GroupUser() { } public GroupUser(Integer userid, String username) {
super();
this.userid = userid;
this.username = username; } public Integer getUserid() {
return userid;
} public void setUserid(Integer userid) {
this.userid = userid;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Group getGroup() {
return group;
} public void setGroup(Group group) {
this.group = group;
} }
- 测试类 Test_ManytoOne.java
package action; import org.hibernate.Session;
import org.hibernate.Transaction; import bean.Group;
import bean.GroupUser;
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(); //添加一个组
Group group=new Group();
group.setGid(1);
group.setGroupName("管理员组"); //添加组成员
GroupUser user=new GroupUser();
user.setUserid(1);
user.setUsername("admin1");
user.setGroup(group); GroupUser user1=new GroupUser();
user1.setUserid(2);
user1.setUsername("admin2");
user1.setGroup(group); session.save(group);
session.save(user);
session.save(user1); 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(); GroupUser user= (GroupUser)session.get(GroupUser.class, new Integer(2));
System.out.println(user.getUserid()+"\t"+user.getUsername()); //单向获取“一”方的信息 Group group=user.getGroup();
System.out.println("groupid="+group.getGid()+"\t"+group.getGroupName()); tran.commit();
} catch (Exception e) {
e.printStackTrace();
tran.rollback();
}
} /**
* 删除Many一方时,默认不会级联删除One的一方。
*
* 如果要级联删除:,一般使用代码手动级联更新
*
* A:使用代码来控制级联删除。[使用这种方式]
*
* B:配置级联关系,让Hibernate自动执行。
*
* 在关联关系中配置cascade属性。
*
* @ManyToOne(cascade = { CascadeType.REMOVE, CascadeType.MERGE })
*
*/
private static void delete() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
/**
* A:使用代码控制级联
*/
// GroupUser user = (GroupUser) session.get(GroupUser.class,
// new Integer(1));
//
// session.delete(user);
//
// Group group = user.getGroup();
// session.delete(group);
/**
* B 在关联关系中配置cascade属性之后
*/
GroupUser user = (GroupUser) session.get(GroupUser.class,
new Integer(1));
session.delete(user); tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
} }
- 一对多可以从“一”方得到“多”方的信息,那么可以用
OneToMany
@JoinColumn(name = " ")
@OrderBy(value=" studentID desc")
来对获得的“多”方信息进行排序
(十二)Hibernate中的多表操作(2):单向多对一的更多相关文章
- (转)Hibernate中的多表操作
http://blog.csdn.net/yerenyuan_pku/article/details/70556208 Hibernate中的多表操作 在实际开发中,我们不可能只是简简单单地去操作单表 ...
- (十五)Hibernate中的多表操作(5):双向多对多
Hibernate的双向关联. 对象之间可以相互读取. 双向只针对读取的操作.对于增.删除.改的操作没有任何影响. 案例 : 实现双向多对多 MenuBean.java package ...
- (十三)Hibernate中的多表操作(3):单向多对多
多对多的处理方式是,有一张中间表,中间表保存两个多方之间的关系.首先来看实际应用场景:在之前开发的系统中,应用了基于角色的控制访问,也就是RBAC模型,一个用户可能存在多种角色,一种角色也可能有多个用 ...
- (十四)Hibernate中的多表操作(4):单向一对一
案例一: 注解方式实现一对一 UserBean.java package bean; import java.io.Serializable; import javax.persistence.Col ...
- (十一)Hibernate中的多表操作(1):单向一对多
一.单向一对多() 案例一(用XML文件配置): 一个班级有多个学生,班级可以查看所有学生的信息. ClassBean.java package bean; import java.util.Hash ...
- J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用
J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用 spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...
- 二十二、OGNL的一些其他操作
二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $ public class Demo2Action extends ActionSupport { public ...
- 第二十二章 Django会话与表单验证
第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...
- (转)SpringMVC学习(十二)——SpringMVC中的拦截器
http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...
随机推荐
- SpringBoot缓存技术
一.SpringBoot整合Ehhcache 添加maven依赖 <dependency> <groupId>org.springframework.boot</grou ...
- 解决ZendStudio打开utf-8格式的php文件乱码
一般php文件都为utf-8无BOM格式的,用zendstudio默认设置打开时中文会产生乱码,这是因为zendstudio默认设置编码格式为GBK格式,所以我们这里需要重新设置其编码格式,这个是ze ...
- QDateTime QString
QDateTime格式化 yyyy-MM-dd hh:mm:ss QString getFormatDateStr(QDateTime dateTimeParam) { qDebug() <& ...
- DTC & MSDTC (待研究)
相关学习文档: Database Systems: The Complete Book
- Python2和Python3的字符串编码和类型
一.字符串编码和类型 任何编码格式的字符串,都可以和Unicode互相转换. gbk -> utf8 # 将字符串按指定格式进行解码,返回Unicode字符串unicode_str = gbk_ ...
- .NET CORE添加引用包
一 .添加服务端引用 1.直接右键添加项目引用,添加后再csproj文件中如下②,也可以直接用这种格式写入csproj文件中 2.直接右键添加DLL引用,添加后再csproj文件中如下③,也可以直接用 ...
- iOS-AVPlayer
MPMoviePlayerController足够强大,几乎不用写几行代码就能完成一个播放器,但是正是由于它的高度封装使得要自定义这个播放 器变得很复杂,甚至是不可能完成.例如有些时候需要自定义播放器 ...
- 最新 中钢网java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.中钢网等10家互联网公司的校招Offer,因为某些自身原因最终选择了中钢网.6.7月主要是做系统复习.项目复盘.LeetCo ...
- UIPath工具里面如何入力一览里面的数据
问题描述: UIpath工具如何在网页里面入力一览多条的数据.例如:某个公司里面在自己的内部员工管理的软件里面手动入力公司员工的所有信息之后反馈到数据库当中. 解决方法: UIpath工具来入力数据, ...
- Time & Space Complexity
Quick Sort: Time complexity: best case O(n*lgn), worst case O(n^2) Space complexity: Best case O(lgn ...