Hibernate---增删改查以及三种状态的转换

增删改查API:

增:session.save()

删:session.delete()

改:session.update()

查:session.get()或session.load()

使用这些API能完成数据库的增删改查,不过Hibernate拥有强大的缓存机制可以跳过这些API完成增删改查。

首先,我们需要了解在Hibernate中的三种状态:

1.瞬时状态     2.持久化状态    3.托管状态

这三种状态与session的缓存有着密切关系

瞬时状态就是刚new出来一个对象,还没有被保存到数据库中,持久化状态就是已经被保存到数据库中,托管状态就是数据库中有,但是session中不存在该对象,区分是否在数据库之中的关键词是是否有对应的主键。

public void First() {

Configuration configure = new Configuration().configure();

SessionFactory SessionFactory = configure.buildSessionFactory();

Session session = SessionFactory.openSession();

Transaction Transaction = session.beginTransaction();
	//增加一个班级
	ClassRoom room=new ClassRoom();
	room.setClassname("3班");
	//这里是瞬时状态
    session.save(room);
    //room进入session缓存中,与session关联
    room.setClassname("2班");
Transaction.commit();
session.close();
//session关闭,清理缓存room与session失去联系,变为托管状态
room.setClassname("4班");
}

这个程序说明了三种状态的变化,那么程序执行的结果是什么?

控制台输出的sql语句是

Hibernate: insert into ClassRoom (classname) values (?)
Hibernate: update ClassRoom set classname=? where cid=?

数据库进行了save和update操作。

运行结果是

程序运行的流程:

执行

ClassRoom room=new ClassRoom();
	room.setClassname("3班");
	//这里是瞬时状态

session.save(room);

处于瞬时状态的room,通过session.save()方法进入session缓存,同时session还为room对象进行了copy放入快照区。

room.setClassname("2班");
Transaction.commit();

room改变classname属性,事务提交,开始进行数据库操作。首先先在数据库insert快照区的room对象,然后再比较缓存区和快照区之间的是否有改变,如果有改变则进行update操作修改。

session.close();
//session关闭,清理缓存room与session失去联系,变为托管状态
room.setClassname("4班");

事务提交后,关闭session,session的缓存也得之清理,room失去了与session的联系,由持久化状态变为托管状态。

之后room对象无论进行什么操作都与session无关,自然和数据库操作无关。

结论:对象是持久化状态与对象是否进入session缓存区有关。

关于session的缓存有以下几个重要API:

session.clear()    session.evirt()    session.flush()

session.clear()就是清除session的所有缓存:

Session session = SessionFactory.openSession();

Transaction Transaction = session.beginTransaction();
	ClassRoom room=new ClassRoom();
	room.setClassname("3班");
    session.save(room);
    session.clear();
    //这一步之后,session清理了缓存,room直接变成了托管状态
    room.setClassname("2班");
Transaction.commit();
session.close();

执行结果是:

简单的查找操作:

public void Search() {
		Configuration configure = new Configuration().configure();

		SessionFactory SessionFactory = configure.buildSessionFactory();

		Session session = SessionFactory.openSession();

		Transaction Transaction = session.beginTransaction();
			ClassRoom room=session.get(ClassRoom.class, 1);//类对象类属性,id值
			System.out.println(room.toString());
		Transaction.commit();
		session.close();
}
结果:
Hibernate: select classroom0_.cid as cid1_0_0_, classroom0_.classname as classnam2_0_0_ from ClassRoom classroom0_ where classroom0_.cid=?
ClassRoom [cid=1, classname=1班]

删除操作:

数据库: 目标是删去多余的三班

public void Delete() {
		Configuration configure = new Configuration().configure();

		SessionFactory SessionFactory = configure.buildSessionFactory();

		Session session = SessionFactory.openSession();

		Transaction Transaction = session.beginTransaction();
			ClassRoom room=session.get(ClassRoom.class, 4);//类对象类属性,id值
			session.delete(room);
		Transaction.commit();
		session.close();
}

熟悉了Hibernate的缓存机制可以知道update操作交由持久化状态处理相当的方便,那么update方法是否显得多余。

update有一个重要的操作就是 将托管状态转化为持久态。

三种状态转化图:


update演示:

当前数据库:     目标将多余的3班改为4班

public void update() {
		Configuration configure = new Configuration().configure();

		SessionFactory SessionFactory = configure.buildSessionFactory();

		Session session = SessionFactory.openSession();

		Transaction Transaction = session.beginTransaction();
			ClassRoom room=new ClassRoom();
			room.setCid(5);//设置了id,room为托管状态
			session.update(room);//由此room变为了持久化状态
			room.setClassname("4班");
		Transaction.commit();
		session.close();
}

执行结果:

Hibernate: update ClassRoom set classname=? where cid=?


上面讲的查询方法操作过于单一,下面介绍高级的查询方法。

HQL查询,HQL是hibernate专门用于查询数据的语句,有别于SQL,HQL跟接近于面向对象的思维方式。 

@Test
public void Query() {
	Configuration configure = new Configuration().configure();

	SessionFactory SessionFactory = configure.buildSessionFactory();

	Session session = SessionFactory.openSession();

	Transaction Transaction = session.beginTransaction();
		org.hibernate.Query query=session.createQuery("from ClassRoom where classname=?");
		query.setString(0, "3班");
		ClassRoom Result = (ClassRoom) query.uniqueResult();
		System.out.println(Result);
	Transaction.commit();
	session.close();
}
执行结果:
Hibernate: select classroom0_.cid as cid1_0_, classroom0_.classname as classnam2_0_ from ClassRoom classroom0_ where classroom0_.classname=?
ClassRoom [cid=3, classname=3班]


使用Criteria进行数据查询:Criteria 完全是面对对象在进行数据查询,将不再看到有sql语句的痕迹

@Test
public void Criteria() {
	Configuration configure = new Configuration().configure();

	SessionFactory SessionFactory = configure.buildSessionFactory();

	Session session = SessionFactory.openSession();

	Transaction Transaction = session.beginTransaction();
		org.hibernate.Criteria cr= session.createCriteria(ClassRoom.class);
		List<ClassRoom> classrooms = cr.list();
		for(ClassRoom room:classrooms) {
			System.out.println(room);
		}
	Transaction.commit();
	session.close();
}

执行结果:

Hibernate: select this_.cid as cid1_0_0_, this_.classname as classnam2_0_0_ from ClassRoom this_
ClassRoom [cid=1, classname=1班]
ClassRoom [cid=2, classname=2班]
ClassRoom [cid=3, classname=3班]
ClassRoom [cid=5, classname=4班]




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值