分享知識-快樂自己:搭建第一個 Hibernate (Demo)
使用 Hibernate 完成持久化操作 七大 步驟:
1、讀取並解析配置檔案及對映檔案:
Configuration configuration=new Configuration().configure();
根據預設位置的 Hibernate 配置檔案中的資訊,構建 Configuration 物件。 Configuration 負責管理 Hibernate 的配置資訊。
2、依據配置檔案和對映檔案中的資訊,建立 SessionFactory 物件;
SessionFactory sessionFactory=configuration.buildSessionFactory();
Configuration 物件會根據當前的資料庫配置資訊, 構造 SessionFactory 物件。SessionFactory 物件一旦構造完畢,Configuration 物件的任何變更不會影響已經建立的 SessionFactory 物件。
如果 Hibernate 配置資訊有改動,那麼需要基於改動後的 Configuration 物件重新構建一個 SessionFactory 物件。
3、開啟 Session ;
Session session=sessionFactory.getCurrentSession(); 或sessionFactory.openSession();
SessionFactory 負責建立 Session 物件。Session 是持久化操作的基礎。Session 作為貫穿 Hibernate 的持久化管理的核心,提拱了眾多持久化方法,如 save()、delete()、update()、get()、load()等...
通過這些方法,即可透明地完成物件的 增刪改查(CRUD)
4、開始一個事務;
Tansaction tx = session.beginTansaction();
5、資料庫操作;
session.save();//儲存操作
6、結束事務;
tx.commit();//提交事務 或 回滾事務
7、如果是通過 SessionFactory 的 openSession() 方法獲取的 Session 物件,則需要關閉 session。
session.close();
提示:如果在 Hibernate 配置檔案中將引數 current_session_context_class 設定為 thread,並採用 SessionFactory 的 getCurrentSession()方法 獲得 Session 物件。
則不需要執行 session.close() 方法,通過這種方式獲得的Session 物件,會在關聯的事務結束(提交或回滾)時自動關閉。
更新資料的方法:
1): update() 方法,用於將遊離的物件恢復為持久狀態,同時進行資料庫更新操作。當引數物件的 OID 為 null 時會報錯異常
2):saveOrUpdate()方法,同時包含了save()與update()方法的功能,如果入參是瞬時狀態的物件,就呼叫 save()方法;如果入參是遊離狀態的物件,則呼叫update()方法。
3):merge()方法,能夠把作為引數傳入的遊離狀態物件的屬性 複製到一個擁有相同 OID 的持久狀態物件中,通過對持久狀態的物件的髒檢查實現更新操作,並返回該持久狀態物件;
如果無法從Session 快取或資料庫中載入到相應的持久狀態物件,即傳入的是瞬時物件,則建立其副本執行插入操作,並返回這一新的持久狀態物件。無論何種情況,傳入的物件狀態都不受影響。
案例目錄結構:
1):環境搭建前期準備:
目前以及後期需要的 JAR:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.3</version> </dependency> <!-- 新增Hibernate依賴 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.10.Final</version> </dependency> <!-- 新增Log4J依賴 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.6.4</version> </dependency> <!-- 新增javassist --> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.0.GA</version> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.0-api</artifactId> <version>1.0.1.Final</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <!-- mysql資料庫的驅動包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> </dependencies> <build> <!--載入我們的各種hbm.xml檔案,如果hbm.xml檔案在resources資料夾下面就不需要了--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build>
配置核心配置檔案:hibernate.cfg.xml (必須以 .cfg.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> <session-factory> <!--配置連線資料庫的四要素--> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://39.105.105.186:3306/MyBatisCode?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!--是否顯示底層生成的sql語句--> <property name="hibernate.show_sql">true</property> <!--是否格式化sql語句--> <property name="hibernate.format_sql">true</property> <!--方言設定--> <!--MySql 驅動程式 eg. mysql-connector-java-5.0.4-bin.jar--> <property name="dialect">org.hibernate.dialect.SQL/">MySQLDialect</property> <!--當前會話上下文--> <property name="current_session_context_class">thread</property> <!--hbm2ddl就是把xx.hbm.xml檔案中的配置生成資料庫中DDL(資料定義語言) create:每次執行都會刪除 上次生成的表,還會建立新的! update: 沒有表會自動建立,有表就增加資料! validate: 如果hbm檔案和資料庫中的欄位對應 就會新增, 否則丟擲異常! create-drop:每次執行都會刪除 上次生成的表,前提是sessionFactory關閉 --> <property name="hbm2ddl.auto">update</property> <!--載入需要的hbm.xml對映檔案--> <mapping resource="mapping/user.hbm.xml"/> </session-factory> </hibernate-configuration>
編寫對映檔案 user.hbm.xml (必須以 .hbm.xml 為字尾)
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- package: 需要對映的實體類所在包 class節點: name:對應的是實體類的類名,如果沒有書寫package,則必須是完整限定類名 table:資料庫中的表名,如果表名和實體類名一致,可以省略 id節點:表中的主鍵 generator:主鍵生成策略 ,主鍵由誰去建立?程式猿?Hibernate?資料庫 name:必須和實體類中的屬性名一致 column : 必須和資料庫中的列名一致,如果列名和屬性名一致,可以省略 --> <!--dynamic-update="false":預設非動態更新--> <hibernate-mapping package="com.mlq.bena"> <class name="com.mlq.bena.User" table="`user`" dynamic-update="true"> <id name="uId" column="uId"> <!--<generator class="assigned"/><!–主鍵生成策略–>--> <generator class="increment"></generator> </id> <property name="userName" column="userName"/> <property name="userPwd" column="userPwd"/> <property name="realName" column="realName"/> </class> </hibernate-mapping> <!--Oracle序列增長--> <!--<generator class="squence">--> <!--<param name="squence">SEQ_DEPTNO</param>--> <!--</generator>--> <!--資料庫中查詢最大值+1--> <!--<generator class="increment"></generator>--> <!--沒有制定使用那種方式:需要結合資料庫方言自增--> <!--<generator class="native"></generator>--> <!--uuid:生成32位字串--> <!--<generator class="uuid"></generator>-->
User 實體類:
package com.mlq.bena; import java.io.Serializable; public class User implements Serializable { private Integer uId; private String userName; private String userPwd; private String realName; @Override public String toString() { return "User{" + "uId=" + uId + ", userName='" + userName + '\'' + ", userPwd='" + userPwd + '\'' + ", realName='" + realName + '\'' + '}'; } public Integer getuId() { return uId; } public void setuId(Integer uId) { this.uId = uId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } }
BaseDao 層:
package com.mlq.bena; import com.mlq.uitl.SessionTool; import org.hibernate.Session; /** * 獲取連線的提升封裝 * @author asus */ public class BaseDao { public Session getSession() { return SessionTool.getSession(); } }
mapper 層:
package com.mlq.mapper; import com.mlq.bena.User; import javax.jws.soap.SOAPBinding; import java.io.Serializable; /** * @author asus */ public interface UserMapper { /** * 新增方法 * @param user */ public void addUser(User user); /** * 根據Id查詢 * @param id * @return */ public User getUser(Serializable id); /** * 根據Id查詢 * @param id * @return */ public User loadUser(Serializable id); /** * 修改使用者資訊:非動態更新 * 指的是在 對映檔案中修改:dynamic-update="false":預設非動態更新 * @param user */ public void updateUser(User user); /** * 修改使用者資訊:動態更新 * 指的是在 對映檔案中修改:dynamic-update="false":預設非動態更新 * @param user */ public void mergeUser(User user); /** * 刪除使用者資訊:需要首先呼叫查詢方法 * @param id */ public void delUser(Serializable id); /** * 刪除使用者資訊:根據自己定義的物件資訊刪除 * @param user */ public void delUser1(User user); /** * 當傳遞的 user 主鍵不生效的時便執行save方法 * @param user */ public void saveUpdate(User user); /** * 可以實現更新 也可以實現 save儲存 同樣根據主鍵是否有效 * 當主鍵不生效的時候變執行的是 save儲存 * @param user * @return */ public User testMerge(User user); }
mapperImpl:
package com.mlq.mapper; import com.mlq.bena.BaseDao; import com.mlq.bena.User; import com.mlq.uitl.SessionTool; import org.hibernate.Session; import java.io.Serializable; /** * @author asus */ public class UserMapperImpl extends BaseDao implements UserMapper { private Session session=null; @Override public void addUser(User user) { session= super.getSession(); session.save(user); } @Override public User getUser(Serializable id) { session= super.getSession(); return (User) session.get(User.class,id); } @Override public User loadUser(Serializable id) { session= super.getSession(); return (User) session.load(User.class,id); } @Override public void updateUser(User user) { session= super.getSession(); session.update(user); } @Override public void mergeUser(User user) { session= super.getSession(); session.merge(user); } @Override public void delUser(Serializable id) { session= super.getSession(); session.delete(this.loadUser(id)); } @Override public void delUser1(User user) { session= super.getSession(); session.delete(user); } @Override public void saveUpdate(User user) { session= super.getSession(); session.saveOrUpdate(user); } @Override public User testMerge(User user) { session= super.getSession(); User merge = (User)session.merge(user); return merge; } }
service 層:
package com.mlq.seivice; import com.mlq.bena.User; import java.io.Serializable; /** * @author asus */ public interface UserService { /** * 新增方法 * @param user */ public void addUser(User user); /** * 根據Id查詢 * @param id * @return */ public User getUser(Serializable id); /** * 根據Id查詢 * @param id * @return */ public User loadUser(Serializable id); /** * 資料更新 * @param user */ public void updUser(User user); /** * 非動態更新資料,會給所有欄位賦值 * 指的是在 對映檔案中修改:dynamic-update="false":預設非動態更新 * @param user */ public void updateUser(User user); /** * 修改使用者資訊:動態更新 * 指的是在 對映檔案中修改:dynamic-update="false":預設非動態更新 * @param user */ public void mergeUser(User user); /** * 刪除使用者資訊:需要首先呼叫查詢方法 * @param id */ public int delUser(Serializable id); /** * 刪除使用者資訊:根據自己定義的物件資訊刪除 * @param user */ public int delUser1(User user); /** * 當傳遞的 user 主鍵不生效的時便執行save方法 * @param user */ public void saveUpdate(User user); /** * 可以實現實現 更新 也可以實現 save儲存 同樣根據主鍵是否有效 * @param user * @return */ public User testMerge(User user); }
service impl:
package com.mlq.seivice.impl; import com.mlq.bena.User; import com.mlq.mapper.UserMapper; import com.mlq.mapper.UserMapperImpl; import com.mlq.seivice.UserService; import com.mlq.uitl.SessionTool; import com.sun.xml.internal.ws.handler.HandlerException; import org.hibernate.Transaction; import java.io.Serializable; /** * 實現資料查詢 * @author asus */ public class UserServiceImpl implements UserService { Transaction transaction=null; private UserMapperImpl userMapper=null; @Override public void addUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.addUser(user); transaction.commit(); }catch (HandlerException e) { e.printStackTrace(); transaction.rollback(); } } @Override public User getUser(Serializable id) { User user=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user = userMapper.getUser(id); transaction.commit(); }catch (HandlerException e) { e.printStackTrace(); transaction.rollback(); } return user; } @Override public User loadUser(Serializable id) { User user=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user = userMapper.loadUser(id); System.out.println(user+"-----------"); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } return user; } @Override public void updUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); User info = userMapper.loadUser(user.getuId()); info.setUserName(user.getUserName()); info.setUserPwd(user.getUserPwd()); info.setRealName(user.getRealName()); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public void updateUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.updateUser(user); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public void mergeUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.mergeUser(user); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public int delUser(Serializable id) { int count=0; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.delUser(id); transaction.commit(); count= 1; }catch (Exception e) { System.out.println("相愛相殺一場!!!"); count=0; e.printStackTrace(); transaction.rollback(); } return count; } @Override public int delUser1(User user) { int count=0; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.delUser1(user); transaction.commit(); count= 1; }catch (Exception e) { System.out.println("相愛相殺一場!!!"); count=0; e.printStackTrace(); transaction.rollback(); } return count; } @Override public void saveUpdate(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.saveUpdate(user); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public User testMerge(User user) { User user1=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user1 = userMapper.testMerge(user); transaction.commit(); }catch (Exception e) { System.out.println("相愛相殺一場!!!"); e.printStackTrace(); transaction.rollback(); } return user1; } }
uitl 獲取連線工具類:
package com.mlq.uitl; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * 讀取配置資訊 */ public class SessionTool { private static SessionFactory sessionFactory=null; private static Configuration configuration=null; static { System.out.println("靜態程式碼塊------"); configuration=new Configuration().configure(); sessionFactory=configuration.buildSessionFactory(); } public static Session getSession() { return sessionFactory.getCurrentSession(); } }
測試類:
package com.mlq; import com.mlq.bena.User; import com.mlq.seivice.impl.UserServiceImpl; import org.junit.Test; /** * 提取工具類的測試 */ public class HibernateDemo { /** * get()查詢 */ @Test public void getUser() { User user = new UserServiceImpl().getUser(42183); System.out.println(user); } /** * load()查詢 */ @Test public void loadUser() { new UserServiceImpl().loadUser(42); } /** * 更新操作 */ @Test public void updUser() { User user=new User(); user.setuId(42183); user.setUserName("aaa"); user.setUserPwd("bbb"); user.setRealName("vvv"); new UserServiceImpl().updUser(user); } //------------------動態與非動態注意檢視 控制檯列印的 SQL-------------------------------// /** * 更新操作:非動態更新 */ @Test public void updatedUser() { User user=new User(); user.setuId(42183); user.setUserName("aaa"); user.setUserPwd("bcb"); user.setRealName("vbv"); new UserServiceImpl().updateUser(user); } /** * 更新操作2:動態更新 */ @Test public void mergeUser() { User user=new User(); user.setuId(42184); user.setUserName("aaa"); user.setUserPwd("bcb"); user.setRealName("vbbbv"); new UserServiceImpl().mergeUser(user); } /** * 刪除使用者資訊:需要根據查詢來獲取使用者物件 然後刪除 */ @Test public void deleteUser() { int i = new UserServiceImpl().delUser(43420); System.out.println((i>0)?"刪除成功":"刪除失敗"); } /** * 刪除使用者資訊:根據自己定義的物件刪除 */ @Test public void deleteUser1() { User user=new User(); user.setuId(43417); int i = new UserServiceImpl().delUser1(user); System.out.println((i>0)?"刪除成功":"刪除失敗"); } //當傳遞的 user 主鍵不生效的時便執行save方法 @Test public void saveUpdate() { User user=new User(); user.setuId(42183); user.setUserName("修改了"); new UserServiceImpl().saveUpdate(user);//執行了Update方法更新 } //當傳遞的 user 主鍵不生效的時便執行save方法 @Test public void saveUpdate1() { User user=new User(); user.setUserName("修改了"); new UserServiceImpl().saveUpdate(user);//執行了save方法更新 } //當傳遞的 user 主鍵不生效的時便執行save方法,否則施行更新 @Test public void textMerge() { User user=new User(); user.setUserName("Merge正在執行儲存!!!"); User user1 = new UserServiceImpl().testMerge(user);//執行了save方法更新 System.out.println(user1); } @Test public void textMerge1() { User user=new User(); user.setuId(42183); user.setUserName("原來的模樣"); User user1 = new UserServiceImpl().testMerge(user);//執行了更新方法更新 System.out.println(user1); } }