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. 四则运算生成器(java) 蔡苑菲,陆海燕

    github地址:https://github.com/Nancy0611/Myapp.git 一.项目相关要求 使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n 10 将生成10个 ...

  2. [leetcode] 5. Minimum Depth of Binary Tree

    二叉树基本功练习题,题目如下: Given a binary tree, find its minimum depth. The minimum depth is the number of node ...

  3. Oracle索引技术研究

    Oracle索引类型 B树索引 特定类型索引 确定索引列 主键和唯一键值列的索引 外键索引 其他合适的索引列 B树索引 B树索引算法 B树是指B-tree(Balanced Tree),B树的存在是为 ...

  4. TSQL--SQL SERVER 常用系统变量

    ----------全局变量select @@version as '版本';---------------------------返回当前数据库的版本信息 select APP_NAME ( ) a ...

  5. .Net WebApi部署问题

    在IIS上部署web api 完成后,浏览时出现了“The compiler failed with error code -2146232576.”的错误(有时会出现这个情况).主要是 我们在.Ne ...

  6. lambda 、 map 、filter 、reduce 及 reversed 常用函数

    lambda 匿名函数 什么是lambda? lambda 操作符(或 lambda 函数)通常用来创建小巧的,一次性的匿名函数对象.它的基本语法如下: lambda arguments : expr ...

  7. “全栈2019”Java异常第八章:throw关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  8. oracle根据四位年周取当周周一的日期函数

    create or replace function FUNC_GET_DATE_BY_WEEK( theYearWeek IN VARCHAR2)return date is normalDate ...

  9. LNMP搭建流程

    参考张宴的nginx搭建流程. http://zyan.cc/nginx_php_v6/

  10. jmeter+ant+jenkins+mac报告优化(一):解决Min Time和Max Time显示NaN

    一.在上篇博客中生成的报告有两个问题: 1.date not defined 2.Min Time和Max Time显示成了NaN 二.Jmeter+Ant报告生成原理: 1.在Jmeter的extr ...