什麼是Hibernatejava
咱們能夠從度娘上摘抄這樣有關Hibernate的介紹:mysql
Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,它將POJO與數據庫表創建映射關係,是一個全自動的orm框架,hibernate能夠自動生成SQL語句,自動執行,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。Hibernate能夠應用在任何使用JDBC的場合,既能夠在Java的客戶端程序使用,也能夠在Servlet/JSP的Web應用中使用。程序員
從中,咱們能夠得出這樣的結論:Hibernate是一個輕量級的JDBC封裝,也就是說,咱們可使用Hibernate來完成原來咱們使用JDBC完成的操做,也就是與數據庫的交互操做。它是在dao層去使用的。web
什麼是ORMsql
對象關係映射(英語:Object Relation Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程序技術,用於實現面向對象編程語言裏不一樣類型系統的數據之間的轉換。 數據庫
對象-關係映射,是隨着面向對象的軟件開發方法發展而產生的。面向對象的開發方法是當今企業級應用開發環境中的主流開發方法,關係數據庫是企業級應用環境中永久存放數據的主流數據存儲系統。對象和關係數據是業務實體的兩種表現形式,業務實體在內存中表現爲對象,在數據庫中表現爲關係數據。內存中的對象之間存在關聯和繼承關係,而在數據庫中,關係數據沒法直接表達多對多關聯和繼承關係。所以,對象-關係映射(ORM)系統通常以中間件的形式存在,主要實現程序對象到關係數據庫數據的映射。 編程
ORM模型的簡單性簡化了數據庫查詢過程。使用ORM查詢工具,用戶能夠訪問指望數據,而沒必要理解數據庫的底層結構。 小程序
簡單來講,咱們使用ORM能夠將咱們的對象(或類)去進行映射,使得咱們能夠去操做對象就能完成對錶的操做。安全
爲何使用Hibernate框架session
緣由以下:
總結:Hibernate是企業級開發中的主流框架,映射的靈活性很出色。它支持不少關係型數據庫。
Hiberate框架學習目標
因爲以前學過Hiberate框架,因此這就等因而在複習了。對於Hiberate框架的學習重點,能夠總結爲:
Hibernate的體系結構:
Hibernate開發步驟:
介紹完Hibernate框架以後,咱們來快速入門Hibernate,對其有一個直觀的瞭解。
下載Hibernate
可去官網下載Hibernate,我下載的是
因此,以後有關Hibernate的系列文章都是以這個版本爲藍圖展開的。下載解壓縮以後,能夠看到以下目錄結構:
其中,在lib/required目錄下,包含運行Hibernate項目必須的jar包有:
建立數據庫與表
正如前面所說,Hibernate是一個輕量級的JDBC封裝,也就是說,咱們可使用Hibernate來完成原來咱們使用JDBC完成的操做,也就是與數據庫的交互操做。因此咱們首先要建立數據庫與表,這裏我使用的數據庫是mysql。
create database hibernateTest;
use hibernateTest;
create table t_customer( id int primary key auto_increment, name varchar(20), address varchar(50) );
建立實體類
首先在Eclipse上建立一個Dynamic Web Project,好比我建立的是hibernate_demo1,而後再切到Java透視圖。這兒咱們在cn.itheima.domain包中建立一個實體類——Customer.java。
public class Customer {
private int id;
private String name;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
}
}
導入Hibernate框架相關依賴jar包
首先導入lib/required目錄下全部的jar包:
再導入mysql數據庫的驅動jar包:
最後導入日誌相關的jar包:
導入完日誌相關的jar包以後,咱們還須將project/etc/log4j.properties文件導入到工程hibernate_demo1的src目錄下,這樣工程的整個結構就爲:
Hibernate的相關配置文件
準備好以上工做以後,咱們終於要踏入Hibernate的學習中了。首先咱們要編寫Hibernate的相關配置文件,Hibernate的相關配置文件分爲兩種:
有關這兩個配置文件的詳細介紹,咱們後面會給你們講解,若是就在這裏弄的話,違背了個人初衷了,本文只是在教初學者怎樣快速入門Hibernate。
映射配置文件
首先咱們要學會如何編寫映射配置文件,你們要知道編寫完的映射配置文件應與實體類在同一個包下,而且名稱應是類名.hbm.xml,因此咱們要在cn.itheima.domain包下建立一個Customer.hbm.xml文件,可是它的約束應該怎麼寫呢?能夠在Hibernate的核心jar包——hibernate-core-5.0.7.Final.jar的org.hibernate包下查找到hibernate-mapping-3.0.dtd文件,打開該文件,找到以下內容:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
而後複製黏貼到Customer.hbm.xml文件中。
這裏我先給出Customer.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="cn.itheima.domain">
<!-- name:即實體類的全名 table:映射到數據庫裏面的那個表的名稱 catalog:數據庫的名稱 -->
<class name="Customer" table="t_customer" catalog="hibernateTest">
<!-- class下必需要有一個id的子元素 -->
<!-- id是用於描述主鍵的 -->
<id name="id" column="id">
<!-- 主鍵生成策略 -->
<generator class="native"></generator>
</id>
<!-- 使用property來描述屬性與字段的對應關係 若是length忽略不寫,且你的表是自動建立這種方案,那麼length的默認長度是255 -->
<property name="name" column="name" length="20"></property>
<property name="address" column="address" length="50"></property>
</class>
</hibernate-mapping>
核心配置文件
核心配置文件主要是Hibernate框架所使用的,它主要包含了鏈接數據庫的相關信息和Hibernate的相關配置等。
如今咱們要學會如何編寫Hibernate核心配置文件,你們也要知道編寫完的核心配置文件應在src目錄下,而且名稱應是hibernate.cfg.xml,因此咱們要在src目錄下建立一個hibernate.cfg.xml文件,可是它的約束應該怎麼寫呢?能夠在Hibernate的核心jar包——hibernate-core-5.0.7.Final.jar的org.hibernate包下查找到hibernate-configuration-3.0.dtd文件,打開該文件,找到以下內容:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
而後複製黏貼到hibernate.cfg.xml文件中。
在這個文件中到底如何配置暱?咱們能夠參考hibernate-release-5.0.7.Final\project\etc\hibernate.properties文件。這裏我先給出hibernate.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>
<!-- 配置關於數據庫鏈接的四個項:driverClass url username password -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernateTest</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">yezi</property>
<!-- 能夠將向數據庫發送的SQL語句顯示出來 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL語句 -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置hibernate的映射文件所在的位置 -->
<mapping resource="cn/itheima/domain/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
Hibernate快速入門開發測試
在cn.itheima.test包下建立一個單元測試類——HibernateTest1.java。
public class HibernateTest1 {
// 保存一個Customer
@Test
public void saveCustomerTest() {
// 建立一個Customer
Customer c = new Customer();
c.setName("葉子");
c.setAddress("武漢");
// 使用Hibernate的API來完成將Customer信息保存到mysql數據庫中的操做
Configuration config = new Configuration().configure(); // Hibernate框架加載hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession(); // 至關於獲得一個Connection
// 開啓事務
session.beginTransaction();
// 操做
session.save(c);
// 事務提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
// 根據id查詢一個Customer對象
@Test
public void findCustomerByIdTest() {
Configuration config = new Configuration().configure(); // Hibernate框架加載hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession(); // 至關於獲得一個Connection
// 開啓事務
session.beginTransaction();
// 根據業務來編寫代碼
// Customer c = session.get(Customer.class, 1);
Customer c = session.load(Customer.class, 1);
System.out.println(c.getName());
// 事務提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
// 修改操做
@Test
public void updateCustomerTest() {
Configuration config = new Configuration().configure(); // Hibernate框架加載hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession(); // 至關於獲得一個Connection
// 開啓事務
session.beginTransaction();
// 根據業務來編寫代碼
Customer c = session.get(Customer.class, 1);
c.setName("鄭敏");
session.update(c); // 修改操做
// 事務提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
// 刪除操做---根據id進行刪除
@Test
public void deleteCustomerTest() {
Configuration config = new Configuration().configure(); // Hibernate框架加載hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession(); // 至關於獲得一個Connection
// 開啓事務
session.beginTransaction();
// 根據業務來編寫代碼
Customer c = session.get(Customer.class, 1);
session.delete(c); // 刪除操做
// 事務提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
// 查詢全部Customer
@Test
public void findAllCustomerTest() {
Configuration config = new Configuration().configure(); // Hibernate框架加載hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession(); // 至關於獲得一個Connection
// 開啓事務
session.beginTransaction();
// 根據業務來編寫代碼
Query query = session.createQuery("from Customer"); // HQL語句,它相似於SQL語句
List<Customer> list = query.list();
System.out.println(list);
// 事務提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
測試如若都無任何問題,則咱們就算入門Hibernate了。
Hibernate執行原理總結
可從度娘上摘抄到以下文字:
前面咱們寫了一個Hibernate入門的小程序。如今咱們來寫第二個Hibernate程序——實現對數據庫完整的操做(CRUD)。
咱們首先建立一個工具類——HibernateUtils.java,該工具類的做用專門用來獲取全局惟一的SessionFactory,以及從全局惟一的SessionFactory中打開一個Session。
public class HibernateUtils {
// SessionFactory全局只須要有一個就能夠了,由於它的建立和銷燬須要消耗大量的資源,初始化信息會比較多,而且它是線程安全的,能夠在多線程的環境下使用它
private static SessionFactory sessionFactory;
static {
// 初始化SessionFactory方式一:
/* Configuration cfg = new Configuration(); // 表明配置文件的一個對象 cfg.configure(); // 讀取默認的配置文件(hibernate.cfg.xml) // cfg.configure("hibernate.cfg.xml"); // 讀取指定位置的配置文件 sessionFactory = cfg.buildSessionFactory(); */
// 初始化SessionFactory方式二:
sessionFactory = new Configuration() //
.configure() //
.buildSessionFactory(); // 方法鏈
}
/** * 獲取全局惟一的SessionFactory * * @return */
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/** * 從全局惟一的SessionFactory中打開一個Session * * @return */
public static Session openSession() {
return sessionFactory.openSession();
}
}
思考一個問題,若咱們要編寫代碼實現對數據庫完整的操做,那麼就一定涉及到分頁查詢,要實現分頁查詢,咱們必定要弄清楚分頁設計結構圖。因此咱們還要建立一個類——QueryResult.java,用於封裝查詢結果。
public class QueryResult {
private int count; // 總記錄數
private List list; // 一頁的數據
public QueryResult(int count, List list) {
this.count = count;
this.list = list;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
}
最後,咱們建立一個類——UserDao.java。UserDao類裏面編寫代碼實現對數據庫完整的操做(CRUD)。
public class UserDao {
/* * 保存 */
public void save(User user) {
Session session = HibernateUtils.openSession();
try {
Transaction tx = session.beginTransaction(); // 開啓事務
session.save(user);
tx.commit(); // 提交事務
} catch (RuntimeException e) {
session.getTransaction().rollback(); // 回滾事務
throw e;
} finally {
session.close(); // 關閉session
}
}
/* * 更新 */
public void update(User user) {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(user);// 操做
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
/* * 刪除 */
public void delete(int id) {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Object user = session.get(User.class, id); // 要先獲取到這個對象
session.delete(user); // 刪除的是實體對象
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
/* * 根據id查詢一個User數據 */
public User getById(int id) {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
User user = (User) session.get(User.class, id);// 操做
tx.commit();
return user;
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
/* * 查詢全部 */
public List<User> findAll() {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 方式一:使用HQL語句
List<User> list = session.createQuery("FROM User").list(); // 使用HQL查詢
tx.commit();
return list;
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
/** * 分頁的查詢數據列表 * @param firstResult 從結果列表中的哪一個索引開始取數據 * @param maxResults 最多取多少條數據 * @return 一頁的數據列表 */
@SuppressWarnings("unchecked")
public QueryResult findAll(int firstResult, int maxResults) {
Session session = HibernateUtils.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 查詢一頁的數據列表
// 方式一:
// Query query = session.createQuery("FROM User");
// query.setFirstResult(firstResult);
// query.setMaxResults(maxResults);
// List<User> list = query.list(); // 使用HQL查詢
// 方式二:方法鏈
List<User> list = session.createQuery( //
"FROM User") //
.setFirstResult(firstResult) //
.setMaxResults(maxResults) //
.list();
// 查詢總記錄數
// session.createQuery("SELECT COUNT(*) FROM User").list().get(0);
// Long count = (Long) session.createQuery("SELECT COUNT(*) FROM User").uniqueResult();
Long count = (Long) session.createQuery( //
"SELECT COUNT(*) FROM User") //
.uniqueResult();
tx.commit();
// 返回結果
return new QueryResult(count.intValue(), list);
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
}
在以下兩個方法中:
public List<User> findAll()
咱們使用到了Hibernate查詢語句——HQL(Hibernate Query Language),後面將會詳細講解,這裏稍微瞭解一下便可,咱們只要會用就好。
HQL(Hibernate Query Language)與SQL類似,查詢的是對象和對象中的屬性,關鍵字不區分大小寫,但類名與屬性名區分大小寫;而SQL查詢的是表和表中的字段,一樣也不區分大小寫。
接下來,爲方便測試,咱們使用單元測試來測試以上編寫的代碼。咱們只要右鍵點擊UserDao類→New→JUnit Test Case,以下:
接下來會彈出以下對話框:
這是要幫咱們自動建立UserDao測試類的節奏。
接着點擊Next按鈕,在彈出的對話框中選中咱們要測試的UserDao類中的方法。
最後點擊Finish完成,這時Eclipse就幫咱們自動建立UserDao類的測試類
——UserDaoTest.java了,而後咱們再在其中編寫測試代碼。
public class UserDaoTest {
private UserDao userDao = new UserDao();
@Test
public void testSave_1() {
User user = new User();
user.setName("張三");
// 保存
userDao.save(user);
}
@Test
public void testGetById() {
User user = userDao.getById(1);
System.out.println(user);
}
@Test
public void testUpdate() {
// 從數據庫中獲取一條存在的數據
User user = userDao.getById(1);
user.setName("李四");
// 更新
userDao.update(user);
}
@Test
public void testDelete() {
userDao.delete(1);
}
// -------------------------
@Test
public void testSave_25() {
for (int i = 1; i <= 25; i++) {
User user = new User();
user.setName("test_" + i);
userDao.save(user); // 保存
}
}
@Test
public void testFindAll() {
List<User> list = userDao.findAll();
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testFindAllIntInt() {
// 查詢
// QueryResult qr = userDao.findAll(0, 10); // 第1頁,每頁10條
// QueryResult qr = userDao.findAll(10, 10); // 第2頁,每頁10條
QueryResult qr = userDao.findAll(20, 10); // 第3頁,每頁10條
// 顯示結果
System.out.println("總記錄數:" + qr.getCount());
for (User user : (List<User>) qr.getList()) {
System.out.println(user);
}
}
}
測試經過,Hibernate入門完結!