web进修之—Hibernate CRUD(2)
概述
在使用 Hibernate
进行编程的时候,我们主要还是和Session打交道,在进行CRUD的时候要现获取 Session
,主要方法如下
- C:增加, save
, persist
, saveOrUpdate
- R:读取, get
, find
, load
, Query
- U:更新, update
- D:删除, delete
对象的三种状态
在进行介绍Hibernate操作之前,有必要先熟悉一下Hibernate对象的三种状态:
- 瞬时状态(transient
)
- 持久状态(persistent
)
- 脱管状态(detached
)
三个状态之间的转换关系如下:
结合上面的图,我们说明各个状态的特点
瞬时状态
首先需要明确的是这几种状态都是指的对象,该对象 在数据库中没有对应的记录 就是瞬时状态。
持久状态
由session管理,但不一定在数据库中有记录(如果提交事务之后就有)。
脱管状态
脱离了session的管理,但是在数据库中有对应的记录
总结上面的介绍我们发现,区分这三种状态主要是看对象和session、数据库的关系。
增加
把数据库保存到数据的方法主要是save(),persist(),saveOrUpdate(),三者之间的使用区别如下:
- save在事务外部被调用的时候有可能会执行一个数据库插入操作也可能不会,但是保证可以访问到id;
- persist在事务外部被调用的时候保证不触发一个数据库插入操作,但是不一定能访问到id;
- saveOrUpdate是指在不清楚数据库是否存在该对象的时候可以使用该方法,Hibernate后自行判断。
一个获取Session的工具类
public class HibernateUtil {
private static SessionFactory sessionFactory;
// 不允许new,保证只有一个sessionFactory
private HibernateUtil(){}
static {
Configuration cfg = new Configuration();
cfg.configure();
sessionFactory = cfg.buildSessionFactory();
}
public static Session getSession(){
return sessionFactory.openSession();
}
public void closeSessionFactory(){
if(sessionFactory != null){
sessionFactory.close();
}
}
}
保存对象的方法
/**
* 保存一个video对象
* @param video
*/
public void save(Video video){
Session session = null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
session.save(video);
// session.persist(video);
// session.saveOrUpdate(video);
session.getTransaction().commit();
} finally {
if(session != null){
session.close();
}
}
}
删除
/**
* 删除一个video
* @param video
*/
public void delete(Video video){
Session session = null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
session.delete(video);
session.getTransaction().commit();
} finally {
if(session != null){
session.close();
}
}
}
修改
/**
* 更新一个video
* @param video
*/
public void update(Video video){
Session session = null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
session.update(video);
// session.saveOrUpdate(video);
session.getTransaction().commit();
} finally {
if(session != null){
session.close();
}
}
}
查询
- get,load,根据id查询单个对象
- criteria,条件查询
- HQL,比上面两个都全面,可以满足所有查询
/**
* 查询所有的video
* 注意hql是一种面向对象的查询语句,也就是说查询的是对象也不是数据库中的表
* @return 返回所有的video对象
*/
public List<Video> findAll(){
Session session = null;
try{
session = HibernateUtil.getSession();
String hql = "from Video";
org.hibernate.Query query = session.createQuery(hql);
return (List<Video>)query.list();
} finally {
if(session != null){
session.close();
}
}
}
/**
* 根据id查找video
* @param id
* @return
*/
public Video findById(long id){
Session session = null;
try{
session = HibernateUtil.getSession();
// session.get(Video.class, id);
// session.load(Video.class, id); // 使用load会有懒加载的问题
// Criteria criteria = session.createCriteria(Video.class);
// criteria.add(Restrictions.eq("id", id));
// Video video = (Video)criteria.uniqueResult();
String hql = "from Video where id=:id";
org.hibernate.Query query = session.createQuery(hql);
query.setLong("id", id);
return (Video)query.uniqueResult();
} finally {
if(session != null){
session.close();
}
}
}
测试代码
public class TestCrud extends TestCase {
private VideoDao dao;
@Override
public void setUp() throws Exception {
dao = new VideoDao();
}
@Override
public void tearDown() throws Exception {
super.tearDown();
HibernateUtil.closeSessionFactory();
dao = null;
}
@Test
public void test(){
// 测试添加
String name = "1.avi";
Video v1 = new Video();
v1.setName(name);
v1.setUrl("http://200007041.vod.myqcloud.com/2009c79e6bd.f20.mp4");
dao.save(v1);
// 测试查询一个
Video video = dao.findById(1);
System.out.println(video);
assertEquals(video.getName(), name);
// 测试查询多个
List<Video> list = dao.findAll();
for(Video v : list){
System.out.println(v.toString());
}
assertEquals(list.size(), 1);
// 测试修改
String newName = "2.avi";
video.setName(newName);
dao.update(video);
Video newVideo = dao.findById(1);
System.out.println(newVideo);
assertEquals(video.getName(), newVideo.getName());
}
}
总结
在Hibernate的CRUD中关键理解了对象的三种状态之后就可以合理选用各个方法。
遗留问题
- HQL的深入学习
- 懒加载
参考文章:
特别感谢以上文章的作者,如若有冒犯或者侵权的地方,请及时联系本人修改。