SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂)
當前環境說明:
Windows10_64
Maven3.x
JDK1.8
MySQL5.6
SpringToolSuite4(Spring官方提供的開發工具,實際就是一個Eclipse)
一.整合JdbcTemplate
1.概述
在實際專案中,在對資料庫訪問層對資料庫進行操作時,大部分時候我們都用的MyBatis/Hibernate,但是偶爾會有用到使用JDBC的時候,一般使用JDBC的話要么就自己封裝一個JDBC連接池進行使用,要么就是使用Apache Common 提供的 DbUtils 工具類,還有個就是Spring JDBC ,提供的JdbcTemplate 工具類,
Spring屬于一堆疊式框架,針對JAVAEE三層中的每一層,都提供了解決技術,在DAO層中Spring中使用JdbcTemplate完成技術需求,(詳情請關注后續發表Spring集)
1 JdbcTemplate中常用類介紹: 2 DriverManagerDataSource類:DataSource連接池的實作子類 3 作用:主要是設定連接資料庫的相關資訊,如:連接地址、用戶名、密碼等 4 常用方法: 5 setDriverClassName(……):設定驅動類 6 setUsername(……):設定用戶名 7 setPassword(……):設定密碼 8 setUrl(……):設定連接地址 9 JdbcTemplate類: 10 作用:由Spring提供的JDBC操作模板類,用于完成CURD操作 11 常用構造方法: 12 JdbcTemplate(DataSource dataSource):創建物件并指定連接管理源 13 常用其他方法: 14 update(……):執行增、刪、改,回傳值為int型別,表示結果影響行數, 15 queryXXX(……);執行查詢,更多請關注博主Spring全集案例
2.準備作業
- 創建資料庫,

