Hibernate(二)

5. 對象的狀態(tài)及生命周期及CRUD操作

5.1 對象的狀態(tài)及生命周期

hibernate對象狀態(tài)轉(zhuǎn)換圖

Transient:瞬時態(tài),session中有,數(shù)據(jù)庫中沒有
Persistent:持久態(tài),session中有,數(shù)據(jù)庫中有。
Detached:游離態(tài),session中沒有,數(shù)據(jù)庫中有。

5.2 new->save->close->update

@Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            // 構(gòu)造對象--瞬時狀態(tài)
            user = new User();
            user.setName("李四");
            user.setPwd("222");
            
            // 持久狀態(tài),user被session管理
            session.save(user);
            
            /*
             * 在持久狀態(tài)下,臟數(shù)據(jù)檢查:當(dāng)提交事務(wù)時或者清理緩存時,發(fā)現(xiàn)session中的數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)不一致時,
             * 將session中的數(shù)據(jù)更新到數(shù)據(jù)庫中
             */
            user.setName("劉德華");
            // 在保存以后再修改對象將會產(chǎn)生多條sql語句,效率較低,建議在save前修改
            session.flush();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
        // 游離狀態(tài)
        user.setName("梁朝偉");
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            // 持久狀態(tài)
            session.update(user);
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

5.3 get/load->clear/evict

get/load的區(qū)別:get會立即查詢對象,load在使用才去查詢,get找不到對象返回null,load找不到對象拋異常。

    @Test
    public void testGet() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            // get后會變?yōu)槌志脿顟B(tài)
            // get方法會立即查詢對象:范圍從Session,SessionFactory,數(shù)據(jù)庫
            // get查詢不到對象返回null
            user = (User) session.get(User.class, 11);
//          System.out.println(user);
            
            // 游離狀態(tài)下不被session管理 數(shù)據(jù)庫中不會被更改
//          session.evict(user);
//          session.clear();
//          user.setName("郭富城");
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void testLoad() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            // load后會變?yōu)槌志脿顟B(tài)
            // load方法不會立即查詢對象,到使用的時候才會查詢
            // loadl當(dāng)對象不存在會拋異常
            user = (User) session.load(User.class, 11);
            System.out.println(user);
            
            // 游離狀態(tài)下不被session管理 數(shù)據(jù)庫中不會被更改
//          session.evict(user);
//          session.clear();
//          user.setName("郭富城");
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

5.4 update:先獲取再修改->可以避免異常

    @Test
    public void testUpdate() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            // 手動構(gòu)造的瞬時狀態(tài)的對象也可以修改,但是需要指定所有屬性,不建議使用。
//          user = new User();
//          user.setId(5);
//          user.setName("王五");
            
            // 通過從數(shù)據(jù)庫中加載該對象然后再修改 可以進行判斷從而避免異常,提高程序的健壯性
            user = (User) session.get(User.class, 5);
            if(user != null) {
                user.setName("老王");
                session.update(user);
            }
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

5.5 delete:先獲取再刪除->可以避免異常

    @Test
    public void testDelete() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            // 手動構(gòu)造的瞬時狀態(tài)的對象也可以刪除,不建議使用。
//          user = new User();
//          user.setId(5);
            
            // 通過從數(shù)據(jù)庫中加載該對象然后再修改 可以進行判斷從而避免異常,提高程序的健壯性
            user = (User) session.get(User.class, 1);
            if(user != null) {
                session.delete(user);
            }
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

6. SchemaExport&組合主鍵映射

6.1 SchemaExport的使用

    @Test
    public void testCreateDB() {
        Configuration cfg = new Configuration().configure();
        SchemaExport se = new SchemaExport(cfg);
        // 第一個參數(shù)是否生成ddl腳本,第二個參數(shù)是否執(zhí)行到數(shù)據(jù)庫
        se.create(true, true);
    }

6.2 通過組件來實現(xiàn)組合主鍵的步驟

  • 編寫組合主鍵的類,該類必須實現(xiàn)Serializable接口
public class ScoreId implements Serializable {
    private Integer stuId;
    private Integer subjectId;
    public Integer getStuId() {
        return stuId;
    }
    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }
    public Integer getSubjectId() {
        return subjectId;
    }
    public void setSubjectId(Integer subjectId) {
        this.subjectId = subjectId;
    }
}
  • 在主類中引用對應(yīng)的組件
