學習hibernate(四) -- hibernate經常使用配置

    hibernate.cfg.xml的經常使用屬性配置。   
java

    在進行項目開發時,建議選擇一款數據源包來託管數據庫鏈接。hibernate包中有一組包叫c3p0,它是一個開源的JDBC鏈接池,實現了數據源與JNDI綁定,支持JDBC3規範和JDBC2標準拓展。mysql

    使用c3p0須要進行兩步操做,首先將jar包導入到項目中,而後在hibernate.cfg.xml中對其進行配置。算法

    jar包在/hibernate-release-4.3.11.Final/lib/optional/c3p0中存放。sql

    導入後,配置hibernate.cfg.xml文件。數據庫

<!-- 最大鏈接數 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 最小鏈接數 -->
<property name="hibernate.c3p0.min_size">5</property>
<!-- 得到鏈接的超時時間,若是超過這個時間,會拋出異常,單位毫秒 -->
<property name="hibernate.c3p0.timeout">120</property>
<!-- 最大的PreparedStatement的數量 -->
<property name="hibernate.c3p0.max_statements">100</property>
<!-- 每隔120秒檢查鏈接池裏的空閒鏈接 ,單位是秒-->
<property name="hibernate.c3p0.idle_test_period">120</property>
<!-- 當鏈接池裏面的鏈接用完的時候,C3P0一下獲取的新的鏈接數 -->
<property name="hibernate.c3p0.acquire_increment">2</property>

    測試一下是否使用了c3p0數據源,打印一個connection對象的類型。安全

    @Test
    public void test() {
        session.doWork(new Work() {

            @Override
            public void execute(Connection connection) throws SQLException {
                System.out.println(connection);
                /**
                 * output:com.mchange.v2.c3p0.impl.NewProxyConnection@68746f22
                 * */
            }

        });
    }

    hibernate中還有兩個經常使用屬性,getch_size和batch_size(oracle、sqlserver支持,mysql不支持)。session

    getch_size是設定JDBC的statement每次從數據庫中取出多少條數據。oracle

    batch_size是對數據庫進行批量刪除、批量更新和批量插入的時候批次的大小。app

    *.hbm.xml的經常使用屬性配置。ide

    以前的代碼調用的update或者insert時,老是會更新或者插入所有的字段,可是經過dynamic_insert和dynamic_update屬性,能夠插入或更新實體類設置的屬性。

<?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>
    <!-- update以前先進行select,對象與數據庫中的記錄一致,則不執行update -->
    <class name="cn.net.bysoft.model.User" table="S_USER" select-before-update="true" 
           dynamic-update="true">
        <id name="id" type="integer" column="ID">
            <!-- 指定主鍵的生成方式,native是使用數據庫本地的方式 -->
            <generator class="native"></generator>
        </id>
        <property name="name" type="string" column="NAME"></property>
        <property name="birthday" type="timestamp" column="BIRTHDAY"></property>
    </class>
</hibernate-mapping>
    @Test
    public void testDynamicUpdate() {
        User user = (User)session.get(User.class, 2);
        user.setName("Kobe");
    }


    設置了dynamic_update屬性等於true後,flush時update的只是修改過的字段,而再也不是所有字段。dynamic_insert同理。

    id節點中,生成數據庫id的方式,經常使用的有四種,分別是increment、identity、sequence、hilo和native。

<id name="id" type="integer" column="ID">
    <!-- 指定主鍵的生成方式,native是使用數據庫本地的方式 -->
    <generator class="native"></generator>
</id>

    他們的含義分別是:

屬性名
說明
increment
讀取映射的數據表中id的最大值+1做爲id值,但線程不安全,建議只在測試時使用。
identity
使用數據庫的自增功能,但數據庫必須支持自增列。
sequence
使用數據庫的序列功能,但數據庫必須支持序列。
hilo
由hibernate使用高低算法生成,不依賴底層的數據庫。
native
使用數據庫本地的方式生成id,數據庫能夠自增就自增,能夠序列就序列,若都不支持則調用hilo生成id值。

    id節點事後是property節點,property節點有一個屬性叫access,它的默認值是property,意思是在取值賦值時使用類的get/set方法,設置成field的話,取值賦值將採用反射的方式。

    還有一個屬性是type,該屬性能夠設置實體類屬性的類型,類型有三個種類,分別是Java類型、數據庫類型和hibernate類型,hibernate類型是Java類型和數據庫類型的適配器。

