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的更多相关文章

  1. hibernate关联关系笔记

    Hibernate关联关系笔记 单向N:1 *  有连接表:在N方使用<join>/<many-to-one>.1方无需配置与之关联的持久化类. *  没有连接表:在N方使用& ...

  2. Hibernate关联关系映射

    1.  Hibernate关联关系映射 1.1.  one to one <class name="Person"> <id name="id" ...

  3. Hibernate 关联关系(一对多)

    Hibernate 关联关系(一对多) 1. 什么是关联(association) 1.1 关联指的是类之间的引用关系.如果类A与类B关联,那么被引用的类B将被定义为类A的属性.例如: class B ...

  4. Hibernate关联关系配置(一对多、一对一和多对多)

    第一种关联关系:一对多(多对一) "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系. 一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多. 多对一:从订单的 ...

  5. Hibernate关联关系之双向1—n

    •双向 1-n 与双向 n-1 是完全相同的两种情形 •双向 1-n 需要在1的一端可以访问n的一端,反之依然. 测试实例代码: 实体类: package com.elgin.hibernate.nt ...

  6. Hibernate关联关系之——单向n-1

    1 .单向 n-1 关联只需从n的一端可以访问1的一端 2.域模型: 从Order到Customer的多对一单向关联需要在Order类中定义一个Customer属性,而在Customer类中无需定义存 ...

  7. hibernate关联关系映射详解

    词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间 ...

  8. hibernate关联关系映射之配置文件

    词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间 ...

  9. Hibernate关联关系之多对多

    多对多映射关系 建立多对多单向关联关系 创建Employee类: public class Employee { private Integer empid; //员工编号 private Strin ...

随机推荐

  1. Echarts.js使用

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>EC ...

  2. Linux umask权限

    文件基本权限 Linux中文件权限由三部分组成: rw-r--r-- 前三位:表示用户所拥有的权限 中三位:表示用户所在组的权限 后三们:表示其他用户的权限 权限 八进制 十进制 - - - 000 ...

  3. [美国代购] Nexus 6 与 Moto X 询价聊天记录整理

    目前手上使用的是 Mi 3,使用了根本还不到一年,但是发现非常多的问题. 官方 APP 不能卸载: 手机的顶部(摄像头)处经常出现高温度现象,如果你长时间讲电话,那么这个温度真的可以烫到你的耳朵无法承 ...

  4. Mirth Connect的简单使用

    第一步: 切换到Channels界面,右键点击New Channel 第二步 : 上面是设置一些通道信息. 其中summary(概要) 界面主要包含 通道名称,数据类型,依赖,通道初始状态,附件(是否 ...

  5. 深夜配置一把struts2

    在intellij idea里面配置出来了struts2的一个Helloworld,因为换了工具,在网上查了很多关于IDEA配置它的方式,好多是用Maven解决依赖关系的.于是按照网上的来,发现很多东 ...

  6. java 封装返回json数据

    做的东西,一直是用easyui的,和后台的交互数据都是json格式的. 今天想要单独弄一个json数据返回给前台,其实是比较简单的问题,json接触不多,记录一下. 代码: public static ...

  7. 在TFS 2013的迭代视图中修改工作项数目限制

    当TFS迭代中的工作项数目超过500时,在TFS的网页(Web Access)显示中就会出现红色警告提示"积压工作(backlog)中的项数超出配置的限制500.当前总数为529-.&quo ...

  8. Hibernate 之核心接口

    1.持久化和ORM 持久化是指把数据(内存中的对象)保存到可持久保存的存储设备中(如硬盘),主要应用于将内存中的数据存储到关系型数据库中,在三层结构中,持久层专注于实现系统的逻辑层面,将数据使用者与数 ...

  9. asp.net core部署到iis

    asp.net core项目部署到IIS稍微不同于之前,记录几个要点: 一.下载安装.NET Core 托管捆绑包,下载地址,这个链接或许不是最新的了,官方文档里面有这个链接,到下图所示位置即可找到. ...

  10. [mvc]记一次“项目”的历程

    大二上半学期因为选修课的原因,答应帮老师完善学院的选课系统.在这之前没有做过一个可以成为“项目”的项目,本着挑战自己的原则和可以不上选修课的福利,断断续续用了一学期的时间来完善这个选课系统. 接受这个 ...