hibernate 基本操作

一、創建SessionFactory的兩種方式:(將下面其中一種封裝成getSessionFactory方法)
1、通過進行創建Configuration:

        //創建配置對象
        Configuration cfg=new Configuration();
        cfg.configure("hibernate.cfg.xml");

        //創建session工廠
        return cfg.buildSessionFactory();
        
2、通過服務註冊類實現

        StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                                                                        .configure("hibernate.cfg.xml")
                                                                        .build();
        SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

 

二、創建一個Main測試類:

public static void main(String[] args) {
    //獲取session工廠
    SessionFactory factory = getSessionFactory();
    //打開一個新的session
    Session session=factory.openSession();
    //開始事務
    Transaction t=session.beginTransaction();

    //這裏寫操作數據庫的代碼(下面的測試代碼均在此處寫)

    //提交事務
    t.commit();
    //關閉session
    session.close();
    //關閉session工廠
    factory.close();
}

三、測試保存或更新api

   Integer index = (Integer)session.save(employee);//返回數據庫中的主鍵Id
   session.persist(employee);//沒有返回值
   Object o = session.merge(employee);//返回整個對象

       session.saveOrUpdate(employee);//沒有返回值,如果有主鍵那麼更新,沒有則插入新紀錄

注意上述的各種方法都會將對象存入到一級緩存session中(其實就是一個Map結構"EntityKey[domain.Employee#112]" -> obj,在變量persistenceContext中),此時的對象都是持久態的

四、各種查詢

   Employee employee = session.find(Employee.class,101);//直接跟進id查詢
   employee.setLastName("xtz");持久化的對象在提交事務後會主動把結果更新的到數據庫
   Employee employee = session.load(Employee.class,101);//通過id查詢,通過懶加載的方式
   employee.setLastName("jeff");//使用到這個對象的時候,才發送查詢sql,同樣的,在關閉事務也會刷線到數據庫中       HQL
      Query<Employee> query = session.createQuery("from domain.Employee");//創建查詢,可以加where order by 等,但是不能加limit      query.setMaxResults(10);//記錄數,用於分頁
    query.setFirstResult(11);//記錄開始的下標,從0開始,用於分頁
    List<Employee> list = query.list();//查詢

         使用具名參數: (我的hinernate 版本hibernate-core-5.4.5.Final.jar

   from domain.Employee where id = :id

         query.setString("id","101");//這個版本已經不推薦使用了,代替的方案如下:

         query.setParameter("id",101, IntegerType.INSTANCE);//什麼類型就用xxxType.INSTANCE

         使用Criteria對象  

    Criteria criteria = session.createCriteria(Employee.class);
    criteria.add(Restrictions.eq("id",101));
    List<Employee> list = criteria.list();//不夠這個版本已經不這樣使用了,在後續的版本中會被移除

         替代方式:  https://stackoverflow.com/questions/40720799/deprecated-createcriteria-method-in-hibernate-5

   //首先獲取CriteriaBuilder
   CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
   //獲取CriteriaQuery對象
   CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
   //用於條件查詢
   Root<Employee> root = criteriaQuery.from(Employee.class);
   //拿id=101的記錄
   criteriaQuery.select(root).where(root.get("id").in(101));
   //創建query對象
   Query<Employee> query1 = session.createQuery(criteriaQuery);
   List<Employee> employees = query1.list();

       使用本地sql

      Query<Employee> query = session.createSQLQuery("select * from tb_employee where id = :id");     

      query.setParameter("id",101, IntegerType.INSTANCE);//設置具名參數

      List<Employee> list = query.list();

五、hibernate的三種對象狀態

      1、瞬時態,(new 出來的對象處於瞬時態)

      2、遊離態,(數據庫中存在,但是session中不存在的對象)

      3、持久態,(數據庫中存在,同時session中也存在的對象)

      這裏我提出一個問題,就是瞬時態和遊離態的區分,感覺界限不太明顯。持久態的最好區分,就是數據庫中和都存在的實體,比如你save、find、load、list等等都是會把實體存在session中,此時就是持久態了。但是比如持久態的對象調用session的clear、evict、close等方法,都會將實體移除session,那麼此時的實體,跟數據庫是對應的,比如他們的主鍵是一樣。那麼這個對應就是遊離態的話。存在一種情況,我new一個對象(將遊離態的實體傳入賦值),那麼這個新new的對象是瞬時態的還是遊離態的呢?(這個是我一直不太理解的地方,知道的大神麻煩指點一下)(其實可不可這樣理解,就針對實體的主鍵而言,如果session的有一個實體和數據庫實體主鍵一致,那麼這個session的實體就是持久態;如果一個實體不存在session中,同時它的的主鍵在數據庫中有一條記錄跟它對應,那麼這個就是遊離態的實體;如果一個實體不存在主鍵或者主鍵在數據庫中找不和它相對的記錄,那麼這個就是瞬時態)

六、在工作記得,在一個會話中,如果如果操作多張表,比如A表和B表。A表呢,你需要返回一些數據,然後你通過find的方式找到entity,然後你在entity中某個字段的值改了,比如image="www.xxxx.jpg",你要加水印,改了image="www.xxxx.jpg-image_big"

然後你返回給前端,就可以展示有水印的圖片。一開始你發現沒啥問題的,但是突然又有一個需求,說是要對這個請求進行記錄,比如要保存這個請求的訪問時間啥的,那麼就需要往B表插入一條數據。此時你會發現A表中,數據庫image的值也被改了。

這是因爲,當持久態的實體,被修改後,執行flush、session.close等操作,會將數據更新到數據庫中(工作中被坑過幾次)。

 

 

 


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章