核心接口开发 (重点)
一, Configuration
a) AnnotationConfiguration
b) 进行配置信息的管理
c) 用来产生SessionFactory
d) 可以在configure方法中指定hibernate配置文件
e) 只关注一个方法即:buildSessionFactory
二, SessoinFactory
a) 用来产生和管理Session
b) 通常情况下每个应用只需要一个SessionFactory
c) 除非要访间多个数据库的情况
d) 关注两个方法即:openSession getCurrentsession
i. open session每次都是新的,需要close
ii. getCurrentsession从上下文找,如果有,用旧的,如果没有,建新的
-
- 用途,界定事务边界
- 事务提交自动close
- 上下文配置可参见xml文件中
thread
4.current_session_context_class (jta、thread常用 managed、custom.Class少用)
a) thread 使用connection 单数据库连接管理事务
b)jta (全称java transaction api)-java分布式事务管理(多数据库访问)
jta由中间件提供(jboss WebLogic等,tomcat不支持)
三, Session
a) 管理一个数据库的任务单元(简单说就是增 删 改 查)
b) 方法(CRUD)
i. Save()
@Test public void testTeacherSave() { Teacher t = new Teacher(); t.setName("t1"); t.setTitle("middle"); t.setBirthDate(new Date()); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.save(t); session.getTransaction().commit(); }
ii. delete
@Test public void TestDelete2(){ Teacher t = new Teacher(); t.setId(1); Session session2=sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.delete(t); session2.getTransaction().commit(); }
iii. load
@Test public void TestLoad(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.load(Teacher.class, 2); System.out.println(teacher.getName()); session.getTransaction().commit(); }
iv. get
@Test public void TestGet(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.get(Teacher.class, 2); System.out.println(teacher.getName()); session.getTransaction().commit(); }
v. get与load的区别
-
- 不存在对应记录时表现不一样
- load返回的是代理对象,等到真正用到对象的内容时才发出sql语句
- get直接从数据库加载,不会延迟
@Test public void TestLoad(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.load(Teacher.class, 2); session.getTransaction().commit(); System.out.println(teacher.getName());//会报错,因为此时已经不能进行sql查询 }
@Test public void TestGet(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.get(Teacher.class, 2); session.getTransaction().commit(); System.out.println(teacher.getName());//不会报错,因为get方法直接把从数据库拿的对象给了teacher }
vi. updates
@Test public void TestUpdate2(){ Teacher teacher=new Teacher(); teacher.setId(5); teacher.setName("ahhah"); Session session2=sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.update(teacher); session2.getTransaction().commit(); }
- 用来更新detached对象,更新完成后转为persistent状态
- 更新transient对象会报错
- 更新自己设定id的transient对象可以(数据库有对应记录)
- persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新
- 更新部分更改的字段
a) xml 设定 property 标签的 update 属性,annotation 设定@Column 的 updatable
属性,不过这种方式很少用,因为不灵活
b) 使用xml中的dynamic-update,JPA1.0 Annotation 没有对应的属性,hibernate 扩
展?
hibernate-mapping>
i. 同一个session可以,跨session不行,不过可以用merge()(不重要)
@Test public void TestUpdate5(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Student s=(Student)session.get(Student.class, 2); s.setName("xiaoming");//只更新name字段 session.getTransaction().commit(); s.setName("san"); Session session2=sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.merge(s);//如果是s.update(s),会全部更新 session2.getTransaction().commit(); }
c) 使用 HQL(EjBQL)(建议)
@Test public void TestUpdate6(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Query query=session.createQuery("update Student s set s.name='hhah' where s.id=1"); query.executeUpdate(); session.getTransaction().commit(); }
vii. saveOrUpdate()
@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); System.out.println(t.getId()); session.getTransaction().commit(); t.setName("t2"); Session session2=sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.saveOrUpdate(t); session2.getTransaction().commit(); }
viii. clear方法
1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找,调用
clear()方法可以强制清除session缓存
@Test public void TestClear(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.load(Teacher.class, 2); System.out.println(teacher.getName()); session.clear(); Teacher teacher2=(Teacher)session.load(Teacher.class, 2); System.out.println(teacher2.getName()); session.getTransaction().commit(); }
ix. flush()方法
- 当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!
@Test public void TestFlush(){ Session session=sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher teacher=(Teacher)session.load(Teacher.class, 2); teacher.setName("ttt"); session.flush(); teacher.setName("tttt"); session.getTransaction().commit(); }
2.session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)
例如: session.setFlushMode(FlushMode.AUTO)
四, SchemaExport (自动建表)
@Test public void TestSchemaExport(){ new SchemaExport(new AnnotationConfiguration().configure()).create(true, true); }
三种对象状态(了解)
1 三种状态的区分关键在于
a) 有没有ID
b) ID在数据库中有没有
c) 在内存中有没有(session缓存)
2 三种状态:
a) transient:内存中一个对象,没ID,缓存中也没有(没有key为id的指向Teacher对象的key-value)
b) persistent:内存中有,缓存中有,数据库有(ID)
c) detached:内存有,缓存没有,数据库有,ID
3 对这三种状态需要关注的问题是在该状态下如果进行数据库的操作会发生什么结果,比 如改变属性的
值会不会发出update语句?
a) 强烈建议动手实验
b) 进行正常人的思考
c) 绝对不要去背这些东西!背过也并不代表你有多牛!