ORM,Object Relation Mapping侦讨,即對(duì)象關(guān)系映射驶冒。Hibernate就是ORM的實(shí)現(xiàn)苟翻,使對(duì)象在數(shù)據(jù)庫(kù)的存儲(chǔ)和獲取非常的方便。
1.Hibernate開發(fā)流程
1.1 引入jar文件
hibernate3.jar核心 + required 必須引入的(6個(gè)) + jpa 目錄 + 數(shù)據(jù)庫(kù)驅(qū)動(dòng)包
1.2 寫對(duì)象類
Employee.java
public class Employee {
private int empId;
private String empName;
private Date workDate;
}
1.3 配置對(duì)象的映射
Employee.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">
<hibernate-mapping package="cn.itcast.a_hello">
<class name="Employee" table="employee">
<!-- 主鍵 骗污,映射-->
<id name="empId" column="id">
<generator class="native"/>
</id>
<!-- 非主鍵崇猫,映射 -->
<property name="empName" column="empName"></property>
<property name="workDate" column="workDate"></property>
</class>
</hibernate-mapping>
1.4 主配置文件
hibernate.cfg.xml
<!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>
<!-- 數(shù)據(jù)庫(kù)連接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.show_sql">true</property>
<!-- 加載所有映射 -->
<mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
1.5 測(cè)試
App.java
public class App {
@Test
public void testHello() throws Exception {
// 對(duì)象
Employee emp = new Employee();
emp.setEmpName("班長(zhǎng)");
emp.setWorkDate(new Date());
// 獲取加載配置文件的管理類對(duì)象
Configuration config = new Configuration();
config.configure(); // 默認(rèn)加載src/hibenrate.cfg.xml文件
// 創(chuàng)建session的工廠對(duì)象
SessionFactory sf = config.buildSessionFactory();
// 創(chuàng)建session (代表一個(gè)會(huì)話,與數(shù)據(jù)庫(kù)連接的會(huì)話)
Session session = sf.openSession();
// 開啟事務(wù)
Transaction tx = session.beginTransaction();
//保存-數(shù)據(jù)庫(kù)
session.save(emp);
// 提交事務(wù)
tx.commit();
// 關(guān)閉
session.close();
sf.close();
}
}
2. Hibernate Api
2.1 Configuration
配置管理類對(duì)象
config.configure(); 加載主配置文件的方法(hibernate.cfg.xml)
默認(rèn)加載src/hibernate.cfg.xml
config.configure(“cn/config/hibernate.cfg.xml”); 加載指定路徑下指定名稱的主配置文件
config.buildSessionFactory(); 創(chuàng)建session的工廠對(duì)象
2.2 SessionFactory
session的工廠(或者說(shuō)代表了這個(gè)hibernate.cfg.xml配置文件)
sf.openSession(); 創(chuàng)建一個(gè)sesison對(duì)象
sf.getCurrentSession(); 創(chuàng)建session或取出session對(duì)象
2.3 Session
session對(duì)象維護(hù)了一個(gè)連接(Connection), 代表了與數(shù)據(jù)庫(kù)連接的會(huì)話需忿。
Hibernate最重要的對(duì)象: 只用使用hibernate與數(shù)據(jù)庫(kù)操作诅炉,都用到這個(gè)對(duì)象
session.beginTransaction(); 開啟一個(gè)事務(wù); hibernate要求所有的與數(shù)據(jù)庫(kù)的操作必須有事務(wù)的環(huán)境屋厘,否則報(bào)錯(cuò)涕烧!
更新:
session.save(obj); 保存一個(gè)對(duì)象
session.update(emp); 更新一個(gè)對(duì)象
session.saveOrUpdate(emp); 保存或者更新的方法:
沒有設(shè)置主鍵,執(zhí)行保存擅这;有設(shè)置主鍵澈魄,執(zhí)行更新操作; 如果設(shè)置主鍵不存在報(bào)錯(cuò)!
主鍵查詢:
session.get(Employee.class, 1); 主鍵查詢
session.load(Employee.class, 1); 主鍵查詢 (支持懶加載)
2.4 Transaction
hibernate事務(wù)對(duì)象
3.Hibernate.cfg.xml 主配置
主配置文件中主要配置:數(shù)據(jù)庫(kù)連接信息仲翎、其他參數(shù)痹扇、映射信息!
3.1 數(shù)據(jù)庫(kù)連接參數(shù)配置
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常溯香,一個(gè)session-factory節(jié)點(diǎn)代表一個(gè)數(shù)據(jù)庫(kù) -->
<session-factory>
<!-- 1. 數(shù)據(jù)庫(kù)連接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
數(shù)據(jù)庫(kù)方言配置鲫构, hibernate在運(yùn)行的時(shí)候,會(huì)根據(jù)不同的方言生成符合當(dāng)前數(shù)據(jù)庫(kù)語(yǔ)法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相關(guān)配置 -->
<!-- 2.1 顯示hibernate在運(yùn)行時(shí)候執(zhí)行的sql語(yǔ)句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 2.3 自動(dòng)建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 3. 加載所有映射
<mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>
-->
</session-factory>
</hibernate-configuration>
4.映射配置
- 普通字段類型
- 主鍵映射
單列主鍵映射
多列作為主鍵映射
主鍵生成策略玫坛,查看api:org.hibernate.id.factory.DefaultIdentifierGeneratorFactory
<?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">
<!-- 映射文件: 映射一個(gè)實(shí)體類對(duì)象结笨; 描述一個(gè)對(duì)象最終實(shí)現(xiàn)可以直接保存對(duì)象數(shù)據(jù)到數(shù)據(jù)庫(kù)中。 -->
<!--
package: 要映射的對(duì)象所在的包(可選,如果不指定,此文件所有的類都要指定全路徑)
auto-import 默認(rèn)為true湿镀, 在寫hql的時(shí)候自動(dòng)導(dǎo)入包名
如果指定為false, 再寫hql的時(shí)候必須要寫上類的全名炕吸;
如:session.createQuery("from cn.itcast.c_hbm_config.Employee").list();
-->
<hibernate-mapping package="cn.itcast.c_hbm_config" auto-import="true">
<!--
class 映射某一個(gè)對(duì)象的(一般情況,一個(gè)對(duì)象寫一個(gè)映射文件勉痴,即一個(gè)class節(jié)點(diǎn))
name 指定要映射的對(duì)象的類型
table 指定對(duì)象對(duì)應(yīng)的表赫模;
如果沒有指定表名,默認(rèn)與對(duì)象名稱一樣
-->
<class name="Employee" table="employee">
<!-- 主鍵 蒸矛,映射-->
<id name="empId" column="id">
<!--
主鍵的生成策略
identity 自增長(zhǎng)(mysql,db2)
sequence 自增長(zhǎng)(序列)瀑罗, oracle中自增長(zhǎng)是以序列方法實(shí)現(xiàn)
native 自增長(zhǎng)【會(huì)根據(jù)底層數(shù)據(jù)庫(kù)自增長(zhǎng)的方式選擇identity或sequence】
如果是mysql數(shù)據(jù)庫(kù), 采用的自增長(zhǎng)方式是identity
如果是oracle數(shù)據(jù)庫(kù), 使用sequence序列的方式實(shí)現(xiàn)自增長(zhǎng)
increment 自增長(zhǎng)(會(huì)有并發(fā)訪問(wèn)的問(wèn)題雏掠,一般在服務(wù)器集群環(huán)境使用會(huì)存在問(wèn)題斩祭。)
assigned 指定主鍵生成策略為手動(dòng)指定主鍵的值
uuid 指定uuid隨機(jī)生成的唯一的值
foreign (外鍵的方式, one-to-one講)
-->
<generator class="uuid"/>
</id>
<!--
普通字段映射
property
name 指定對(duì)象的屬性名稱
column 指定對(duì)象屬性對(duì)應(yīng)的表的字段名稱乡话,如果不寫默認(rèn)與對(duì)象屬性一致摧玫。
length 指定字符的長(zhǎng)度, 默認(rèn)為255
type 指定映射表的字段的類型,如果不指定會(huì)匹配屬性的類型
java類型: 必須寫全名
hibernate類型: 直接寫類型蚊伞,都是小寫
-->
<property name="empName" column="empName" type="java.lang.String" length="20"></property>
<property name="workDate" type="java.util.Date"></property>
<!-- 如果列名稱為數(shù)據(jù)庫(kù)關(guān)鍵字席赂,需要用反引號(hào)或改列名吮铭。 -->
<property name="desc" column="`desc`" type="java.lang.String"></property>
</class>
</hibernate-mapping>
5.復(fù)合主鍵映射
// 復(fù)合主鍵類
public class CompositeKeys implements Serializable{
private String userName;
private String address;
// .. get/set
}
public class User {
// 名字跟地址时迫,作為復(fù)合主鍵颅停,不會(huì)重復(fù)
private CompositeKeys keys;
private int age;
}
User.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">
<hibernate-mapping package="cn.itcast.d_compositeKey" auto-import="true">
<class name="User">
<!-- 復(fù)合主鍵映射 -->
<composite-id name="keys">
<key-property name="userName" type="string"></key-property>
<key-property name="address" type="string"></key-property>
</composite-id>
<property name="age" type="int"></property>
</class>
</hibernate-mapping>
App2.java
public class App2 {
private static SessionFactory sf;
static {
// 創(chuàng)建sf對(duì)象
sf = new Configuration()
.configure()
.addClass(User.class) //(測(cè)試) 會(huì)自動(dòng)加載映射文件:Employee.hbm.xml
.buildSessionFactory();
}
//1. 保存對(duì)象
@Test
public void testSave() throws Exception {
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
// 對(duì)象
CompositeKeys keys = new CompositeKeys();
keys.setAddress("廣州棠東");
keys.setUserName("Jack");
User user = new User();
user.setAge(20);
user.setKeys(keys);
// 保存
session.save(user);
tx.commit();
session.close();
}
@Test
public void testGet() throws Exception {
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
//構(gòu)建主鍵再查詢
CompositeKeys keys = new CompositeKeys();
keys.setAddress("廣州棠東");
keys.setUserName("Jack");
// 主鍵查詢
User user = (User) session.get(User.class, keys);
// 測(cè)試輸出
if (user != null){
System.out.println(user.getKeys().getUserName());
System.out.println(user.getKeys().getAddress());
System.out.println(user.getAge());
}
tx.commit();
session.close();
}
}