在hibernate中的数据库操作.docx
《在hibernate中的数据库操作.docx》由会员分享,可在线阅读,更多相关《在hibernate中的数据库操作.docx(9页珍藏版)》请在冰点文库上搜索。
在hibernate中的数据库操作
session.save()
把对象持久化,让内存的数据进入缓存,我个人认为相当于数据库中的insert插入
Teachert=newTeacher();
t.setName("s1");
t.setTitle("yy");
t.setDate(newDate());
Configurationcfg=newAnnotationConfiguration();
SessionFactorysf= cfg.configure().buildSessionFactory();
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
sf.close();
session.get()
先从缓存中读取数据,缓存没有就向数据库读取
Configurationcfg=newAnnotationConfiguration();
SessionFactorysf= cfg.configure().buildSessionFactory();
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.get(Teacher.class,1)//get(class,id的值),数据库表必须有相应id值,不然报错,最最主要是它是直接把sql语句传给了t,这点与load不同
system.out.println(t.getName());//若id不匹配就会报错,t.getClass也一样,因为无论如何它都要写sql语句,一写就错了
session.getTransaction().commit();
system.out.println(t.getName());
sf.close();
注意:
system.out.println(t.getName());位置放哪里都没有影响,因为其已经把值直接存到t里面了,虽然缓存commit提交消失,但其t的内存没消失
session.load()
先从缓存中读取数据,缓存没有就向数据库读取
Configurationcfg=newAnnotationConfiguration();
SessionFactorysf= cfg.configure().buildSessionFactory();
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.get(Teacher.class,1)//get(class,id的值),数据库表必须有相应id值,不然报错,它与get不同的是,它只是把代理给了t而已,比较其t.getClass,可以知道,具体调用到t.getName()时,才写SQL语句
system.out.println(t.getName());//id匹配,在数据库中有,那么,commit之前不会报错,之后会报错,因为session关闭,但是t.getClass(),不管id是否匹配,session是否关闭,它都不报错,能显示名字
session.getTransaction().commit();
system.out.println(t.getName());
sf.close();
注意:
system.out.println(t.getName());位置放哪里都没有影响,因为其已经把值直接存到t里面了,虽然session的缓存commit提交消失,但其t的内存没消失,t.getClass()中,load的值与id,commit无关,随时能读取,get的值会受id影响。
猜测:
load把代理的名或者说地址,传给了t,所以不管它session是否关闭,id是否匹配,你只读名字不受影响,但是读数据库sql受id和session影响,否则指不到对应的值。
get和load主要区别是一个直接把sql值传给t,一个只是把代理,后者真正调用才用
session.delete()
从数据库中的delete中可以看出,delete需要有属性来确认,一般我们选用id这个主键属性,所以先用get或load从数据库中读取,再delete删除
@Test
publicvoidtestdelete(){
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.get(Teacher.class,119); //从数据库中找到对应的id.
session.delete(t);
session.getTransaction().commit();
}
session.update()
从数据库中的update可以看出,update是要进行更新的。
查文档,可知,update是把持久态(persistent),变为托管态(detach),即commit()之后,对话关闭再进行,更新。
也可以直接在游离态进行,瞬时态(transist)直接,进行更新,但是没用到的值会为空。
1. @Test
publicvoidUpdate(){
Teachert=newTeacher();
t.setId(4);
t.setName("t3");
t.setTitle("中级");
t.setBirthday(newDate());
t.setZhichen(ZhiChen.B);
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit(); //commit之后成为了detach状态
t.setName("yaya");
Sessionsession2=sf.getCurrentSession();
session2.beginTransaction();
session2.update(t);
session2.getTransaction().commit();
}
和saveorupdate例子一样
2. @Test
publicvoidUpdate(){
Teachert=newTeacher();
t.setId
(1); //这个数据库表中必须有一样的id,这是直接成游离的update,说是更新,其实是把相应那行记录清除(不是整张表)之后,再加上新的内容
t.setName("t2");
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
session.update(t);
session.getTransaction().commit();
}
3.@test
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.load(Teacher.class,1);
t.setName("yayazhi");
//session.update(t); //有没有无影响,相当于存在一个这个update,因为t已经指向session的缓存中,重新设值后,提交后,相当于做了这步
session.getTransaction().commit();
}
只进行局部更新方法有三:
一.annotation中@column(updatable=false)),不推荐
意思是让哪个属性不更新,默认为true.
@Column(updatable=false)
publicStringgetTitle(){
returntitle;
}
publicvoidsetTitle(Stringtitle){
this.title=title;
}
二.hbm.xml中class属性下,加入动态更新
其他一样
三.用hql来写,推荐常用
@Test
publicvoidUpdate2(){
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Queryq=session.createSQLQuery("updateTeachertsett.name='Iloveyaya'wheret.id=1");
q.executeUpdate();
session.getTransaction().commit();
}
这种方法最好,相当于自己写sql语句,比较清楚,注意这时的session操作。
另外,不同session间的局部插入,用到session.merge(),用update()是所有属性加入,因为新session中,原来缓存为空,update自然全部更新,而merge()只是合并,不同合并。
@Test
publicvoidtestmerge(){
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.get(Teacher.class,1); //get直接写入,把sql传给t,但还没入数据库,commit才入,所以commit之后还有
// Teachert=(Teacher)session.load(Teacher.class,33);//load动态代理,只是把一个代理给t,需要时,才具体调用,但commit后,session消失,无法调用
t.setName("yy312");
//其实commit相当于之前已经update过了
session.getTransaction().commit();
t.setName("yy515");
Sessionsession2=sf.getCurrentSession();
session2.beginTransaction();
session2.merge(t);//合并,数据库的数据和内存不一致时,会产生合并,只更新不一致的位置,若为update()这里全部更新
,merge虽然部分更新,但是需要读表一次来比对
session2.getTransaction().commit();
}
session.saveOrUpdate()
saveOrUpdate,系统自动根据自己所写语句,来调用时用save还是update.
@Test
publicvoidtestsaveorUpdate(){
Teachert=newTeacher();
t.setId(119);
t.setName("t2");
t.setTitle("中级");
t.setBirthday(newDate());
t.setZhichen(ZhiChen.B);
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
session.saveOrUpdate(t); //这里相当于save
session.getTransaction().commit();
t.setName("yaya");
Sessionsession2=sf.getCurrentSession();
session2.beginTransaction();
session2.saveOrUpdate(t); //这里相当于update
session2.getTransaction().commit();
}
session.clear()
clear清空缓存,把存入缓存的值清空
@Test
publicvoidtestclear(){
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.load(Teacher.class,3);
System.out.println(t.getName());
// session.clear(); //清除缓存中的值
Teachert2=(Teacher)session.load(Teacher.class,3);
System.out.println(t2.getName());
session.getTransaction().commit();
}
注意,若是没用clear,select语句只读一次,因为第一次缓存为空,用select语句从数据库读取,所以就不用第二次select了.
session.flush()
可以简单理解为,把缓存的值写入数据库中,确切说是数据库缓存中,如果不写,默认commit()提交前,都有个flush(),commit是最后确认写入数据库,还有具体功能,较为复杂,暂不研究。
@Test
publicvoidtestflush(){
Sessionsession=sf.getCurrentSession();
session.beginTransaction();
Teachert=(Teacher)session.get(Teacher.class,3);
t.setName("aa55");
session.flush();
t.setName("sdfsf");
session.getTransaction().commit();
}
SchemaExport
importorg.hibernate.tool.hbm2ddl.SchemaExport;org.hibernate中自建的建表语句,不想用hibernate.cfg.xml中声明那个属性可以自己导。
@Test
publicvoidtestSchemaExport(){
newSchemaExport(newAnnotationConfiguration().configure()).create(false,true);//create有两值,都是boolen,前者为是否写出sql语句,后者是是否写入数据。
}
有个问题:
貌似用了这个之后,就不能插入数据库信息了,没有仔细研究,
问题:
org.hibernate.HibernateException:
getisnotvalidwithoutactivetransaction
session读取值的时候,必须读值要放在session.beginTransaction()之后,不然会报错,只有事务开始了,才能读值。