Java類型
hibernate類型
標準數據庫類型
java.lang.Interger/int
integer/int
INTEGER
java.lang.Long/long
long
BIGINT
java.lang.Short/short
short
SMALLINT
java.lang.Byte/byte
byte
TINYINT
java.lang.Float/float
float
FLOAT
java.lang.Double/double
double
DOUBLE
java.math.BigDecimal
big_decimal
NUMERIC
java.lang.Charatcter/Java.lang.String/char
character
CHAR(1)
java.lang.String
string
VARCHAR
java.lang.Boolean/boolean
boolean/yes_no/true_false
BIT
java.util.Data/java.sql.Data
date
DATE
java.util.Data/java.util.Timestamp
timestamp
TIMESTAMP
java.util.Calendar
calendar
TIMESTAMP
java.util.Calendar calendar_date
Date
byte[]
binary
BLOB
java.util.String
text
TEXT
java.sql.Blob
blob
BLOB
java.sql.Clob
clob
CLOB

    剩下的一些經常使用屬性是:

屬性名
說明
unique
設置惟一標識字段,該字段的值不能重複。
update
該自動的值是否能夠被修改。
index
設置該字段爲索引。
length
設置該字段的長度。
formula 設置一個SQL表達式生成值。
scale
保留幾位小數位數。

    寫一個測試用例使用這些屬性:

<?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>
    <!-- update以前先進行select,對象與數據庫中的記錄一致,則不執行update -->
    <class name="cn.net.bysoft.model.Employee" table="S_EMPLOYEE"
        dynamic-update="true">
        <id name="id" type="integer" column="ID">
            <!-- 指定主鍵的生成方式,native是使用數據庫本地的方式 -->
            <generator class="native"></generator>
        </id>
        <!-- 設置了unique屬性爲true。身份證不能重複 -->
        <!-- 設置了length屬性爲18。身份證長度爲18位 -->
        <property name="idcard" type="string" column="IDCARD" unique="true"
            length="18"></property>
        <property name="firstName" type="string" column="FIRSTNAME"></property>
        <property name="lastName" type="string" column="LASTNAME"></property>
        <!-- 設置了formula屬性爲fullname使用firstName.lastName來初始化值。 -->
        <property name="fullName" type="string" column="FULLNAME"
            formula="(SELECT CONCAT(e.FIRSTNAME, '.', e.LASTNAME) FROM S_EMPLOYEE e WHERE e.ID = id)"></property>
        <property name="birthday" type="timestamp" column="BIRTHDAY"></property>
        <!-- 保留兩位小數  -->
        <property name="salary" type="double" column="SALARY" scale="2"></property>
    </class>
</hibernate-mapping>

    經過該屬性建立表:

    身份證字段長度經過length屬性設置了長度,保存一條數據,在查詢:

    @Test
    public void test() {
        Employee employee = new Employee();
        employee.setFirstName("Jack");
        employee.setLastName("Sparrow");
        employee.setIdcard("123456789123456789");
        employee.setBirthday(new Date());
        employee.setSalary(20000.0000D);
        //    保存。
        session.save(employee);
    }

    @Test
    public void test() {
        Employee employee = (Employee) session.get(Employee.class, 1);
        System.out.println(employee.getFullName());
    }


    觀察打印的sql語句,會發現fullname是經過子查詢得到結果後,複製給了fullname字段,而數據庫自己並無fullname字段。

    最後,測試一下CLOB與BLOB兩個類型的數據的操做,在Employee類中加入一個簡介字段和照片字段。

    @Test
    public void test() throws IOException {
        Employee employee = (Employee) session.get(Employee.class, 1);
        // 建立一個Clob對象。
        String strContent = "He's a Pirate.";
        Clob content = Hibernate.getLobCreator(session).createClob(strContent);
        employee.setContent(content);
        // 定位圖片。
        InputStream stream = new FileInputStream("1.jpg");
        // 建立一個Blob對象。
        Blob photo = Hibernate.getLobCreator(session).createBlob(stream,
                stream.available());
        employee.setPhoto(photo);
    }

    經過Hibernate建立Clob對象和Blob對象,建立完成後更新數據庫中的數據,結果以下:

    能夠看到數據庫中已經保存了CONTENT和PHOTO兩個字段的數據,建議使用CLOB不如直接使用string方便。讀取這兩個字段的方式以下:

    

@Test
    public void testGetBlobAndClob() throws IOException, SQLException {
        Employee employee = (Employee) session.get(Employee.class, 1);
        // 輸入照片的文件大小。
        Blob photo = employee.getPhoto();
        InputStream stream = photo.getBinaryStream();
        System.out.println(stream.available());
        // 輸入簡介。
        Clob content = employee.getContent();
        Reader reader = content.getCharacterStream();// 獲得流
        BufferedReader br = new BufferedReader(reader);
        String strContent = br.readLine();
        StringBuffer sb = new StringBuffer();
        while (strContent != null) {// 執行循環將字符串所有取出付值給StringBuffer由StringBuffer轉成STRING
            sb.append(strContent);
            strContent = br.readLine();
        }
        strContent = sb.toString();
        System.out.println(strContent);
    }


    結果如圖,以上就是hibernate中配置文件裏的經常使用屬性。

相關文章
相關標籤/搜索