Hibernate框架
用於實現關係型數據庫訪問操作。例如Oracle、Mysql。
是基於ORM思想將jdbc進行了封裝,實現對象關係映射。
目標:將關係表中數據映射成Java中實體對象,程序員對對象操作從而實現對數據庫操作
Hibernate和MyBatis的區別
1.Hibernate複雜度比MyBatis高,功能多
2.Hibernate自動生成SQL,MyBatis編寫SQL
3.Hibernate關聯映射種類多,Mybatis簡單就@one和@Many
4.Hibernate提供了多種操作方式,HQL、Criteria、NativeSQL三種操作
5.Hibernate還封裝了緩存、延遲加載、持久化等特性
6.Hibernate直接實現對象到數據庫映射,Mybatis實現對象到SQL參數映射
Hibernate操作
1.導入Hibernate開發包、數據庫驅動包、junit測試包
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2.追加主配置文件hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect <!-- Mysql數據庫的翻譯,Oracle的就用Oracle的。。。 -->
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/test
</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 加載映射描述信息 -->
<mapping resource="hbm/Subject.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.根據操作表編寫Java實體類
public class Subject implements Serializable{
private Integer id;
private String name;
private Integer directionId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDirectionId() {
return directionId;
}
public void setDirectionId(Integer directionId) {
this.directionId = directionId;
}
}
4.根據表和類,編寫映射信息(XML或註解)此處使用XML的形式配置
<?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>
<class name="cn.xdl.entity.Subject" table="SUBJECT">
<id name="id" column="ID"></id> <!--主鍵 -->
<property name="name" column="NAME"></property>
<property name="directionId" column="DIRECTION_ID"></property>
</class>
</hibernate-mapping>
5.獲取Session數據庫操作對象進行操作
5.1封裝Util獲取Session
package cn.xdl.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
public static Session getSession() {
//加載主配置文件hibernate.cfg.xml
Configuration conf = new Configuration();
conf.configure("hibernate.cfg.xml");
//獲取SessionFactory
SessionFactory factory = conf.buildSessionFactory();
//獲取session
Session session = factory.openSession();
return session;
}
}
5.2創建測試類進行增刪查改的操作。
package ssh03;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.xdl.entity.Subject;
import cn.xdl.util.HibernateUtil;
public class TestSubject {
//xml文件映射基礎方法使用
//添加
@Test
public void test1(){
Subject subject = new Subject();
subject.setId(50);
subject.setName("JAVA");
subject.setDirectionId(2);
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
session.save(subject);
tx.commit();
session.close();
}
//修改
@Test
public void test2(){
Subject subject = new Subject();
subject.setId(50);
subject.setName("PYTHON");
subject.setDirectionId(2);
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
session.update(subject);
tx.commit();
session.close();
}
//根據id刪除
@Test
public void test3(){
Subject subject = new Subject();
subject.setId(50);
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
session.remove(subject);
tx.commit();
session.close();
}
//根據id查詢
@Test
public void test4(){
Session session = HibernateUtil.getSession();
Subject subject = (Subject)session.get(Subject.class, 50);
System.out.println(subject.getId()+" "+subject.getName());
session.close();
}
}
Hibernate主鍵生成
Hibernate框架集成了主鍵ID生成方法,在添加時有效。
可以在映射描述配置文件Subject.hbm.xml中指定以下類型。
-
identity
適用於MySQL、SQLServer等帶自動遞增類型的數據庫。在添加時,採用數據庫自動遞增生成ID值。
<id name="id" column="ID"> <generator class="identity"></generator> </id>
-
sequence
適用於Oracle、DB帶序列的數據庫。在添加時,採用指定序列生成ID值。
-
increment
適用於多種數據庫。在添加時,先查詢ID最大值,然後加1後進行插入。
-
native
根據dialect方言設置判斷,如果是Oracle就採用sequence,如果是MySQL就採用identity
-
uuid
添加時生成一個UUID字符串值做主鍵。
-
assigned
默認值,意思是Hibernate忽略不管理ID主鍵,需要程序員在代碼中設置ID值,否則不正常。
爲了方便程序員查看框架自行處理的sql語句可以在hibernate.cfg.xml主配置文件中開啓sql語句的輸出和格式化。有助於瞭解內部執行過程可以用於後期優化。
<!-- 後臺顯示框架處理的sql語句並格式化 -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
註解映射描述(是JPA的典型)
寫一個實體類,在實體類中使用註解進行映射描述
@Entity
@Table(name="SUBJECT")
public class Subject2 implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)//主鍵
@Column(name="ID")
private Integer id;
@Column(name="NAME")
private String name;
@Column(name="DIRECTION_ID")
private Integer directionId;
。。。省略getset方法自行生成
}
在hibernate.cfg.xml主配置文件中加載映射描述
<mapping class="cn.xdl.entity.Subject2"/>
測試類:
//註解映射用法 查詢,此處只舉例說明了查詢方法其他方法和配置xml文件相同
@Test
public void test1(){
Session session = HibernateUtil.getSession();
//load和get的區別在於查詢時是否延遲,load延遲查詢
Subject2 load = session.load(Subject2.class, 50);
System.out.println(load.getId()+" "+load.getName());
session.close();
}
結果:
Hibernate操作
Hibernate提供了HQL、Criteria、NativeSQL三種操作方式。
-
HQL語句
Hibernate Query Language,屬於面向對象查詢語言。
HQL語法結構與SQL相似,支持select...from...where...group by...having...order by...,區別如下:
SQL: select ID,NAME from DIRECTION
HQL: select id,name from Direction
HQL: from Direction
HQL: from Direction where name like ?
HQL: select count(*) from Direction
- HQL使用類名、屬性名;SQL使用表名、字段名
- HQL大小寫敏感,類名和屬性名與實際保持一致
- HQL語句不支持select *寫法,可以省略
- HQL語句不支持join...on結構的on子句
- HQL語句不支持數據庫特有函數和關鍵詞
通過Subject2實體類的註解映射描述進行HQL語句的操作。
//查詢所有
@Test
public void test2(){
Session session = HibernateUtil.getSession();
Query<Subject2> query = session.createQuery("from Subject2");
List<Subject2> list = query.getResultList();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId()+" "+subject2.getName());
}
session.close();
}
//jpa語法格式查詢name做條件帶參數的
@Test
public void test3(){
Session session = HibernateUtil.getSession();
Query<Subject2> query = session.createQuery("from Subject2 where name like ?1");
query.setParameter(1, "%JAVA%");
List<Subject2> list = query.getResultList();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId()+" "+subject2.getName());
}
session.close();
}
// Hibernate語法格式查詢name做條件帶參數的
@Test
public void test4() {
Session session = HibernateUtil.getSession();
Query<Subject2> query = session.createQuery("from Subject2 where name like :name");
query.setParameter("name", "%JAVA%");
List<Subject2> list = query.getResultList();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId() + " " + subject2.getName());
}
session.close();
}
// 單行等值查詢,單行可以使用uniqueResult()
@Test
public void test5() {
Session session = HibernateUtil.getSession();
Query<Subject2> query = session.createQuery("from Subject2 where id = :id");
query.setParameter("id",50);
Subject2 subject2 = query.uniqueResult();
System.out.println(subject2.getId()+" "+subject2.getName());
session.close();
}
//查詢總記錄數或者具體某一個值只需要在select後指定就行
@Test
public void test6() {
Session session = HibernateUtil.getSession();
Query<Long> query = session.createQuery("select count(*) from Subject2");
Long size = query.uniqueResult();
System.out.println("總記錄數:"+size);
session.close();
}
// 查詢所有信息,分頁語句具體實現和方言有關
//<property name="dialect">
//org.hibernate.dialect.MySQLDialect <!-- Mysql數據庫的翻譯,Oracle的就用Oracle的。。。 -->
//</property>
@Test
public void test7() {
Session session = HibernateUtil.getSession();
Query<Subject2> query = session.createQuery("from Subject2");
//設置分頁
query.setFirstResult(0);//設置抓取記錄起點,從0開始
query.setMaxResults(3);//設置抓取最大記錄數量
List<Subject2> list = query.getResultList();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId() + " " + subject2.getName());
}
session.close();
}
Native SQL
可以將原始SQL語句發送給數據庫執行。
package ssh03;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.query.NativeQuery;
import org.junit.Test;
import cn.xdl.entity.Subject2;
import cn.xdl.util.HibernateUtil;
public class TestSQL {
//查詢所有
@Test
public void test1(){
String sql = "select * from subject"; //表名
Session session = HibernateUtil.getSession();
NativeQuery nativeQuery = session.createNativeQuery(sql);
List<Object[]> resultList = nativeQuery.getResultList();//默認使用Object[] 數組類型
for (Object[] object : resultList) {
System.out.println(object[0]+" "+object[1]);
}
session.close();
}
@Test
public void test2(){
String sql = "select * from subject";
Session session = HibernateUtil.getSession();
NativeQuery nativeQuery = session.createNativeQuery(sql);
nativeQuery.addEntity(Subject2.class);//指定使用Subject2封裝一條記錄
List<Subject2> resultList = nativeQuery.getResultList();
for (Subject2 object : resultList) {
System.out.println(object.getId()+" "+object.getName());
}
session.close();
}
//查詢name做條件帶參數的
@Test
public void test3(){
String sql = "select * from subject where name like ?";
Session session = HibernateUtil.getSession();
NativeQuery nativeQuery = session.createNativeQuery(sql);
nativeQuery.setParameter(1, "%JAVA%");
nativeQuery.addEntity(Subject2.class);//指定使用Subject2封裝一條記錄
List<Subject2> resultList = nativeQuery.getResultList();
for (Subject2 object : resultList) {
System.out.println(object.getId()+" "+object.getName());
}
session.close();
}
//分頁查詢
@Test
public void test4(){
String sql = "select * from subject";
Session session = HibernateUtil.getSession();
NativeQuery nativeQuery = session.createNativeQuery(sql);
nativeQuery.addEntity(Subject2.class);//指定使用Subject2封裝一條記錄
//設置分頁參數
nativeQuery.setFirstResult(0);
nativeQuery.setMaxResults(3);
List<Subject2> resultList = nativeQuery.getResultList();
for (Subject2 object : resultList) {
System.out.println(object.getId()+" "+object.getName());
}
session.close();
}
}
實現底層語句和結果:
Hibernate操作(Criteria)
查詢操作,只是版本新舊問題,實現的查詢效果相同。
@Test //5之前版本應用
public void test1(){
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Subject2.class);
criteria.add(Restrictions.like("name", "JAVA"));//類視sql語句的where
criteria.addOrder(Order.asc("id"));//排序
List<Subject2> list = criteria.list();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId()+" "+subject2.getName());
}
session.close();
}
@Test //5版本之後應用
public void test2(){
Session session = HibernateUtil.getSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Subject2> criteriaQuery = builder.createQuery(Subject2.class);
//設置from、where、order
Root<Subject2> root = criteriaQuery.from(Subject2.class);
criteriaQuery.where(builder.like(root.get("name"), "%JAVA%"));
criteriaQuery.orderBy(builder.asc(root.get("id")));
//執行CriteriaQuery
Query<Subject2> query = session.createQuery(criteriaQuery);
List<Subject2> list = query.getResultList();
for (Subject2 subject2 : list) {
System.out.println(subject2.getId() + " " + subject2.getName());
}
session.close();
}
刪除操作
@Test//5版本之後應用
public void test3(){
Session session = HibernateUtil.getSession();
//增刪改必須開啓事務
Transaction tx = session.beginTransaction();
CriteriaBuilder builder = session.getCriteriaBuilder();
//創建刪除的criteria
CriteriaDelete<Subject> criteriaDelete =
builder.createCriteriaDelete(Subject.class);
//設置刪除哪些記錄
Root<Subject> root = criteriaDelete.from(Subject.class);
criteriaDelete.where(builder.like(root.get("name"), "hibernate%"));
//執行操作
Query<Subject> query = session.createQuery(criteriaDelete);
int size = query.executeUpdate();
System.out.println("刪除的記錄條數:"+size);
tx.commit();//提交事務
session.close();
}