- 新增對應資料庫物體類,
1 @Data 2 @AllArgsConstructor 3 @NoArgsConstructor 4 public class Person { 5 private Integer id; 6 private String name; 7 private String password; 8 }
- 修改pom.xml引入依賴
SpringBoot引入MySQL驅動默認版本為8.x,可以手動配置版本,
1 <!-- SpringBoot整合JdbcTemplate --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-jdbc</artifactId> 5 </dependency> 6 7 <!-- MySQL驅動(SpringBoot默認引入版本為8.x)手動配置版本 --> 8 <dependency> 9 <groupId>mysql</groupId> 10 <artifactId>mysql-connector-java</artifactId> 11 <scope>runtime</scope> 12 </dependency>
- 修改application.yml檔案添加資料源配置
1 spring: 2 datasource: 3 #根據MySQL版本配置驅動類5.x----8.x 驅動類“com.mysql.jdbc.Driver” 或 “com.mysql.cj.jdbc.Driver”, 4 driver-class-name: com.mysql.cj.jdbc.Driver 5 #useSSL:SSL協議提供服務主要作用:(不建議在沒有服務器身份驗證的情況下建立SSL連接,) 6 # 1)認證用戶服務器,確保資料發送到正確的服務器; . 7 # 2)加密資料,防止資料傳輸途中被竊取使用; 8 # 3)維護資料完整性,驗證資料在傳輸程序中是否丟失; 9 #serverTimezone:設定時區,不設定會報錯,GMT%2B8:東八區北京時間 Asia/Shanghai:上海時間 10 #useServerPrepStmts:在url中給出useServerPrepStmts=true引數,開啟預編譯(默認PS是關閉的) 11 #allowMultiQueries:設定為true,開啟批量執行sql的開關,更多請持續關注博主檔案 12 url: jdbc:mysql://localhost:3306/springboot?useSSL=false&serverTimezone=GMT%2B8 13 username: root 14 password: xsge
3.整合實作
- 撰寫DAO層基礎的CURD,
使用注解@Repository標注為Spring--DAO層組件,注入JdbcTemplate物件
BeanPropertyRowMapper是JdbcTemplate提供的一個結果集處理器類,是RowMapper結果集處理器介面的實作,
注意:兩個查詢方法不一樣
1 @Repository // Spring注解標注DAO層組件 2 public class PersonDao{ 3 4 @Autowired // 注入jdbcTemplate 5 private JdbcTemplate jdbcTemplate; 6 7 /** 8 * 插入資料 9 */ 10 public void insertPerson(Person p) { 11 jdbcTemplate.update("INSERT INTO person(name,password) VALUES (?,?)", 12 p.getName(),p.getPassword()); 13 } 14 /** 15 * 根據ID查詢 16 * 方法queryForObject可以查詢單行單列,也可以查詢單行多列 17 * 引數1:SQL 18 * 引數2:一個型別 或者 一個結果集處理器(取決于查詢的結果和需求) 19 * 引數3:可變引數 20 */ 21 public Person selectPersonById(Integer id) { 22 Person person = jdbcTemplate.queryForObject("SELECT * FROM person WHERE id =?", 23 new BeanPropertyRowMapper<Person>(Person.class), id); 24 return person; 25 } 26 /** 27 * 查詢所有 28 * 方法query可以查詢多行多列, 29 * 引數1:SQL 30 * 引數2:一個結果集處理器(取決于查詢的結果和需求) 31 * 引數3:可變引數 32 */ 33 public List<Person> selectPersonList() { 34 List<Person> personList = jdbcTemplate.query("SELECT * FROM person", 35 new BeanPropertyRowMapper<Person>(Person.class)); 36 return personList; 37 } 38 39 }
- 撰寫Service介面
1 public interface PersonService { 2 /** 3 * 新增 4 */ 5 void insertPerson(Person p); 6 /** 7 * 查詢一個 8 */ 9 Person selectPersonById(Integer id); 10 /** 11 * 查詢多個 12 */ 13 List<Person> selectPersonList(); 14 15 }
- 撰寫Service實作類
使用注解@Service標注為Spring組件,注入DAO物件
1 @Service 2 public class PersonServiceImpl implements PersonService { 3 4 @Autowired 5 private PersonDao personDao; 6 7 @Override 8 public void insertPerson(Person p) { 9 personDao.insertPerson(p); 10 } 11 12 @Override 13 public Person selectPersonById(Integer id) { 14 return personDao.selectPersonById(id); 15 } 16 17 @Override 18 public List<Person> selectPersonList() { 19 return personDao.selectPersonList(); 20 } 21 22 }
- 撰寫Controller,提供一組restFUL風格的介面
使用注解@RestController標注控制器類,使其回傳資料結果都是JSON格式,注入Service物件,使用RestFUL風格提供訪問介面
1 @RestController 2 public class PersonController { 3 4 @Autowired 5 private PersonService personService; 6 7 /** 8 * 介面地址:http://localhost:8080/insertPerson 9 * 請求方式:PUT 入參:JSON資料 10 */ 11 @RequestMapping(value = "https://www.cnblogs.com/insertPerson", method = RequestMethod.PUT) 12 public void insertPerson(@RequestBody Person p) { 13 personService.insertPerson(p); 14 }; 15 /** 16 * 介面地址:http://localhost:8080/selectPersonById/1 17 * 請求方式:GET 入參:id 18 */ 19 @GetMapping(value = "https://www.cnblogs.com/selectPersonById/{id}") 20 public Person selectPersonById(@PathVariable Integer id) { 21 System.err.println("id值為:"+id); 22 return personService.selectPersonById(id); 23 }; 24 /** 25 * 介面地址:http://localhost:8080/selectPersonList 26 * 請求方式:POST 入參:無 27 */ 28 @PostMapping("/selectPersonList") 29 public List<Person> selectPersonList(){ 30 return personService.selectPersonList(); 31 }; 32 }
- 安裝Postman工具,訪問測驗介面,
啟動SpirngBoot專案主程式,請求介面測驗!
Postman是一款常用的介面測驗工具,可以測驗發送不同請求,傳遞不同引數,具體操作請關注博主盡情期待,PostMan下載地址
二.整合JPA
JPA是Java Persistence API的簡稱,中文名Java持久層API,是SUN公司推出的一套基于ORM的規范,Hibernate框架中提供了JPA的實作,Spring Data JPA是Spring基于Hibernate開發的一個JPA框架,可以極大的簡化JPA的寫法,可以在幾乎不用寫具體代碼的情況下,實作對資料的訪問和操作,除了CRUD外,還包括如分頁、排序等一些常用的功能,此外更強大的是,它還可以通過方法命名規則進行資料庫查詢操作
Spring Data JPA提供的介面:
Repository:最頂層的介面,是一個空的介面,目的是為了統一所有Repository的型別,且能讓組件掃描的時候自動識別,CrudRepository:是Repository的子介面,提供CRUD的功能(內置默認的簡單的CURD方法,可以直接參考)PagingAndSortingRepository:是CrudRepository的子介面,添加分頁和排序的功能,JpaRepository:是PagingAndSortingRepository的子介面,增加了一些實用的功能,比如:批量操作等,(相對最完整的內置方法:簡單的CURD/分頁/批量)JpaSpecificationExecutor:用來做負責查詢的介面Specification:是Spring Data JPA提供的一個查詢規范,要做復雜的查詢,只需圍繞這個規范來設定查詢條件即可,
其中,自定義查詢,方法名命名規范如下:
| 命名可選關鍵字 | 方法命名舉例 | 執行方法時對應產生的SQL,Where子句 |
|---|---|---|
| And | findByNameAndPwd | where name= ? and pwd =? |
| Or | findByNameOrSex | where name= ? or sex=? |
| Is,Equals | findById,findByIdEquals | where id= ? |
| Between | findByIdBetween | where id between ? and ? |
| LessThan | findByIdLessThan | where id < ? |
| LessThanEquals | findByIdLessThanEquals | where id <= ? |
| GreaterThan | findByIdGreaterThan | where id > ? |
| GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
| After | findByIdAfter | where id > ? |
| Before | findByIdBefore | where id < ? |
| IsNull | findByNameIsNull | where name is null |
| isNotNull,NotNull | findByNameNotNull | where name is not null |
| Like | findByNameLike | where name like ? |
| NotLike | findByNameNotLike | where name not like ? |
| StartingWith | findByNameStartingWith | where name like ‘?%’ |
| EndingWith | findByNameEndingWith | where name like ‘%?’ |
| Containing | findByNameContaining | where name like ‘%?%’ |
| OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
| Not | findByNameNot | where name <> ? |
| In | findByIdIn(Collection<?> c) | where id in (?) |
| NotIn | findByIdNotIn(Collection<?> c) | where id not in (?) |
| True | findByAaaTue | where aaa = true |
| False | findByAaaFalse | where aaa = false |
| IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
這個確實,夠強大!但查詢條件一多,這個方法名就也會很長了哦……
Spring Data JPA簡單總結:
- 提供了基本的CURD方法,批處理,分頁方法等,
- 允許自定義方法名,根據指定命名規則實作查詢,
- 允許使用@Query注解,自定義更高級,更復雜的SQL
1.準備作業
- 引入
spring-data-jap依賴1 <!-- SpringBoot整合JPA --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-data-jpa</artifactId> 5 </dependency>
- 修改yml組態檔設定JPA配置及資料庫配置
1 spring: 2 datasource: 3 #根據MySQL版本配置驅動類5.x----8.x 驅動類“com.mysql.jdbc.Driver” 或 “com.mysql.cj.jdbc.Driver”, 4 driver-class-name: com.mysql.cj.jdbc.Driver 5 #useSSL:SSL協議提供服務主要作用:(不建議在沒有服務器身份驗證的情況下建立SSL連接,) 6 # 1)認證用戶服務器,確保資料發送到正確的服務器; . 7 # 2)加密資料,防止資料傳輸途中被竊取使用; 8 # 3)維護資料完整性,驗證資料在傳輸程序中是否丟失; 9 #serverTimezone:設定時區,不設定會報錯,GMT%2B8:東八區北京時間 Asia/Shanghai:上海時間 10 #useServerPrepStmts:在url中給出useServerPrepStmts=true引數,開啟預編譯(默認PS是關閉的) 11 #allowMultiQueries:設定為true,開啟批量執行sql的開關,更多請持續關注博主檔案 12 url: jdbc:mysql://localhost:3306/springboot?useSSL=false&serverTimezone=GMT%2B8 13 username: root 14 password: xsge 15 #JPA配置—————————————————————————————————————————————————————————————————————————— 16 jpa: 17 #是否顯示SQL 18 show-sql: true 19 hibernate: 20 #表結構處理方式方式,update表示,第一次執行時根據物體類創建表結構,之后的操作只做資料更新 21 ddl-auto: update
- 新增物體類對應資料庫表
配置物體常用注解:(這里僅僅列舉,更多詳情請關注博主Hibernate文章)
@Entity
作用:標識當前物體為資料物體類
@Table(name=值)
作用:標識當前物體對應的是資料庫表
屬性:Name:指定當前物體對應資料庫表名稱
@Id
作用:標識當前屬性為主鍵列屬性
@Column
作用:標識當前屬性對應資料庫的欄位
屬性:Name:指定當前屬性所對應的資料庫欄位列名稱
@GeneratedValue
作用:指定欄位列的主鍵策略
屬性:Generator:該屬性值,指定Hibernate中提供的主鍵策略宣告別名
Strategy:該屬性,標注JPA提供的主鍵生成策略(即主鍵生成方式),
取值GenerationType:
AUTO:自適應,選擇一下三種,默認選擇TABLE
IDENTITY:Mysql自增長,要判斷是否支持
SEQUENCE:Oracle自增長,要判斷是否支持
TABLE:類似于Helw高低位演算法,無需判斷,因為使用的是固定格式的演算法生成,
1 @Entity // 標識當前物體為資料物體類 2 @Data // 自動生成get/set等 3 @AllArgsConstructor // 全參建構式 4 @NoArgsConstructor // 無參建構式 5 @Table(name = "student") // 標識物體對應的表名 6 @EntityListeners(AuditingEntityListener.class) // spring-data-jap物體類資料更新的監聽器注解 7 public class Student { 8 // 標識當前屬性為主鍵列屬性 9 @Id 10 // 標識欄位列的主鍵策略(主鍵生成方式)GenerationType.IDENTITY表示shiyongMySQL默認自增長生成主鍵值 11 @GeneratedValue(strategy = GenerationType.IDENTITY) 12 private Integer sid; 13 14 // 標識當前屬性對應資料庫的欄位 15 @Column(name = "name") 16 private String name; 17 @Column(name = "age") 18 private Integer age; 19 20 // spring-data-jap中提供的自動填充,新增時自動填充時間(配合SPRING-DATA-JPA監聽注解使用) 21 @CreatedDate 22 private Date createTime; 23 24 // spring-data-jap中提供的自動填充,有更新時自動填充更新時間(配合SPING-DATA-JPA監聽注解使用) 25 @LastModifiedDate 26 private Date updateTime; 27 }
這里需要注意,在《Mybatis-Plus使用全解》中,介紹過如何設定公共欄位自動填充功能,比如創建時間和修改時間,創建人和修改人等等,都是可以一進行賦值的,在
spring-data-jap中,是使用@CreatedDate和@LastModifiedDate標記,同時,需要在物體類上,加@EntityListeners(AuditingEntityListener.class),然后在啟動類上加入注解@EnableJpaAuditing(開啟JPA自動填充),這樣就實作類似公共欄位自動填充的功能了,(JPA自動填充注解如下圖)
- 修改SpringBoot主程式
在啟動類上加入注解@EnableJpaAuditing
1 @SpringBootApplication 2 @EnableJpaAuditing // 開啟JPA自動填充功能 3 @Slf4j 4 public class AnnotaticSpringBootApplication { 5 // 主函式 6 public static void main(String[] args) { 7 // 啟動App 8 SpringApplication.run(AnnotaticSpringBootApplication.class, args); 9 log.info("主程式啟動了………………"); 10 } 11 }
2.整合實作CURD
在Spring-Data-Jpa概述中,簡單總結了JPA操作的方法,概括有三種:呼叫原介面方法實作簡單CURD,自定義方法名實作簡單CURD,自定義SQL實作CURD,通常情況下,三者結合使用,如果功能需求本身直接使用原介面方法就能實作那就無需更改,如果需求需要不同條件,那么自定義方法名即可,如果更為復雜的需求,直接使用自定義SQL實作,
A,介面源方法實作CURD
- 撰寫子介面繼承介面JpaRepository,
說明:JpaRepository介面中繼承了來自各個父類的簡單CURD方法,包括分頁/排序等,這些方法可以直接參考,無需關注SQL,
1 /** 2 * 撰寫DAO介面繼承JpaRepository介面 3 * 泛型引數1:CURD物體型別 4 * 泛型引數2:主鍵的型別(通常為Integer或Long) 5 */ 6 public interface StudentDao extends JpaRepository<Student, Integer>{ 7 }
- 撰寫Service實作,
(實際開發中需要抽象介面(Inteface)的不能省略,這里圖方便就省略了,直接顯示的是介面實作類)
DAO物件直接自動注入即可,SpringBoot-Data-JPA自主掃描Repository及其所有子介面/子實作類組件,
更多其他方法請自行參考附錄
1 @Service 2 public class StudentServiceImpl implements StudentService { 3 4 @Autowired 5 private StudentDao studentDao; 6 7 /** 8 * 添加:呼叫JpaRepository的默認方法save實作保存 9 * 回傳值為添加的資料物件,同時還會將添加資料的id給回傳 10 */ 11 @Override 12 public Student save(Student student) { 13 return studentDao.save(student); 14 } 15 /** 16 * 根據ID查詢:呼叫JpaRepository的默認方法findById實作根據id查詢 17 * 回傳結果為Optional<Student>,是JDK1.8新增的防null物件問題的一個核心類, 18 * 你可以理解為將物件查詢后,有放入到一個Optional容器中,呼叫方法get即可將物件取出 19 */ 20 @Override 21 public Student findById(Integer sid) { 22 return studentDao.findById(sid).get(); 23 } 24 /** 25 * 分頁查詢:呼叫JpaRepository的默認方法findAll實作查詢所有 26 * 實際引數型別為:Pageable分頁介面,PageRequest使其間接實作子類, 27 * 引數1:當前頁碼(從0開始,不能為負數) 28 * 引數2:當前頁資料顯示行數(從1開始,不能為負數) 29 */ 30 @Override 31 public Page<Student> findAll(Integer page,Integer size) { 32 return studentDao.findAll(PageRequest.of(page,size)); 33 } 34 35 }
- 新增控制器,提供介面測驗
1 @RestController 2 public class StudentController { 3 4 @Autowired 5 private StudentService studentService; 6 7 /** 8 * 測驗介面:http://localhost:8080/saveStu 9 * 請求方式:PUT 入參:JSON資料 10 */ 11 @RequestMapping(value = "https://www.cnblogs.com/saveStu",method = RequestMethod.PUT) 12 public Student save(@RequestBody Student student) { 13 return studentService.save(student); 14 } 15 16 /** 17 * 測驗介面:http://localhost:8080/findById 18 * 請求方式:GET 入參:占位符引數sid 19 */ 20 @GetMapping("/findById/{id}") 21 public Student findById(@PathVariable(name = "id") Integer sid) { 22 return studentService.findById(sid); 23 } 24 /** 25 * 測驗介面:http://localhost:8080/findAll 26 * 請求方式:POST 入參:page=?& size=? 27 */ 28 @PostMapping("/findAll") 29 public Page<Student> findAll(Integer page,Integer size) { 30 return studentService.findAll(page,size); 31 } 32 33 }
- 啟動主程式,利用Postman工具測驗
B,自定義方法名及自定義SQL實作操作
當功能需求無法通過原介面方法能實作時,就需要手動自定義方法,或者自定義SQL實作CURD,其實并不需要多復雜的部署,在源方法案例的基礎上,直接在持久層介面中新增自定義方法名的方法或者新增自定義SQL的方法即可,
1 public interface StudentDao extends JpaRepository<Student, Integer>{ 2 // 使用自定義命名方法名規則,進行查詢服務,并添加分頁功能 3 List<Student> findByNameContaining(String name,Pageable pageable);// …… where name like ‘%?%’ 4 5 /** 6 * @Query進行 自定義sql撰寫 7 * nativeQuery=true:表示定義的SQL為標準SQL(沒有這一項,SQL陳述句中的表名和欄位名是物體類名和物體類中的欄位名) 8 * 傳引數使用占位符?代替,但需要注意的是這里的占位符后面需要跟數字(第幾個?N 數字N從1開始) 9 */ 10 @Query(value="https://www.cnblogs.com/xsge/p/select * from student where name = ?1",nativeQuery=true) 11 List<Student> queryByName(String name); 12 }
其他測驗省略……
附錄
JPA默認方法說明:查原始碼結構如下(內部方法好好看吧!)
1 QueryDslJpaRepository 2 ┣━ QueryDslPredicateExecutor 3 ┗━ SimpleJpaRepository 4 ┣━ JpaSpecificationExecutor 5 ┗━ JpaRepository 6 ┣━ QueryByExampleExecutor 7 ┗━ PagingAndSortingRepository 8 ┗━ CrudRepository 9 ┗━Repository
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/202748.html
標籤:Java
