hibernate关联关系的crud2
hibernate关联关系的CRUD操作,解释都在注释里了,讲了fetchType、cascade。
User类:
package com.oracle.hibernate; import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; @Entity
public class User { private int id;
private String name;
private Group group; //多对一
@ManyToOne(cascade={CascadeType.ALL}//, //设置级联
//fetch = FetchType.LAZY
)
@JoinColumn(name="groupId")//指定外键名称
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
Group类:
package com.oracle.hibernate; import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table; @Entity
@Table(name="t_group")//group是mysql的关键字,换个名
public class Group { private int id;
private String name;
private Set<User> users = new HashSet<User>(); //设置mappedBy和级联
@OneToMany(mappedBy="group",
cascade={CascadeType.ALL}//,//级联管增删改, //fetch=FetchType.EAGER //一的一方默认为LAZY
)
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
测试类:
package com.oracle.hibernate; import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass; public class Test { private static SessionFactory sf = null;
@BeforeClass
public static void beforeClass(){ try {
//生成表
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
sf = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @org.junit.Test
public void testSchemaExport(){
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true); }
@AfterClass
public static void afterClass(){
sf.close();
} @org.junit.Test
public void testSaveUser(){ Session s = sf.getCurrentSession();
s.beginTransaction();
User user = new User();
user.setName("u1");
Group g = new Group();
g.setName("g1");
user.setGroup(g);
//s.save(g);默认不会自动保存关联变量,
//设置cascade后,直接保存user就能把user的group也保存
s.save(user);
s.getTransaction().commit();
} @org.junit.Test
public void testSaveGroup(){ Group g = new Group();
g.setName("g1");
User u1 = new User();
u1.setName("u1");
//必须设定User所属的group,否则在保存user时不会保存g的信息(hibernate不知道属于哪个group啊)
u1.setGroup(g);
User u2 = new User();
u2.setName("u2");
u2.setGroup(g);
g.getUsers().add(u1);
g.getUsers().add(u2); Session s = sf.getCurrentSession();
s.beginTransaction(); s.save(g);
s.getTransaction().commit();
} @org.junit.Test
public void testGetUser(){
testSaveGroup();//生成数据 Session s = sf.getCurrentSession();
s.beginTransaction();
/**
* 默认情况,多的一方的fetchType=Eager,这符合正常思维,比如我们取学生时也会把他的老师取出来。
* 设置多的一方User里设fetchType=Lazy时(很少这么干),执行下边的代码发出的sql语句是:
* Hibernate:
select
user0_.id as id2_0_,
user0_.groupId as groupId2_0_,
user0_.name as name2_0_
from
User user0_
where
user0_.id=?
不会把一的一方Group给取出来,只有当用到group的时候(如下边的取u.getGroup.getName)才发sql语句把User和group连接查询
*
*/
User u = (User) s.get(User.class,1);
//取User,默认情况下,不设cascade,也能取出group,这符合平常逻辑。
System.out.println(u.getName()+u.getGroup().getName());
s.getTransaction().commit(); //System.out.println(u.getName()+u.getGroup().getName());
//会报错,因为fetchType为Lazy,用group的时候才发sql语句,而session却关了,所以报错(懒加载错误)
} @org.junit.Test
public void testGetGroup(){
testSaveGroup();//生成数据 Session s = sf.getCurrentSession();
s.beginTransaction();
//取group一方,fetchType默认为Lazy,执行下边的一句话:
//不发取user的sql语句,只发取group的信息的sql。不取多的一方,只有用到user信息时才发sql'语句,下边的g.getUsers()XXX
Group g = (Group) s.get(Group.class,1);
s.getTransaction().commit();
//设置fetchType为EAGER,发的sql语句把user也取出来了,所以即使session关了,也能取出User(从内存)而不报错
System.out.println(g.getName()+g.getUsers());
} @org.junit.Test
public void testLoadUser(){
testSaveGroup();//生成数据 Session s = sf.getCurrentSession();
s.beginTransaction();
//get拿的是User对象,load,拿的是user的代理对象,
//执行下边的代码不会发sql语句,当getGroup时才发sql语句
User u = (User) s.load(User.class,1); //执行此句时先发出sql语句取user,再发sql语句取user和group,发了2条select
System.out.println(u.getName()+u.getGroup().getName());
s.getTransaction().commit(); } @org.junit.Test
public void testUpdateUser1(){
testSaveGroup();//生成数据 Session s = sf.getCurrentSession();
s.beginTransaction();
/**
* 发的sql语句:
* 因为 u.getName()+u.getGroup().getName()既取了u。name,又取了u.的group的name,所以
* 发的select语句取了user和group,
* Hibernate:
select
user0_.id as id2_1_,
user0_.groupId as groupId2_1_,
user0_.name as name2_1_,
group1_.id as id3_0_,
group1_.name as name3_0_
from
User user0_
left outer join
t_group group1_
on user0_.groupId=group1_.id
where
user0_.id=?
//但是为什么还会发出下边的select 语句呢?因为group的fetchType设的EAGER,
* 在u.getGroup().getName()的同时,也会发sql语句去取user的信息。所以不能同时两边设EAGER
* 一般正常人思维去思考:一般:一对多设lazy,多对一设eager。
* 但是假设一个人有多个权限,可以设一对多为eager。公司机构、部门可以用。
Hibernate:
select
users0_.groupId as groupId1_,
users0_.id as id1_,
users0_.id as id2_0_,
users0_.groupId as groupId2_0_,
users0_.name as name2_0_
from
User users0_
where
users0_.groupId=?
* 可以看到先发的select语句取user和group,又取的user()
*/
User u = (User) s.load(User.class,1);
u.setName("user");
u.getGroup().setName("group");
System.out.println(u.getName()+u.getGroup().getName());
s.getTransaction().commit(); } @org.junit.Test
public void testUpdateUser2(){
testSaveGroup();//生成数据 Session s = sf.getCurrentSession();
s.beginTransaction(); User u = (User) s.get(User.class,1);
s.getTransaction().commit();//关闭session,而u已经在内存中。 u.setName("user");//修改user姓名
u.getGroup().setName("group");//修改group Session s2 = sf.getCurrentSession();
s2.beginTransaction();
s2.update(u); //group和user同时更新,user里cascade起的作用
s2.getTransaction().commit(); }
@org.junit.Test
public void testDeleteUser(){
testSaveGroup();//生成表user:u1 u1.group: g u2.group:g group:g Session s = sf.getCurrentSession();
s.beginTransaction();
User u = (User) s.load(User.class, 1);
// 级联:会把u1删掉,再把u1指向的group:g删了,g删了,他所关联的u2也没了。
//s.delete(u);
//解决办法:先解除关联关系,把u的group设成null,再删除
u.setGroup(null);
s.delete(u);
//用hql:
//s.createQuery(" from User u where u.id = 1");
s.getTransaction().commit();
} @org.junit.Test
public void testDeleteGroup(){
testSaveGroup();//生成表user:u1 u1.group: g u2.group:g group:g Session s = sf.getCurrentSession();
s.beginTransaction(); Group g = (Group) s.load(Group.class,1);
//外键指向g的 user 都会被删掉。如果不想删,可以把User的group都设成null,不过这些数据也就成了垃圾数据。
s.delete(g);
s.getTransaction().commit();
}
}
hibernate关联关系的crud2的更多相关文章
- hibernate关联关系笔记
Hibernate关联关系笔记 单向N:1 * 有连接表:在N方使用<join>/<many-to-one>.1方无需配置与之关联的持久化类. * 没有连接表:在N方使用& ...
- Hibernate关联关系映射
1. Hibernate关联关系映射 1.1. one to one <class name="Person"> <id name="id" ...
- Hibernate 关联关系(一对多)
Hibernate 关联关系(一对多) 1. 什么是关联(association) 1.1 关联指的是类之间的引用关系.如果类A与类B关联,那么被引用的类B将被定义为类A的属性.例如: class B ...
- Hibernate关联关系配置(一对多、一对一和多对多)
第一种关联关系:一对多(多对一) "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系. 一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多. 多对一:从订单的 ...
- Hibernate关联关系之双向1—n
•双向 1-n 与双向 n-1 是完全相同的两种情形 •双向 1-n 需要在1的一端可以访问n的一端,反之依然. 测试实例代码: 实体类: package com.elgin.hibernate.nt ...
- Hibernate关联关系之——单向n-1
1 .单向 n-1 关联只需从n的一端可以访问1的一端 2.域模型: 从Order到Customer的多对一单向关联需要在Order类中定义一个Customer属性,而在Customer类中无需定义存 ...
- hibernate关联关系映射详解
词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间 ...
- hibernate关联关系映射之配置文件
词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间 ...
- Hibernate关联关系之多对多
多对多映射关系 建立多对多单向关联关系 创建Employee类: public class Employee { private Integer empid; //员工编号 private Strin ...
随机推荐
- cron.c
/* $OpenBSD: cron.c,v 1.39 2007/02/18 23:59:03 jmc Exp $ */ /* Copyright 1988,1990,1993,1994 by Paul ...
- MySQL性能调优与架构设计——第11章 常用存储引擎优化
第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ...
- MySQL性能调优与架构设计——第1章 MySQL 基本介绍
第1章 MySQL 基本介绍 前言:作为最为流行的开源数据库软件之一, MySQL 数据库软件已经是广为人知了. 但是为了照顾对MySQL还不熟悉的读者,这章我们将对 MySQL 做一个简单的介绍.主 ...
- 如何查看非自己提交的请求的结果 - 深入浅出Oracle EBS之杂项技术荟萃
如何查看非自己提交的请求的结果定位要找的请求SQL举例:SELECT req.request_id, fcp.user_concurrent_program_name, usr ...
- github的使用经历
首先我打开百度搜索markdown,点击这个在线编辑器,开始编写,如下图: 预览效果如下: 然后打开github的网页登录后,点击下图这个标志: 然后给给要上传的一个命名: 然后选择README 确认 ...
- 三部曲搭建本地nuget服务器(图文版)
下载Demo: 1.新建web的空项目 2.引入nuget包 3.修改配置文件config(可以默认) 运行效果:
- CI-Excel-Generation-Library php导出excel乱码。
修改 private function generate($headers, $data) { $this->set_headers(); $data = " ...
- easyui datagrid fit 属性
fit:true - 自适应大小,填充容器 fitColumns:true - 自动使列适应表格宽度以防止出现水平滚动.
- 【转】Leader-Follower线程模型
上图就是L/F多线程模型的状态变迁图,共6个关键点: (1)线程有3种状态:领导leading,处理processing,追随following (2)假设共N个线程,其中只有1个leading线程( ...
- cnVCL的安装
cnVCL是cnpack组件中的不可视组件库,里面包含很多有用的组件,网址:http://www.cnpack.org/showdetail.php?id=739&lang=zh-cn 安装步 ...