如果對您有幫助,請點贊!
概述
WEB后端開發(fā),需要訪問數(shù)據(jù)庫。Hibernate是目前主流對象關(guān)系映射框架(ORM),對JDBC進(jìn)行了對象封裝,可以自動生成SQL語句,使得Java程序員可以使用對象編程思維來操縱數(shù)據(jù)庫。
本文講解Spring Boot 與Hibernate的集成。通過實戰(zhàn)完成數(shù)據(jù)庫的基本操作,如插入數(shù)據(jù)、查詢、更新、刪除數(shù)據(jù)。
適合讀者
- 具有Java編程基礎(chǔ)
- 具有數(shù)據(jù)庫基礎(chǔ)
- Spring Boot 及 Hibernate 小白
如果你對Spring Boot 完全不了解:請移步 spring boot 入門1:環(huán)境搭建及HelloWorld
開發(fā)環(huán)境
- windows 10
- JDK 1.8.0_25
- IDEA Community 2019.2 (社區(qū)版)
- IDEA 插件:Spring Assistant
- MySql 8.x
準(zhǔn)備工作
- 請自行安裝mysql數(shù)據(jù)庫,并創(chuàng)建一個數(shù)據(jù)庫
(也可以使用其他數(shù)據(jù)庫,如Oracle、DB2、MSSqlserver 等等,本文以mysql為例說明) - 請確保使用mysql客戶端工具,可以連接到數(shù)據(jù)庫
- 在創(chuàng)建項目過程中,可能需要聯(lián)網(wǎng),下載JAR包等資源
實戰(zhàn)
創(chuàng)建項目
首先在IDEA中創(chuàng)建一個項目 helloHibernate ,如下圖所示:

選擇項目中需要使用的組件
- Spring Web Starter:
- Spring Data JPA組件 :Spring Boot使用 Hibernate作為JPA實現(xiàn)(JPA-JAVA持久化API)
- MySQL Driver



項目創(chuàng)建完成后,打開pom.xml 文件,可以看到選擇的組件自動添加到了項目依賴中 。

