Hibernate 学习笔记2
来源:互联网 发布:java web和前端开发 编辑:程序博客网 时间:2024/06/14 04:26
将Session与本地线程绑定
//由于session是单线程对象 所以实际中一般会把它与线程绑定
//保证它的单线程性
public static Session getCurrentSession(){
return sf.getCurrentSession();
}
这个需要在hibernate.cfg.xml中配置
<!-- 配置将hibernate与本地session绑定 保证session是单线程对象 -->
<property name="hibernate.current_session_context_class">thread</property>
实体类的三种状态:
1. 临时态:(无id 与session无关)
User user =new User();
user.setName(“aaa”);
user.setPwd(“123”);
session.save(user);
2.托管态(有id 与session无关)
User user =new User();
user.setId(2);
session.delete(user)
3.持久态(有id 与session有关)
User user=session.get(User.class,1);
Hibernate缓存:
验证一级缓存(默认打开):
执行过程:(存的不是对象 而是对象值,再以某个值作为这个存储的索引,以便下次的寻找 比如id然后再组装成一个对象返回)
查询只做了一次// 5 具体的crud操作Student stu1=session.get(Student.class, 3);System.out.println(stu1);Student stu2 = session.get(Student.class, 3);System.out.println(stu2);
一级缓存执行过程:
建立一对多 和多对多关系:
都知道数据库中 有一对多和多对多的关系
比如学生对班级 1对多 学生对课程 就是多对多
一共3步骤:
1. 编写实体类
*在1的一方 需要包含多的一方 也就是之间的关联关系
*在多的一方 需要包含另一方Set<>集合也就是之间的聚合关系
2. 配置xx.hbm.xml文件(需要双向配置)
<many-to-onename="cla" column="class_id" class="com.lsy.entity.Class"></many-to-one>
<!--这个many-to-one配置的是它代表与班级之间的 它是多的关系
配置在多的一方
name属性 为Student类中Class的名称
column为表中外键的列名
class 为1的一方的实体类的路径
-->
<setname="stuSet"cascade="save-update">
<keycolumn="class_id">
</key>
<one-to-manyclass="com.lsy.entity.Student"/>
</set>
<!-- 这个set标签配置的是 它与学生之间它是1的关系(记住hibernate里面是双向维护外键不能只单纯只配置一方)
配置cascade属性:后可以少写一部分代码 在做级联保存 添加 这种时可以直接把多的一方 添加少的一方即可
也就是这部分代码:
Studentstu =new Student();
stu.setAge(21);
stu.setName("asdf");
stu.setSex("男");
Classcla=session.get(Class.class, 1);
//cla.getStuSet().add(stu)
stu.setCla(cla);
可以少写注释了的代码 配置后hibernate帮我们封装
key标签配置外键的列名
最后加上一个one-to-many标签 加上多的一方的class
-->
完整配置见之后代码块
学会了一对多的配置后 对于多对多应该看一下就能明白(直接见代码块)
3. 在核心文件中引入最后测试
student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 配置表与实体间的一一对应关系(mapping) --><class name="com.lsy.entity.Student" table="t_student"><!-- 配置主键 --><id name="id" column="id"><!--配置主键生成策略 native表示主键自动增长 --><generator class="native"></generator></id><!-- 配置其他的字段 name 实体类属性名称 column表字段名称 --><property name="name" column="name"></property><property name="sex" column="sex"></property><property name="age" column="age"></property><!--配置1对多(多的一方) --><many-to-one name="cla" column="class_id" class="com.lsy.entity.Class"></many-to-one><!--配置多对多 --><set name="courseSet" table="student_course" cascade="save-update,delete"><key column="stu_id"></key><many-to-many column="course_id" class="com.lsy.entity.Course"></many-to-many></set></class></hibernate-mapping>
Student.java
package com.lsy.entity;import java.util.HashSet;import java.util.Set;public class Student {private Integer id;private String name;private String sex;private Integer age;private Class cla;private Set<Course> courseSet=new HashSet<Course>();public Set<Course> getCourseSet() {return courseSet;}public void setCourseSet(Set<Course> courseSet) {this.courseSet = courseSet;}public Class getCla() {return cla;}public void setCla(Class cla) {this.cla = cla;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}
class.hbm.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.lsy.entity.Class" table="t_class" > <id name="cid" column="id"> <generator class="native"></generator> </id><!-- 配置其他的字段name 实体类属性名称column表字段名称 --><property name="name" column="name"></property><!-- 这个many-to-one 配置的是它代表与系之间的 它是多的关系--> <many-to-one name="dep" column="dep_id" class="com.lsy.entity.Department"></many-to-one><!-- 配置1对多(多的一方): --><set name="stuSet" cascade="save-update,delete"><key column="class_id"></key><one-to-many class="com.lsy.entity.Student"/></set> </class> </hibernate-mapping>
Class.java
package com.lsy.entity;import java.util.HashSet;import java.util.Set;public class Class {private int cid;private String name;private Set<Student> stuSet=new HashSet<Student>();private Department dep;public Department getDep() {return dep;}public void setDep(Department dep) {this.dep = dep;}public int getCid() {return cid;}public void setCid(int cid) {this.cid = cid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Student> getStuSet() {return stuSet;}public void setStuSet(Set<Student> stuSet) {this.stuSet = stuSet;}}
做级联crud的测试代码:
@Testpublic void testOneToMany() {SessionFactory sf = HibernateUtils.getSessionFactory();Session session = sf.openSession();Transaction tran;try {tran = session.beginTransaction();Student stu = new Student();//瞬时态对象stu.setAge(21);stu.setName("asdf");stu.setSex("男");Class cla = session.get(Class.class, 1);stu.setCla(cla);session.save(stu);tran.commit();} catch (Exception e) {e.printStackTrace();} finally {session.close();sf.close();// 真正项目中不用关闭}}@Testpublic void testOneToManyDelete() {SessionFactory sf = HibernateUtils.getSessionFactory();Session session = sf.openSession();Transaction tran;try {tran = session.beginTransaction();Class cla = session.get(Class.class, 1);session.delete(cla);tran.commit();} catch (Exception e) {e.printStackTrace();} finally {session.close();sf.close();}}@Testpublic void testOneToManyUpdate() {SessionFactory sf = HibernateUtils.getSessionFactory();Session session = sf.openSession();Transaction tran;try {tran = session.beginTransaction();Student stu = session.get(Student.class,1);stu.setName("Benjamin");//原本stu的class_id是1 现在想让它是2Class cla = session.get(Class.class, 2);cla.getStuSet().add(stu);stu.setCla(cla);//session.save(stu); 持久态的对象会自动更新 意思不用save 它也会帮你更新tran.commit();} catch (Exception e) {e.printStackTrace();} finally {session.close();sf.close();// 真正项目中不用关闭}}@Testpublic void testManyToMany1() {SessionFactory sf = HibernateUtils.getSessionFactory();Session session = sf.openSession();Transaction tran = session.beginTransaction();try {Student stu = session.get(Student.class, 2);// 持久态对象Course course1 = session.get(Course.class, 1);// 持久态对象Course course2 = session.get(Course.class, 3);stu.getCourseSet().add(course1);stu.getCourseSet().add(course2);session.save(stu);tran.commit();} catch (Exception e) {e.printStackTrace();tran.rollback();} finally {session.close();sf.close();// 真正项目中不用关闭}}@Testpublic void testManyToMany2() {SessionFactory sf = HibernateUtils.getSessionFactory();Session session = sf.openSession();Transaction tran = session.beginTransaction();try {Student stu = new Student();stu.setId(5);stu.setName("jack");stu.setAge(20);stu.setSex("男");Course course1 = new Course();course1.setName("JAVA");course1.setCredit(4);Course course2 = new Course();course1.setName("Python");course1.setCredit(2);stu.getCourseSet().add(course1);stu.getCourseSet().add(course2);session.save(stu);tran.commit();} catch (Exception e) {e.printStackTrace();tran.rollback();} finally {session.close();sf.close();// 真正项目中不用关闭}}
无论是一对多还是多对多做级联保存时 都需要在set 设置cascade 的值为 “save-update”
执行上面的这个测试方法时testOneToManyUpdate()
做修改时有这问题 (他会修改两次 显然有一次是多余的原因是因为双方都维护了外键)
解决方式:为提高性能 会让其中的一方放弃维护外键,一般让一的那一方, inverse属性 值为:false(默认) 代表不放弃 true代表放弃
<!-- 配置1对多(多的一方): -->
<set name="stuSet" cascade="save-update,delete" inverse="true" >
而一对多做删除时 比如删除班级 然后删除此班级的所有学生 可以在cascade 中设置 delete 多个值之间有,逗号分开 调用方法session.delete();
多对多时不需要调用session.delete 而是调用其中一方的Set集合的remove方法 使用delete时除了将第三张表中两对象的ID删除在原来的表中也会删除。
- Hibernate学习笔记2
- Hibernate 学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记(2)
- hibernate学习笔记2
- Hibernate学习笔记(2)
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记2
- Hibernate 学习笔记2
- Hibernate 学习笔记2
- Hibernate学习笔记2
- Hibernate学习笔记(2)
- Hibernate 学习笔记(2)
- mmap内存映射
- Android中设置ListView内容刷新问题
- eclipse 常用插件 整理
- C#上机实验之题目四
- 【R机器学习笔记】XGBoost——XGBboost包
- Hibernate 学习笔记2
- Nginx配置记录
- 单链表的归并排序
- PAT_1032. Sharing(自己的代码最后一个case没过)
- Elasticearch索引mapping写入、查看、修改(head、kopf插件)
- POJ 1698 Alice's Chance 二分图多重匹配 网络最大流
- 1030. 完美数列(25)
- 第一章 USB Type C的基本原理(连载一)
- PL/SQL DeveloperZ中文乱码问题解决