Hibernate主鍵ID生成方式
1、assigned生成方式:【手動生成】
<另:在用Hibernate的時候,當有表中的主鍵是庫自動生成的時候將使用native。而當是自己添加的時候則需要改為assigned。否則將會出現異常!>
即主鍵由外部程序負責生成,無需Hibernate參與,即當增加一個實例時,由程序設定該實體的ID值(手工分配值)
即在映射文件中如下增加:
<generator class="assigned"></generator>
而增加記錄的類里給其賦ID值。
2、identity生成方式:【MYSQL自增】
在DB、SQL Server、MySql等數據庫產品表中主鍵可以設定自動增長列,則增加一條記錄時主鍵的值可以不賦值。
用數據庫的主鍵生成機制:數據庫表創建時加:auto_increment。
表映射文件:
<generator class="identity"></generator>
在操作實體以及實體類中無需體現ID主鍵。
3、increment生成方式:【實例自增-避免使用】
主鍵按數值順序遞增-------盡量避免使用該方法。多個實例操作數據庫時,會造成主鍵重復現象
表映射:
<generator class="increment"></generator>
4、sequence生成方式:【Oracle自生】
采用數據庫提供的sequence機制生成主鍵,如Oracle數據庫。
表映射:
<generator class="sequence"></generator>
5、uuid.hex生成方式:【依據機器標識等自生】
由Hibernate為ID列賦值,依據當前客戶端機器的IP、JVM啟動時間、當前時間、一個機器數生成串、以該串為ID值。
表映射:
<generator class="uuid.hex"></generator>
注意:以上方法建議都掌握牢記原理
實例一:assigned生成方式:【手動生成】-----之前的文章已有
實例二、identity生成方式:【MYSQL自增】
一、在原來的hibernate.cfg.xml文件中,記得加入:
表的映射文件記錄。即:
<mapping resource="resource/Customer2.hbm.xml"/>
完整代碼:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- 配置文件標簽順序property*,mapping*,(class-cache|collection-cache),event,listener* --> <session-factory> <!-- 設置訪問mysql數據庫的驅動描述 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 設置數據庫的url --> <property name="connection.url">jdbc:mysql://127.0.0.1:3306/test</property> <!-- 指定登錄數據庫用戶賬戶 --> <property name="connection.username">root</property> <!-- 指定登錄數據庫用戶密碼 --> <property name="connection.password">123456</property> <!-- 設置訪問數據庫的方言,提高數據庫訪問性能 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 設置ddl --> <!-- <property name="hbm2ddl.auto">auto</property> --> <!-- 配置控制台視圖,顯示查詢內容 --> <property name="show_sql">true</property> <!-- 下面是多表映射 --> <!-- 映射表文件 --> <mapping resource="resource/Customer.hbm.xml"/> <!-- 映射表文件 --> <mapping resource="resource/Customer2.hbm.xml"/> </session-factory> </hibernate-configuration>
二、新建表映射表文件(Customer2.hbm.xml)
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="bean" auto-import="false"> <!-- POJO類映射表及某表的關系--> <class name="bean.Customer2" table="customers2" catalog="test"> <id name="customerID" type="java.lang.Integer"> <column name="customerID"/> <generator class="identity"></generator> </id> <!-- 映射表中name字段 --> <property name="name" type="java.lang.String"> <column name="name" length="40"/> </property> <!-- 映射表中phone字段 --> <property name="phone" type="java.lang.String"> <column name="phone" length="16"/> </property> </class> </hibernate-mapping>
悟:該文件主要改<generator class="identity"></generator>,后續主鍵生成方式。字段根據表來即可。
二、將之前的HibernateSessionFactory類拿來使用:【代碼復用】
package bean; import java.util.List; import hibernate.factory.HibernateSessionFactory; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.query.Query; //用於測試identity主鍵生成方式,增加記錄 //由於是增加數據,所以不需要寫Query,只需要new表,增加數據即可 public class Customer2Demo { Session session = HibernateSessionFactory.getSession(); Transaction tran = session.beginTransaction(); public static void main(String[] args) { //測試identity主鍵生成 Customer2Demo demo = new Customer2Demo(); Customer2 customer2 = new Customer2(); demo.saveCustomer2IDByIdentity(customer2, "華山", "580"); //測試查詢結果 List list = demo.queryAllCustomer2(); for (int i = 0; i < list.size(); i++) { Customer2 customer = (Customer2)list.get(i); System.out.println(customer.getCustomerID()+customer.getName()+customer.getPhone()); } HibernateSessionFactory.closeSession(); } //下面是封裝保存 public void saveCustomer2IDByIdentity(Customer2 customer2,String name,String phone) { customer2.setName(name); customer2.setPhone(phone); session.save(customer2); //一定一定要記得提交事務 tran.commit(); } //下面是封裝查詢 @SuppressWarnings("rawtypes") public List queryAllCustomer2(){ /**由會話工廠類創建一個會話Session對象**/ Session session = HibernateSessionFactory.getSession(); /**由會話session對象創建一個查詢對象**/ Query query = session.createQuery("from bean.Customer2"); List list = query.list(); HibernateSessionFactory.closeSession(); return list; } }
三、新建映射表類:Customer2.java
package bean; //驗證identity生成主鍵方式的映射類,數據庫對應表customers2 public class Customer2 { private int customerID; private String name,phone; public int getCustomerID() { return customerID; } public void setCustomerID(int customerID) { this.customerID = customerID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
四、測試類:【順便查詢結果,看是否成功】
package bean; import java.util.List; import hibernate.factory.HibernateSessionFactory; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.query.Query; //用於測試identity主鍵生成方式,增加記錄 //由於是增加數據,所以不需要寫Query,只需要new表,增加數據即可 public class Customer2Demo { Session session = HibernateSessionFactory.getSession(); Transaction tran = session.beginTransaction(); public static void main(String[] args) { //測試identity主鍵生成 Customer2Demo demo = new Customer2Demo(); Customer2 customer2 = new Customer2(); demo.saveCustomer2IDByIdentity(customer2, "華山", "580"); //測試查詢結果 List list = demo.queryAllCustomer2(); for (int i = 0; i < list.size(); i++) { Customer2 customer = (Customer2)list.get(i); System.out.println(customer.getCustomerID()+customer.getName()+customer.getPhone()); } HibernateSessionFactory.closeSession(); } //下面是封裝保存 public void saveCustomer2IDByIdentity(Customer2 customer2,String name,String phone) { customer2.setName(name); customer2.setPhone(phone); session.save(customer2); //一定一定要記得提交事務 tran.commit(); } //下面是封裝查詢 @SuppressWarnings("rawtypes") public List queryAllCustomer2(){ /**由會話工廠類創建一個會話Session對象**/ Session session = HibernateSessionFactory.getSession(); /**由會話session對象創建一個查詢對象**/ Query query = session.createQuery("from bean.Customer2"); List list = query.list(); HibernateSessionFactory.closeSession(); return list; } }
悟:在編寫程序過程中,代碼復用很重要,同時,考慮減少代碼量,但減少代碼量的時候應該考慮減少代碼是否會造成后續不可用,該不該較少等。如四中,設置了一個全局對象session,后續查詢的方法中,直接使用該對象是不可行的,而是重新獲得,這是為什么呢?
個人思考:
一、在提交事務保存的時候,會話會被清空,從而造成后續使用問題。
二、后續封裝的方法盡量不使用全局變量或者對象,使之分工明確。
其他注意:在數據庫沒有設定ID自增時,會報如下錯誤。
數據庫修改設置字段自增:
alter table customers2 auto_increment=初始值;