Hibernate学习笔记2.5(Hibernate核心开发接口和三种状态)
1.configuration(配置信息管理,产生sessionfactory)
sessionfactory管理一系列的连接池
opensession 永远打开新的,需要手动close
getcurrentsession如果当前环境有,就会用已经存在的,没有就创建新的
一旦提交就没了
getcurrentsession主要用于界定事务边界,事务提交自动close
上下文:在hibernate.cfg.xml里面改 currentsession_context_class
thread:线程 当前线程有没有一个对象,没有就创建i新的,使用connection
jta: 分布式事务 ,Java tarsaction api多数由中间键服务器提供 Tomcat不具备该能力
manager:手动管理事务
custormclass:自己定义
如果使用getcurrentsession必须设定上下文环境
geucurrentsession和sessionopen拿到的类 具体实现可能不一样 因此一般情况下 不建议混用
如果址用hibernate 就要写trycatch
用spring的话就不用写try catch
save();设定一个主键,id
首先搞懂三种状态
三种状态
transient :内存中的一个对象 缓存中没有对应的id和value
Persistent:内存中有 缓存中有 数据库有 有id
Datached: 内存有 缓存没有 数据库有 有id
save方法即是把transient转化为Persisitence
delete方法
Load
@Test public void testLoad() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); session.getTransaction().commit(); System.out.println(t.getClass()); //System.out.println(t.getName()); }
1,自动打包为intege 实现了序列化接口
get
@Test public void testGet() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.get(Teacher.class, 1); session.getTransaction().commit(); System.out.println(t.getClass()); //System.out.println(t.getName()); }
用load拿出东西的时候才会发出sql语句,不存在对应记录不拿东西不会报错,返回代理对象()
用get拿出对象的时候是直接在数据库加载,不存在对应记录不拿东西也会报错
update
第一种 有detach到persistence 同时数据库更新
@Test public void testUpdate1() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.get(Teacher.class, 1); session.getTransaction().commit(); t.setName("zhanglaoshi"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.update(t); session2.getTransaction().commit(); }
更新trasent会报错
如果transent设置id数据库并且存在
数据库得有对应的记录
@Test public void testUpdate2() { Teacher t = new Teacher(); t.setName("zhanglaoshi"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.update(t); session2.getTransaction().commit(); }
如果有一个字段特别长 全改就会变低
Load的时候自动会检查缓存是否与数据库一致 如果不一致 就会发update语句 ,所有字段均会更新,如果相同,不会更改
@Test public void testUpdate4() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.get(Teacher.class, 1); t.setName("zhangsan2"); session.getTransaction().commit(); }
想要只更改一条想要更改的内容
1.加注解(很少用 不够灵活)
anntation
@Column(updatable = false) public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }
xml:
property属性 update 设置true或者false
2.在xml配置文件上写
<hibernate-mapping> <class name="com.bjsxt.hibernate.Student" dynamic-update="true">
设置之后在同一个session之后就只更新只更改改的那一部分
跨session的话
@Test public void testUpdate5() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Student s = (Student)session.get(Student.class, 1); s.setName("zhangsan5"); session.getTransaction().commit(); s.setName("z4"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.update(s); session2.getTransaction().commit(); }
他会全部发送,全部更改
如果想要跨session,可以使用merge方法
@Test public void testUpdate6() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Student s = (Student)session.get(Student.class, 1); s.setName("zhangsan6"); session.getTransaction().commit(); s.setName("z4"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.merge(s); session2.getTransaction().commit(); }
在update之前会先搜索一下 比较是否相同
3.使用hql语句
@Test public void testUpdate7() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Query q = session.createQuery("update Student s set s.name='z5' where s.id = 1"); q.executeUpdate(); session.getTransaction().commit(); }
Save or update
@Test public void testSaveOrUpdate() { Teacher t = new Teacher(); t.setName("t1"); t.setTitle("middle"); t.setBirthDate(new Date()); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.saveOrUpdate(t); session.getTransaction().commit(); t.setName("t2"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.saveOrUpdate(t); session2.getTransaction().commit(); }
没id就save 有id就update
Clear方法
@Test public void testClear() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); System.out.println(t.getName()); //first session.clear(); Teacher t2 = (Teacher)session.load(Teacher.class, 1); //second System.out.println(t2.getName()); session.getTransaction().commit();
clear用于清除缓存,load和get方法都会先查找缓存,有的话就不会发sql语句
Flush
@Test public void testFlush() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); t.setName("tttt"); t.setName("ttttt"); session.getTransaction().commit(); }
如果不加flush的话 他永远只取一次,取最后的
@Test public void testFlush() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); t.setName("tttt"); session.flush(); t.setName("ttttt"); session.getTransaction().commit(); }
加了flush之后可以强制缓存的内容与数据库的内容做同步
commit方法默认执行flush
在什么时间执行flush由flushmode控制
在前面设置 session.setFlushMode(FlushMode.xxxx)
find方法很老 现在也不怎么用了
SkemaExport
@Test public void testSchemaExport() { new SchemaExport(new AnnotationConfiguration().configure()).create(false, true); }
控制建表语句