標籤:.com 就是 builds div rup .class hibernate cto context
1.可以重載方法進行設定檔的指定
sessionFactory = new AnnotationConfiguration().configure("hibernate.xml").buildSessionFactory();
這樣讀取到的就是hibernate.xml 但一般不建議修改
getcurrentsession 指的是上下文如果沒有提交 就不會建立新的session
opensession 永遠開啟新的session 用於評鑑事務邊界 比如加入日誌操作等
事務:要麼同時完成,要麼就復原
<property name="current_session_context_class">thread</property>
從當前線程裡找
還有其他幾個參數:
例如 jta ,managed,custorm.class等
thread使用資料庫連結作為交易管理
但是管理不了分散式交易
jta(java trasaction api) 往往用在分布式上
需要一個manager管理對部署在兩個資料庫的操作
如果不設上下文他就無法找到
opensession盡量不要跟getcurrentsession同用 不是同一個session
緩衝就是記憶體中的一塊地區 放著我們想要提高讀取效率的對象
對象的三種狀態
Transient persistent detached
Transient 記憶體有一個對象 但是沒有id 緩衝中也沒有 資料庫也沒有
persistent 記憶體有 緩衝中有 資料庫有 也有id session裡有key和value
detached 記憶體有 緩衝沒有 資料庫有
三種狀態區分在於:
有沒有id
id在資料庫中有沒有
在記憶體中沒有(session緩衝)
session 管理一個資料庫的任務單元 管理增刪改查的操作
save 略
delete
只要有id 包括detach態 就可以delete
例如:
@Test public void testDelete() { Teacher t = new Teacher(); t.setName("t1"); t.setTitle("middle"); t.setBirthDate(new Date()); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); session.save(t); System.out.println(t.getId()); session.getTransaction().commit(); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.delete(t); session2.getTransaction().commit(); } @Test public void testDelete2() { Teacher t = new Teacher(); t.setId(2); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.delete(t); session2.getTransaction().commit(); }
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 是可以自動打包
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()); }
兩者區別:
需要注意的是 get 和load方法有重要區別 load種 是產生一個代理 當真正想使用對象的屬性的時候才會發出sql語句 而get是馬上就發
update
更新detach的一個對象
@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(); }
更新transient 會報錯 但是更新有id的transient不會報錯 (資料庫有對應記錄)
@Test public void testUpdate4() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.get(Teacher.class, 1); t.setName("zhangsan2"); session.getTransaction().commit(); }
以上的更新會更新所有欄位 為提高效率 所以摸索
如何只改想要的欄位
如果是p對象 只要設定欄位 就會發生更新
@Test public void testUpdate5() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Student s = (Student)session.get(Student.class, 1); s.setName("zhangsan5"); session.getTransaction().commit(); //發現對象與資料庫中不同 自動update s.setName("z4"); Session session2 = sessionFactory.getCurrentSession(); session2.beginTransaction(); session2.update(s); session2.getTransaction().commit(); }
但是這種更新還是全部的
要想實現只更新想要更新的欄位
有三種方法:
1.加上column = false屬性
或者xml加入column = false屬性
2.在xml中加入
<class name="com.bjsxt.hibernate.Student" dynamic-update="true">
這樣在資料庫提交的時候就會只更新自己想改的欄位
但是要注意 這個對象一旦在處瑜detach狀態 再提交commit的時候無法作比較 所以就無法更新 所以更新的還是全部欄位
@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);//merge可以合并對象 這樣也不用發多餘的其他欄位的修改 session2.getTransaction().commit(); }
第三種 是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 orupdate
@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(); }
沒有的話就save 有的話就update
clear
無論是load還是get 都會首先尋找緩衝(一級緩衝),如果沒有 ,才會去資料庫尋找,調用clear方法可以強制清除session緩衝
@Test public void testClear() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); System.out.println(t.getName()); session.clear();//如果不加這句話 將只發出一條select sql語句 ,加了之後清除session緩衝下面就需要重新發了 Teacher t2 = (Teacher)session.load(Teacher.class, 1); System.out.println(t2.getName()); session.getTransaction().commit(); }
flush方法
強制讓緩衝內容與資料庫內容同步
具體在什麼時間flush 是由flushmode設定
@Test public void testFlush() { Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); t.setName("tttt"); session.flush(); //強制與資料庫同步,發出update t.setName("ttttt"); session.getTransaction().commit(); //發現不一致 再發出update }
testschemaexport
可以在設定檔中不讓他自動建表
然後自己寫一個類建表
第一個參數這是指是否顯示ddl語句 第二個參數是指是否執行ddl語句
@Test public void testSchemaExport() { new SchemaExport(new AnnotationConfiguration().configure()).create(false, true); }
Hibernate 再接觸 核心開發介面