public class Score implements Serializable {
    private ScoreId scoreId;
    private Integer result;
    public ScoreId getScoreId() {
        return scoreId;
    }
    public void setScoreId(ScoreId scoreId) {
        this.scoreId = scoreId;
    }
    public Integer getResult() {
        return result;
    }
    public void setResult(Integer result) {
        this.result = result;
    }
}
  • 編寫配置文件
<hibernate-mapping package="com.yxxy.pojo">
    <class name="Score">
        <!-- 組合主鍵 -->
        <composite-id name="scoreId" class="ScoreId">
            <key-property name="stuId"></key-property>
            <key-property name="subjectId"></key-property>
        </composite-id>
        <!-- 實體類的屬性 -->
        <property name="result"></property>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Score score = new Score();
            ScoreId sId = new ScoreId();
            sId.setStuId(1);
            sId.setSubjectId(2);
            score.setResult(90);
            score.setScoreId(sId);
            
            session.save(score);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

7. 大對象映射

  • 在pojo類中,用Blob類型和Clob類型
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    // 存放大數(shù)據(jù) 最大可存放4G
    private Blob image;
    private Clob introduce;
}
  • 在*.hbm.xml文件中需要指定類型
<hibernate-mapping package="com.yxxy.pojo">
    <class name="Student">
        <id name="id">
            <generator class="native"></generator>
        </id>
    
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <property name="age"></property>
        <property name="image" type="java.sql.Blob"></property>
        <property name="introduce" type="java.sql.Clob"></property>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Student stu = new Student();
            stu.setName("張三");
            stu.setAge(20);
            Blob blob = new SerialBlob("blob".getBytes());
            Clob clob = new SerialClob("clob".toCharArray());
            stu.setImage(blob);
            stu.setIntroduce(clob);
            
            session.save(stu);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

8. 組件映射

  • 編寫Teacher類
public class Teacher {
    private Integer id;
    private String name;
    private String sex;
    private Address address;
}
  • 編寫Teacher類的組件Address類
public class Address {
    private String add1;
    private String add2;
    private String add3;
}
  • Teacher.hbm.xml映射文件
<hibernate-mapping package="com.yxxy.pojo">
    <class name="Teacher">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <property name="sex"></property>
        <!-- 組件映射 -->
        <component name="address" class="Address">
            <property name="add1"></property>
            <property name="add2"></property>
            <property name="add3"></property>
        </component>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Teacher teacher = new Teacher();
            teacher.setName("高淇");
            teacher.setSex("男");
            Address address = new Address();
            address.setAdd1("西三旗");
            address.setAdd2("西直門");
            address.setAdd3("北五環(huán)");
            teacher.setAddress(address);
            
            session.save(teacher);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

9. 單向多對一的關(guān)聯(lián)映射

  • 學(xué)生表和年級表

學(xué)生表

ID Name Age Grade_ID
1 張三 20 1
2 李四 30 2
3 王五 40 1

年級表

ID Name
1 初級
2 中級
  • Student類和Grade類
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private Grade grade;
}
public class Grade {
    private Integer id;
    private String name;
}
  • 映射文件

Grade.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Grade">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
    </class>
</hibernate-mapping>

Student.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Student">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <property name="age"></property>
        <!-- 
            多對一
            name:表示屬性名
            class:指明屬性對應(yīng)的類
            colume:指數(shù)據(jù)庫表中的列名    
         -->
         <many-to-one name="grade" class="Grade" column="grade_id" foreign-key="fk_grade" not-null="true"></many-to-one>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Grade grade = new Grade();
            grade.setName("基礎(chǔ)");
            
            Student stu = new Student();
            stu.setName("張三");
            stu.setAge(20);
            stu.setGrade(grade);
            
            session.save(grade);
            session.save(stu);
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

10. 單向一對多的關(guān)聯(lián)映射

  • 類Student和Grade類
public class Grade {
    private Integer id;
    private String name;
    private Set<Student> students = new HashSet<>();
}
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}
  • 映射文件

