Hibernate自學詳細筆記,hibernate自學

來源:互聯網
上載者:User

Hibernate自學詳細筆記,hibernate自學

Hibernate設定檔添加環境1.Jar包2.設定檔hibernate.cfg.xml/xxx.hbm.xml3.使用hibernate實現增刪改查Configuration cfg = new configuration.config();SessionFactory sessionFactory = cfg.buildSessionFactory();Session session = sessionFactory.openSession();Try{Transaction  tx = session.beginTransaction().commit();}catch(Exception e){Tx.rollback();}finally{Session.close();}4.方法:save(object) / update(object) / delete(Object) / createQuery(hql) ./ get(class,id)5.主設定檔:資料庫資訊:方言、URL、驅動、使用者名稱、密碼匯入對應檔其他的配置show_sql = true; hbm2ddl.auto = update;6.映射配置映射基礎:無參的構造方法,get和set方法映射普通屬性name ,type, length , column ,not-null映射的主鍵native,assigned,uuid,hilo等等1  hibernate.cfg.xml該檔案配置了Hibernate需要的資料庫的url以及帳號和密碼等等的資訊例如:<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><!-- Generated by MyEclipse Hibernate Tools.                   --><hibernate-configuration><session-factory><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">mysql</property><property name="dialect">org.hibernate.dialect.MySQLDialect</property><property name="connection.pool_size">1</property><property name="show_sql">true</property><mapping resource="com/shangyanyuan/entity/User.hbm.xml"/></session-factory></hibernate-configuration>2  設定檔:User.hbm.xml該檔案負責對User進行映射的檔案,配置了user的一些屬性值和資料庫中對應的屬性以及相應的設定資訊,如類型,是否為空白。<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC                            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"                            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" ><hibernate-mapping><class name = "com.shangyanyuan.entity.User" table="user"><id name = "id" type = "java.lang.Integer" column = "id"><generator class="increment"></generator></id><property name="username" type = "java.lang.String" column = "username" length = "20"></property><property name="password" type = "java.lang.String" column = "password" length = "20"></property></class></hibernate-mapping>Name屬性:對象中的屬性名稱,這個必須要有的Type屬性:類型屬性,如果不寫的話Hibernate會自動的檢測其類型Column屬性:對應著資料庫當中的某一列。Length屬性:長度。Not-null屬性:非空屬性。如果說你現在設定好了User.hbm.xml這個檔案,但是資料庫當中沒有該資料庫,那麼由這個設定檔Hibernate會自動的幫你在資料庫當中產生該表。注意:type的值如果大寫的話可以這樣java.lang.String(java中類型),小寫話string(Hibernate類型)即可。映像,byte[] 的形式在設定檔中類型對應著binary類型,最好是指定長度值。主鍵:如果是int的話最好是設定為Integer類型,初始值int類型為0,而Integer則為null3  主鍵建置原則:Native 根據資料的性質自動的選擇用那個建置原則。Assigned 手動的指定它的值。使用UUID.randomUUID().toString();手動設定可保證唯一性。Identity 使用資料庫的自己的主鍵建置原則,但是oracle不支援。Sequence oracle中使用這個,也可以db2等等資料庫Hilo 高低位演算法來產生主鍵,只需要一張額外的表,所以的資料庫都支援。Increment 查詢最大的id值然後加1增長,Hibernate協助增長的,不推薦使用,多線程的情況下會有問題的。Uuid 設定其主鍵建置原則為uuid即可實現與assigned中使用UUID.randomUUID().toString();的效果。4 集合類型的資料的儲存Set 無序 不重複List 有序 可重複Map 無序 不重複有序的集合無法配置使其排序,但是無序的集合可以通過配置的方式使其排序但是排序一般不會用到。比如購物網站使用者地址資訊Set集合 非常重要會經常用到設定有序無序unsorted|natural|comparatorClass預設的方式是unsorted需要設定的屬性是sort屬性order-by屬性order-by = “address DESC/ASC(預設是ASC)”List集合List集合是有順序的所以在映射的時候需要配置這樣幾個屬性:userid, address,idx(索引表示它的順序)這樣設計它的對應檔中應該寫為:<list name = “addressList” table = “user_address”><key column = “userid”></key><list-index column = “idx”></list-index><element type = “string” column = “address”></element></list>數組<array name = “addressList” table = “user_address”><key column = “userid”></key><list-index column = “idx”></list-index><element type = “string” column = “address”></element></array>Arrays.toString(“”);可查看數組的元素Map集合<map name = “addressMap” table = “user_addressMap”><key column = “userid”></key><map-key type = “string” column  = “key_”></map-key><element type = “string” column = “address”></element></map>Hibernate特有的集合Bag 無序,可重複<bag name = “addressbag” table = “user_addressbag”><key column = “userid”></key><element type = “string” column = “address”></element></map>5:set集合順序問題HashSet 無序的TreeSet 有序,放入資料之后里面的資料是排好了順序的LinkedHashSet 有序的,按照放入的資料的順序存放的6:一對多的關係外鍵在多的那一方中例如員工部門的關係package cn.itcast.f_hbm_oneToMany;import java.util.HashSet;import java.util.Set;/** * 部門 *  * @author tyg *  */public class Department {private Integer id;private String name;private Set<Employee> employees = new HashSet<Employee>(); // 關聯的很多員工@Overridepublic String toString() {return "[Department: id=" + id + ", name=" + name + "]";}}<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.itcast.f_hbm_oneToMany"><class name="Department" table="department"><id name="id">        <generator class="native"></generator></id><property name="name"/><!-- employees屬性,Set集合,表達的是本類與Employee的一對多 class屬性:關聯的實體類型key子項目:對方表中的外鍵列(多方的那個表)inverse屬性:預設為false,表示本方維護關聯關係。如果為true,表示本方不維護關聯關係。只是影響是否能設定外鍵列的值(設成有效值或是null值),對擷取資訊沒有影響。cascade屬性:預設為none,代表不級聯。級聯是指操作主對象時,對關聯的對象也做相同的操作。可設為:delete, save-update, all, none ...<set name="employees" cascade="all"><key column="departmentId"></key><one-to-many class="Employee"/></set>--></class></hibernate-mapping>================================================================package cn.itcast.f_hbm_oneToMany;/** * 員工 *  * @author tyg *  */public class Employee {private Integer id;private String name;private Department department; // 關聯的部門對象@Overridepublic String toString() {return "[Employee: id=" + id + ", name=" + name + "]";}}<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.itcast.f_hbm_oneToMany"><class name="Employee" table="employee"><id name="id">        <generator class="native"></generator></id><property name="name" type="string" column="name"/><!-- department屬性,表達的是本類與Department的多對一 class屬性:關聯的實體類型column屬性:外鍵列(引用關聯對象的表的主鍵)--><many-to-one name="department" class="Department" column="departmentId"></many-to-one></class></hibernate-mapping>測試package cn.itcast.f_hbm_oneToMany;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.junit.Test;public class App {private static SessionFactory sessionFactory = new Configuration()//.configure()//.addClass(Department.class)// 添加Hibernate實體類(載入對應的對應檔).addClass(Employee.class)// 添加Hibernate實體類(載入對應的對應檔).buildSessionFactory();// 儲存,有關聯關係@Testpublic void testSave() throws Exception {Session session = sessionFactory.openSession();session.beginTransaction();// --------------------------------------------// 建立對象Department department = new Department();department.setName("開發部");Employee employee1 = new Employee();employee1.setName("張三");Employee employee2 = new Employee();employee2.setName("李四");// 關聯起來employee1.setDepartment(department);employee2.setDepartment(department);department.getEmployees().add(employee1);department.getEmployees().add(employee2);// 儲存//session.save(employee1);//session.save(employee2);session.save(department); // 儲存部門// --------------------------------------------session.getTransaction().commit();session.close();}// 擷取,可以擷取到關聯的對方@Testpublic void testGet() throws Exception {Session session = sessionFactory.openSession();session.beginTransaction();// --------------------------------------------// 擷取一方,並顯示另一方資訊Department department = (Department) session.get(Department.class, 1);System.out.println(department);System.out.println(department.getEmployees());// Employee employee = (Employee) session.get(Employee.class, 1);// System.out.println(employee);// System.out.println(employee.getDepartment());// --------------------------------------------session.getTransaction().commit();session.close();}// 解除關聯關係@Testpublic void testRemoveRelation() throws Exception {Session session = sessionFactory.openSession();session.beginTransaction();// --------------------------------------------// // 從員工方解除// Employee employee = (Employee) session.get(Employee.class, 1);// employee.setDepartment(null);// 從部門方解除(與inverse有關係,為false時可以解除)Department department = (Department) session.get(Department.class, 1);department.getEmployees().clear();// --------------------------------------------session.getTransaction().commit();session.close();}// 刪除對象,對關聯對象的影響@Testpublic void testDelete() throws Exception {Session session = sessionFactory.openSession();session.beginTransaction();// --------------------------------------------// // 刪除員工方(多方),對對方沒有影響// Employee employee = (Employee) session.get(Employee.class,2);// session.delete(employee);// 刪除部門方(一方)// a, 如果沒有關聯的員工:能刪除。// b, 如果有關聯的員工且inverse=true,由於不能維護關聯關係,所以會直接執行刪除,就會有異常// c, 如果有關聯的員工且inverse=false,由於可以維護關聯關係,他就會先把關聯的員工的外鍵列設為null值,再刪除自己。Department department = (Department) session.get(Department.class, 4);session.delete(department);// --------------------------------------------session.getTransaction().commit();session.close();}}多對多對於老師的hbm的設定檔應該是:<!--Teacher屬性,Set集合表達的是本類與Teacher的多對多的關係Table屬性:中間表(集合表)-->一定要一致Key子項目:集合外鍵(引用當前表主鍵的那個外鍵)--><set name = “teachers”  table = “t_teacher_student”><key column = “studentId”></key><many-to-many class = “Teacher” column = “teacherId”></many-to-many></set>對於學生類的hbm的設定檔應該是:<set name = “students”  table = “t_teacher_student”><key column = “teacherId”></key><many-to-many class = “Student” column = “studentId”></many-to-many></set>預設的是雙方都維護中間表中這個資料庫的資料,與inverse有關,inverse = true那麼本方不維護。多對多的時候inverse = false的時候,能維護關聯關係,那麼先接觸關聯關係然後再刪除。但是inverse = true 的時候,如果本身不維護的話就直接刪除但是這樣會報錯(因為存在著關聯關係)。Cascade屬性級聯預設的是none操作本對象的時候對於與之關聯的對象也做相同的操作可以設定的值是delete,save-update,all,none7. Session對象Session.save(“”);Session.save(“”);Session.save(“”);Session.save(“”);只會執行一次insert語句。session.save(“sdfsdfsdf”);session.flush();立即執行Session.evict(user);清除某一個指定的對象一.操作實體物件的Save(),update(),saveOrUpdate(),delete()Save()的時候直接就執行而不是等到提交的時候才執行。二.操作緩衝的Clear(),evict();flush();三.查詢實體物件的Get();load();createQuery();createCriteria();Load()不是馬上執行,只有在你用的時候才會執行Hibernate交易隔離等級<property name = “connnection.isolation”>1(讀未提交)/2(讀已提交)/4(可重複讀)/8(序列化(不可並行))</property>一對一映射基於外鍵的方式:1. 在person的設定檔中,其設定檔當中沒有外鍵,property-ref屬性寫的是對方映射中外鍵列對應的屬性名稱。採用<one-to-one name = “” column = “”></one-to-one>標籤2.在idcard的設定檔中設定有外鍵的<many-to-one name = “”  class = “” column = “” > </many-to-many>注意:從有外鍵的哪一方解除關係可以的,但是從沒有外鍵的哪一方解除關係是不可以的,只能由有外鍵的哪一方去解除關聯關係。基於主鍵的方式:1. 在Person的設定檔當中採用<one-to-one name = “idcard” column = “Idcard”></one-to-one>標籤2.在Idcard的設定檔當中採用:<one-to-one name = “person” column = “Person” constrained = “true”></one-to-one>標籤注意當使用一對一基於主鍵方式的時候,有外鍵方的主鍵建置原則一定要是foreign<generator class = “foreign”><param name = “property”> person </param></generator>刪除時如果是沒有外鍵的那一方(和對方的外索引值有關聯關係),直接執行刪除動作的時候會發生異常,因為和對方的外索引值有關聯關係,但是如果是對方進行刪除的話不會出現異常。繼承結構的:1.設計表的時候可以將所有的內容都放在一張表中。不過一行中往往會有多個null的值設定檔:<!-- discriminator-value屬性:用於鑒別是哪個類的一個值,表示這個值就是這個類。如果不寫,預設為類的全限定名。 --><class name="Article" table="article" discriminator-value="Aticle"><id name="id">        <generator class="native"/></id><!-- 用於鑒別是什麼類型的一個列 --><discriminator type="string" column="class_"></discriminator><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子類:Topic --><subclass name="Topic" discriminator-value="Topic"><property name="type"></property></subclass><!-- 子類:Reply --><subclass name="Reply" discriminator-value="Reply"><property name="floor"></property></subclass>2. <!-- 採用每個類一張表的方式,抽象類別也對應表。 --><class name="Article" table="article2"><id name="id">        <generator class="native"/></id><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子類:Topic --><joined-subclass name="Topic" table="topic2"><key column="id"></key><property name="type"></property></joined-subclass><!-- 子類:Reply --><joined-subclass name="Reply" table="reply2"><key column="id"></key><property name="floor"></property></joined-subclass></class>3.<!-- 採用每個具體類一張表的方式,抽象類別不對應表。abstract預設為false,設為true表示本類不對應表(類可以不是abstract的),這時就會忽略table屬性。 --><class name="Article" abstract="false" table="article3"><id name="id"><!-- 當使用每個具體類一張表的方式時,主鍵建置原則不能是identity。因為在整個繼承結構中,主索引值是不能重複的。 -->        <generator class="hilo">        <param name="table">hi_value</param>                <param name="column">next_value</param>                <param name="max_lo">100</param>        </generator></id><property name="title"/><property name="content" type="text" length="10000"/><property name="postTime" type="timestamp"/><!-- 子類:Topic --><union-subclass name="Topic" table="topic3"><property name="type"></property></union-subclass><!-- 子類:Reply --><union-subclass name="Reply" table="reply3"><property name="floor"></property></union-subclass></class>8 HQL語句Auto-import 表示在HQL語句中寫類的簡單名稱時,是否自動的導包QBC方式查詢 :Query by Criteria一對一的只有有外鍵的那一方才能維護關係。繼承結構的映射1.所有的資料都放在一張表當中去,當然很多的列會存在=null的情況。2.每個類對應著一張表,包括抽象類別也有自己的一張表。3.每個具體的類都對應著一張表但是抽象類別不對應著表。HQL語句查詢的是對象和屬性。關鍵字不區分大小寫,但是類名和屬性名稱的話區分大小寫。文法 FROM 實體 AS EWhere / Order by / group by  、having /  Lazy屬性True:第一次的時候載入False:及時的載入Extra:增強懶載入策略。Hibernate串連池使用C3P0串連池需要匯入C3P0的包,只需要在Hibernate的設定檔當中進行設定即可<!-- C3P0串連池設定--><!-- 使用c3p0串連池  配置串連池提供的供應商--><property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider                                                                                                                                                     </property><!--在串連池中可用的資料庫連接的最少數目 --><property name="c3p0.min_size">5</property><!--在串連池中所有資料庫連接的最大數目  --><property name="c3p0.max_size">20</property><!--設定資料庫連接的到期時間,以秒為單位,如果串連池中的某個資料庫連接處於空閑狀態的時間超過了timeout時間,就會從串連池中清除 --><property name="c3p0.timeout">120</property> <!--每3000秒檢查所有串連池中的空閑串連 以秒為單位--><property name="c3p0.idle_test_period">3000</property>二級緩衝:EhCacheProvider(比較強大些)(使用之前要匯入三個jar包+ehcache.xml(直接拷貝用稍微修改即可))<!-- 使用二級緩衝,預設是未開啟的。 --><!-- 指定要使用的緩衝的供應商,這也就開啟了二級緩衝 <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>--><property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property><!-- 開啟使用查詢快取 --><property name="cache.use_query_cache">true</property><!-- 指定要使用二級緩衝的實體類 --><class-cache usage="read-write" class="cn.itcast.l_second_cache.Employee"/><class-cache usage="read-write" class="cn.itcast.l_second_cache.Department"/><collection-cache usage="read-write" collection="cn.itcast.l_second_cache.Department.employees"/><!-- 匯入對應檔 <mapping resource="cn/itcast/a_helloworld/User.hbm.xml"/>-->HashTable -->安全執行緒的,但是速度回慢一些HashMap-->線程不安全的,速度快一些。getCurrentSession只要是存在Session的時候就不會建立新的Session,當發生提交或者復原後,Hibernate會自動的關閉Session但是openSession則不一樣,每次都是重新建立一個新的Session。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.