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中配置文件裏的經常使用屬性。