Grade.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Grade">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <!-- set是Grade中的集合屬性 name屬性名稱 -->
        <set name="students">
            <!-- key表示外鍵 colume外鍵列名 -->
            <key column="grade_id" not-null="true" foreign-key="fk_grade"></key>
            <!-- 一對多 類Grade中 students所表示的類型 -->
            <one-to-many class="Student"/>
        </set>
    </class>
</hibernate-mapping>

Student.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Student">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <property name="age"></property>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSave() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Grade grade = new Grade();
            grade.setName("基礎(chǔ)");
            
            Student stu = new Student();
            stu.setName("張三");
            stu.setAge(20);
            stu.setGrade(grade);
            
            session.save(grade);
            session.save(stu);
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

11. 雙向一對多的關(guān)聯(lián)映射

  • 類Student和Grade類
public class Grade {
    private Integer id;
    private String name;
    private Set<Student> students = new HashSet<>();
}
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private Grade grade;
}
  • 映射文件

    Grade.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Grade">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <!-- set是Grade中的集合屬性 name屬性名稱 -->
        <set name="students">
            <!-- key表示外鍵 colume外鍵列名 -->
            <key column="grade_id" not-null="true" foreign-key="fk_grade"></key>
            <!-- 一對多 類Grade中 students所表示的類型 -->
            <one-to-many class="Student"/>
        </set>
    </class>
</hibernate-mapping>

Student.hbm.xml

<hibernate-mapping package="com.yxxy.pojo">
    <class name="Student">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <!-- 實體類的屬性 -->
        <property name="name"></property>
        <property name="age"></property>
        <!-- 
            多對一
            name:表示屬性名
            class:指明屬性對應(yīng)的類
            colume:指數(shù)據(jù)庫表中的列名    
         -->
         <many-to-one name="grade" class="Grade" column="grade_id" foreign-key="fk_grade"></many-to-one>
    </class>
</hibernate-mapping>
  • 測試
    @Test
    public void testSaveByOneToMany() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Student stu = new Student();
            stu.setName("張三");
            stu.setAge(20);
            
            Grade grade = new Grade();
            grade.getStudents().add(stu);
            grade.setName("基礎(chǔ)");
            
            /**
             * 保存數(shù)據(jù)的順序是根據(jù)外鍵的配置來決定的
             * 如果外鍵不能為null 先保存一的一端
             * 如果外鍵可以為null 則隨意保存,但是會多執(zhí)行update語句
             */
            session.save(grade);
            session.save(stu);
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void testSaveByManyToOne() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            
            Grade grade = new Grade();
            grade.setName("基礎(chǔ)");
            
            Student stu = new Student();
            stu.setName("張三");
            stu.setAge(20);
            stu.setGrade(grade);
            
            session.save(grade);
            session.save(stu);
            
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void testGet() {
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
            //取數(shù)據(jù)
            Grade grade = (Grade) session.get(Grade.class, 1);
            System.out.println("gradeName:" + grade.getName());
            System.out.println("grade所對應(yīng)的多的一端的數(shù)據(jù)");
            Iterator<Student> iter = grade.getStudents().iterator();
            for(; iter.hasNext();) {
                Student stu = iter.next();
                System.out.println("name=" + stu.getName() + " age=" + stu.getAge());
            }
            System.out.println("=================================");
            Student stu = (Student) session.get(Student.class, 1);
            System.out.println("name=" + stu.getName() + " age=" + stu.getAge());
            System.out.println("student所對應(yīng)的一端的數(shù)據(jù)");
            System.out.println("gradeName:" + stu.getGrade().getName());
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.OID和主鍵生成策略 1.1.主鍵(Primary key): 在數(shù)據(jù)庫表中能夠唯一識別每一行記錄的一個字段或...
    賈里閱讀 1,257評論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,734評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,017評論 0 11
  • 1、編譯安裝MySQL需要一些必備的組件,可以直接使用yum安裝即可 yum -y install cmake n...
    者火閱讀 905評論 0 1
  • 可能會有很多人在上了大學(xué)之后想要改變自己,這個改變是從性格開始,開學(xué)后沒多久學(xué)校各個社團就開始納新而我在面...
    A以為閱讀 276評論 0 1

友情鏈接更多精彩內(nèi)容