1.Hibernate对象的三种状态
瞬时态:瞬时态的对象是由new关键字开辟内存空间的对象,不存在在持久化标识OID(相当
于主键值),并且与任何session关联
在数据库中也没有记录,失去引用将会被JVM回收
持久态:持久态的对象存在一个持久化标识OID,当对象加入到session缓存时,就会和session的实例对象关联。
注意:的是持久和对象是在事务还未提交前变成持久态的
脱管|游离态:脱管态的对象是当持久态对象与session断开时就变成脱管态
注意:上述是正常情况,如果瞬时态直接给一个数据库存在的OID标识而未关联session对象则还是脱管态
2.Hibernate的一级缓存和快照
2.1一级缓存是hibernate的内置缓存其实就是session缓存,session缓存是一块内存空间,用于存放和管理Java对象。
在使用Hibernate查找对象时首先会使用对象的OID值在Hibernate的一级缓存中寻找如果没有再去数据库中查询相应的数据
从而减少HIbernate对数据库访问的次数。
2.2
当程序调用session接口的save()、update()、saveOrUpdate 时
当程序调用load(),get()方法,以及query接口的list(),iterator()方法时
会去查询session缓存中有没有相应的对象,在决定去不去数据库查询,查询数据库的数据加入一级缓存
session调用close()方法时session缓存会清空,session.flush()方法数据刷入数据库
Hibernate 快照
Hibernate向一级缓存存入数据时会复制一份放入快照
快照的作用是在判断数据在数据库取出和存入数据库(调用session的commit()方法)时比较数据是否发生改变
如果改变则执行update的语句反之则不执行
3Hibernate的关联关系的映射
一对一:在任意一方引入对方的主键作为外键
一对多:在“多”的一方,添加“一”的一方的主键作为外键。
多对多:产生中间关系表,分别引入两张表的主键作为外键,两个主键成为联合主键
反转操作(inverse)
使某一方的放弃管理双方的关联关系
实体类
User类
public class Users { private Integer id; private String username; private Integer age; private String gender; private ClassRoom classroom; private Setcourse = new HashSet<>(); public Users() {} public Users(String username) { super(); this.username = username; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public ClassRoom getClassroom() { return classroom; } public void setClassroom(ClassRoom classroom) { this.classroom = classroom; } public Set getCourse() { return course; } public void setCourse(Set course) { this.course = course; } }
ClassRoom类
public class ClassRoom { private Integer class_id; private String class_name; private Integer number; private Setuser = new HashSet<>(); public Set getUser() { return user; } public void setUser(Set user) { this.user = user; } public Integer getClass_id() { return class_id; } public void setClass_id(Integer class_id) { this.class_id = class_id; } public String getClass_name() { return class_name; } public void setClass_name(String class_name) { this.class_name = class_name; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; }
Course类
public class Course { private Integer course_id; private String course_name; private Setuser = new HashSet<>(); public Integer getCourse_id() { return course_id; } public void setCourse_id(Integer course_id) { this.course_id = course_id; } public String getCourse_name() { return course_name; } public void setCourse_name(String course_name) { this.course_name = course_name; } public Set getUser() { return user; } public void setUser(Set user) { this.user = user; }}
1.一对多
配置文件:
一的一方:
多的一方
多对多
另一方配置也就相反
一对多
@Test //创建 public void add() { Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); //准备对象 Users u1 = new Users(); u1.setUsername("xjh"); u1.setAge(14); u1.setGender("女"); Users u2 = new Users(); u2.setUsername("tjl"); u2.setAge(16); u2.setGender("女"); ClassRoom room = new ClassRoom(); room.setClass_name("14sss"); room.setNumber(27); //建立关系 u1.setClassroom(room); u2.setClassroom(room); //如果配置inverse则无需写 /*room.getUser().add(u1); room.getUser().add(u2);*/ //保存 session.save(room); session.save(u1); session.save(u2); tx.commit(); }
@Test //修改 //将其中的一个人换一个班级 public void move() { Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Users users = session.get(Users.class, 1); ClassRoom classRoom = session.get(ClassRoom.class, 1); //先解除关系 classRoom.getUser().remove(users); users.setClassroom(null); ClassRoom room = new ClassRoom(); room.setClass_name("1488"); room.setNumber(27); //设置新关系 users.setClassroom(room);// room.getUser().add(users); session.save(room); tx.commit(); }
1 //删除 2 @Test 3 public void remove() { 4 Session session = HibernateUtils.getCurrentSession(); 5 Transaction tx = session.beginTransaction(); 6 Users users = (Users) session.createCriteria(Users.class) 7 .add(Restrictions.eq("username", "tjl")) 8 .uniqueResult(); 9 // ClassRoom classRoom = session.get(ClassRoom.class, 1);10 // classRoom.getUser().remove(users);11 users.setClassroom(null);12 13 session.delete(users);14 15 tx.commit();16 17 }
多对多
1 @Test 2 public void init() { 3 Session session = HibernateUtils.getCurrentSession(); 4 Transaction tx = session.beginTransaction(); 5 Users u1 = session.get(Users.class,1); 6 Course c1 = new Course(); 7 c1.setCourse_name("语文"); 8 Course c2 = new Course(); 9 c2.setCourse_name("英语");10 11 u1.getCourse().add(c1);12 u1.getCourse().add(c2);13 session.save(u1);14 session.save(c1);15 session.save(c2);16 tx.commit();17 }
1 @Test 2 //为某个学生添加课程 3 public void add() { 4 Session session = HibernateUtils.getCurrentSession(); 5 Transaction tx = session.beginTransaction(); 6 session.get(Users.class, 2) 7 .getCourse() 8 .add((Course) session.createCriteria(Course.class) 9 .add(Restrictions.eq("course_name", "语文"))10 .uniqueResult());11 tx.commit();12 }
1 @Test 2 //删除学生的一门课 3 public void remove() { 4 Session session = HibernateUtils.getCurrentSession(); 5 Transaction tx = session.beginTransaction(); 6 Users user = (Users) session.createCriteria(Users.class) 7 .add(Restrictions.eq("username", "xjh")) 8 .uniqueResult(); 9 user.getCourse()10 .remove(session.createCriteria(Course.class)11 .add(Restrictions.eq("course_name", "语文"))12 .uniqueResult());13 tx.commit();14 }