1. 程式人生 > >Hibernate 再接觸 核心開發接口

Hibernate 再接觸 核心開發接口

ear ans 語句 修改 ransient 就是 新的 nat ati

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 再接觸 核心開發接口