配置數(shù)據(jù)庫訪問參數(shù)
打開application.properties文件 (該文件在 src\main\resources\目錄下)
配置數(shù)據(jù)庫訪問參數(shù),如下所示(請根據(jù)你的數(shù)據(jù)庫名稱、用戶、密碼等進(jìn)行修改):
# 以下參數(shù)定義了hibernate的行為:
# spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
# spring.jpa.database-platform=org.hibernate.dialect.MySQLInnoDBDialect
# hbm2ddl.auto參數(shù): 開發(fā)建議 update 或 create 自動測試建議 create-drop 生產(chǎn)環(huán)境建議 validate
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 數(shù)據(jù)庫的配置
# 配置數(shù)據(jù)庫驅(qū)動為mysql (如果使用其他數(shù)據(jù)庫,請更改驅(qū)動)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 配置數(shù)據(jù)庫連接,本示例使用helloworld數(shù)據(jù)庫,請更改為你自己創(chuàng)建的數(shù)據(jù)庫
spring.datasource.url=jdbc:mysql://localhost:3306/helloworld?serverTimezone=UTC
# 訪問數(shù)據(jù)庫的用戶名:請更改為你的數(shù)據(jù)庫用戶名
spring.datasource.username=root
#訪問數(shù)據(jù)庫的密碼,請更改為你的數(shù)據(jù)庫密碼
spring.datasource.password=123456
通過JAVA類定義表結(jié)構(gòu)
新建User.java類,并定義了兩個屬性,具體代碼如下:
@Entity注解,可以將類映射到數(shù)據(jù)庫表(user表)
@Id注解,將屬性映射為表的主鍵字段;@GeneratedValue注解表示該字段的值可以自動生成
@Column注解,將屬性映射為表的字段
//User.java
package com.example.hello.hibernate;
import javax.persistence.*;
@Entity
//@Table(name="my_user") //若表名與類名不同時,可指定表名
public class User {
@Id //聲明主KEY字段
@GeneratedValue
private Long id;
@Column //(name="user_name",nullable = false, unique = false) //可指定字段的屬性
private String userName;
@Column
private String address;
public User(){ //需要缺省構(gòu)建函數(shù)
}
public User(Long id, String userName, String address) {
this.id = id;
this.userName = userName;
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
定義操作User對象的接口
新建UserRepository.java, 并繼承JpaRepository接口
//UserRepository.java
package com.example.hello.hibernate;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
編寫JUnit測試代碼
在src\test\java目錄com.example.hello.hibernate包下,新建HibernateTests.java

代碼如下所示:
//HibernateTests.java
package com.example.hello.hibernate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class HibernateTests {
@Autowired
private UserRepository userRepository;
@Test
public void test() throws Exception {
userRepository.save(new User(null, "Jack" ,"重慶市"));
userRepository.save(new User(null, "Mary","四川省"));
userRepository.save(new User(null, "張三豐","重慶市"));
}
}
執(zhí)行JUnit測試代碼
在HibernateTests類上(或test方法上),右鍵執(zhí)行Run 菜單:即可執(zhí)行JUnit單元測試。
如果執(zhí)行正常,會顯示 √ 圖標(biāo),如下圖所示:

這時我們可以進(jìn)入數(shù)據(jù)庫,查看結(jié)果:

打開user表,可看到插入的記錄

在REST服務(wù)中,訪問數(shù)據(jù)庫
新建TestRestController.java

代碼如下所示:
package com.example.hello.hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestRestController {
@Autowired
private UserRepository userRepository;
@RequestMapping("/test") //url
public String test() {
userRepository.save(new User(null, "Jack" ,"重慶市"));
userRepository.save(new User(null, "Mary","四川省"));
userRepository.save(new User(null, "張三豐","重慶市"));
return "OK";
}
}
啟動REST服務(wù)(在Application.java上右鍵,點“ Run" 菜單),
通過瀏覽器訪問 REST服務(wù)地址 http://localhost:8080/test
若成功執(zhí)行,將顯示下圖界面:

進(jìn)入數(shù)據(jù)庫,查看結(jié)果如下圖所示:

查詢數(shù)據(jù)(查詢?nèi)繑?shù)據(jù)):
在TestRestController.java類中,增加如下方法:
import java.util.List;
@RequestMapping("/findall")
public List<User> testFindAll() {
List<User> listUser = userRepository.findAll();
return listUser;
}
重啟REST服務(wù):
通過瀏覽器訪問 REST服務(wù)地址 http://localhost:8080/findall
查詢結(jié)果將顯示在界面上:

查詢數(shù)據(jù)(根據(jù)ID查詢數(shù)據(jù)):
在TestRestController.java類中,增加一個查詢方法testFindByID(),代碼如下:
import java.util.Optional;
@RequestMapping("/findbyid")
public User testFindByID() {
try {
long id=3; //請?zhí)鎿Q成數(shù)據(jù)庫表中有的ID值
Optional< User> user= userRepository.findById(id);
return user.get();
}catch (Exception e){
return null;
}
}
重啟REST服務(wù):
通過瀏覽器訪問 REST服務(wù)地址 http://localhost:8080/findbyid
查詢結(jié)果將顯示在界面上:

自定義查詢數(shù)據(jù)
通過前面的示例,我們知道Spring Boot的JPI接口中,已經(jīng)包含了一些數(shù)據(jù)查詢方法。
當(dāng)然還可以自定義查詢(JPI): Hibernate會根據(jù)方法名,自動生成SQL語句:
- findXXX 查詢
- countXXX 計數(shù)
- deleteXXX 刪除
- 查詢前N條數(shù)據(jù)
自定義查詢數(shù)據(jù)(單一條件查詢:精確查詢)
在UserRepository類中,增加一個自定義查詢方法
//UserRepository.java
//自定義簡單查詢(JPI): Hibernate會根據(jù)方法名,自動生成SQL
//findByXXX (XXX=value) 單字段條件查詢
List<User> findByUserName(String userName); //根據(jù)用戶名進(jìn)行查詢
在TestRestController.java類中,增加一個查詢測試方法testFindByName(),代碼如下:
@RequestMapping("/findbyname")
public List<User> testFindByName() {
List<User> list= userRepository.findByUserName("張三豐");
return list;
}
以下是查詢結(jié)果:

自定義查詢數(shù)據(jù)(單一條件查詢:模糊查詢)
在UserRepository類中,增加一個自定義查詢方法
//findByXXXLike (XXX like value) 單字段條件查詢 (value可以使用%做為通配符)
List<User> findByUserNameLike(String userName);
以下是測試代碼(通過使用SQL的通配符,可以進(jìn)行模糊查詢):
List<User> list= userRepository.findByUserNameLike("張%");
查詢數(shù)據(jù)(組合條件查詢)
在UserRepository類中,增加一個自定義查詢方法
//findByXXXAndXXX | findByXXXOrXXX (XXX and|or XXX) 多字段條件查詢
List<User> findByUserNameLikeAndAddressLike(String userName,String address);
以下是測試代碼(通過使用SQL的通配符,可以進(jìn)行模糊查詢):
List<User> list= userRepository.findByUserNameLikeAndAddressLike("張%","重慶市");
查詢數(shù)據(jù)(排序)
在UserRepository類中,增加自定義查詢方法
//findByXXXOrderByXXX 排序
List<User> findByAddressOrderByUserName(String address); //正序
List<User> findByAddressOrderByUserNameDesc(String address); //倒序
以下是測試方法
List<User> list= userRepository.findByAddressOrderByUserName("重慶市");
List<User> list2= userRepository.findByAddressOrderByUserNameDesc("重慶市");
查詢數(shù)據(jù)(分頁查詢)
在UserRepository類中,增加自定義查詢方法
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
//Page<User> findALL(Pageable pageable); //這個方法基類中有,可以直接使用
Page<User> findByUserNameLike(String userName,Pageable pageable);
以下是測試方法
@RequestMapping("/page")
public Page<User> testPage() {
int nPage=0; //取第N頁,從0開始
int nSize=3; //每頁數(shù)據(jù)條數(shù)
//Pageable pageable = PageRequest.of(nPage,nSize); //不需要字段排序時,使用此方法
Sort sort = new Sort(Sort.Direction.ASC, "id");
Pageable pageable = PageRequest.of(nPage,nSize,sort); //需要排序時,使用此方法
Page<User> page= userRepository.findAll(pageable); //分頁查詢
return page;
}
計數(shù)查詢
Long countByUserName(String userName)
新增數(shù)據(jù)
//使用save方法(前面已經(jīng)有使用)
刪除數(shù)據(jù)
//deleteByXXX (語法與查詢相似)
Long deleteById(Long id);
更新數(shù)據(jù)
?
自定義SQL查詢
修改UserRepository接口,以增加一個SQL查詢接口方法findUserByName ()代碼如下:
//UserRepository.java
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
//UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select t from User t where t.userName like :userName") //如果是精確查詢,將like改為=
public List<User> findUserByName(@Param("userName") String userName);
}
在TestRestController.java類中,增加一個測試方法代碼如下:
@RequestMapping("/findbyname")
public List<User> testFindByName() {
List<User> list= userRepository.findUserByName("張三豐"); //對于like條件,可使用%進(jìn)行模糊查詢 例如 "張%"
return list;
}
自定義SQL:刪除
修改UserRepository接口,以增加一個SQL刪除數(shù)據(jù)接口方法deleteByName ()代碼如下:
//UserRepository.java
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
@Modifying //表明這是一個刪除或更新SQL,返回值類型為 int,返回刪除或更新的記錄數(shù)量
@Transactional //刪除或更新需要使用事務(wù)
@Query("delete from User t where t.userName like :userName") //如果是精確查詢,將like改為=
public int deleteByName(@Param("userName") String userName);
測試刪除,在TestRestController.java類中,增加一個測試方法代碼如下:
@RequestMapping("/deletebyname")
public int testDeleteByName() {
int n= userRepository.deleteByName("張三豐");
return n;
}
自定義SQL:更新、新增
(略)請參考刪除寫法,自行編寫
多表查詢方法1(SQL方式)
- 首先定義一個接口:包含查詢結(jié)果的字段
- 定義數(shù)據(jù)庫訪問接口(繼承JpaRepository接口)
- 在數(shù)據(jù)庫訪問接口中,增加多表查詢方法(在查詢中使用inner join)
多表查詢方法2(級聯(lián)查詢方式)
?
異構(gòu)數(shù)據(jù)庫多源支持
例如項目中,即有 mysql的查詢,也有Mongodb 的查詢。
?
下一篇 spring boot 從零開始入門5: RES服務(wù)接收J(rèn)SON參數(shù)自動轉(zhuǎn)換為JAVA對象