文章目錄
-
-
-
- 概念
- 1.SpringBoot+jdbctemplate
- 2.SpringBoot+MyBatis
- 3.SpringBoot+Spring Date JPA
-
-
SpringBoot提供的資料持久層的解決方案:
- SpringBoot+jdbctemplate(用的很少,自己demo用用挺好,輕量級,功能比較少)
- SpringBoot+MyBatis(實際開發中使用最多)
- SpringBoot+Spring Date JPA(沒有2用的多,它的優點可能就在于它是Spring整個體系下提供的,并且支援ORM,因為底層基于Hibernate實作的,自動完成實體類和表的映射,就不用像MyBatis那樣手動完成映射了。)
概念
1.Hibernate:Hibernate是一個開放源代碼的對象關系映射架構,它對JDBC進行了非常輕量級的對象封裝,使得Java程式員可以随心所欲的使用對象程式設計思維來操縱資料庫。屬于全自動的ORM架構,着力點在于POJO和資料庫表之間的映射,完成映射即可自動生成和執行sql。
2.Mybatis:MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,并且改名為MyBatis 。屬于半自動的ORM架構,着力點在于POJO和SQL之間的映射,自己編寫sql語句,然後通過配置檔案将所需的參數和傳回的字段映射到POJO。
3.Spring Data JPA:Spring Data是一個通過命名規範簡化資料庫通路,并支援雲服務的開源架構。其主要目标是使得對資料的通路變得友善快捷,并支援map-reduce架構和雲計算資料服務。
1.SpringBoot+jdbctemplate
JdbcTemplate 是 Spring 自帶的 JDBC 模版元件,底層實作了對 JDBC 的封裝,⽤用法與 MyBatis 類似,開發者需要⾃自定義 SQL 語句句,JdbcTemplate 幫助開發者完成資料庫連接配接,SQL 執⾏,以及結果集的解析。
目錄結構:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB9ENnpHWrR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwUDN1QjMxADM2ADNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.southwind</groupId>
<artifactId>jdbctemplate</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
entity:
@Data
public class Student {
private int id;
private String name;
}
資料層:
public interface StudentRepository {
Student findById(int id);
}
@Repository
public class StudengRepositoryImpl implements StudentRepository {
@Autowired
JdbcTemplate jdbcTemplate;
@Override
public Student findById(int id) {
//三個參數:1.sql。2.參數數組。3.BeanPropertyRowMapper是RowMapper的實作類。RowMapper是一個接口,作用是解析結果集,将sql查詢出的ResultSet對象轉換為泛型指定的java對象。
return jdbcTemplate.queryForObject("select * from student where id = ?",new Object[]{id},new BeanPropertyRowMapper<Student>(Student.class));
}
}
controller層:
@RestController
public class StudentHandler {
@Autowired
StudentRepository studentRepository;
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") int id){
return studentRepository.findById(id);
}
}
Application啟動類:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
配置檔案:
spring:
datasource:
url: jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
username: root
password: xxxx
driver-class-name: com.mysql.cj.jdbc.Driver
資料庫部分就建了個Student表。
上面代碼複制即可運作。
因為jdbc現實中很少使用的,是以就curd就不具體寫了。
可以注意的是:
JdbcTemplate 對基本的 CRUD 操作提供了了良好的⽀支援,通過調⽤用 query 和 update ⽅方法即完成相關操作,其中 query 是⽤用來做查詢操作的,update 是⽤用來做添加、删除、修改功能。
1、queryForObject(String sql,Object[] args,RowMapper rowMapper),查詢⼀條記錄,并且将結果集封裝成 Java 對象。
2、query(String sql,RowMapper rowMapper),查詢⼀組資料,并且将結果集封裝成集合對象。RowMapper 是⼀個接⼝,作⽤就是解析結果集,将 JDBC 查詢出的 ResultSet 對象轉換為對應的 Java對象,在調⽤用該對象時需要指定目标類的結構,泛型。
update(String sql, Object… args)
參數:1、要執⾏的 SQL 語句。2、可變參數 Object…args,滿⾜參數的可變性。
用戶端⽤?傳參 key-value 形式将資料傳給 Spring MVC 服務端,業務方法的形參清單不需要添加任何注解即可自動封裝參數 Java 對象。
用戶端傳 JSON 格式資料,業務⽅法的形參清單需要添加 @RequestBody 注解,才能封裝參數 Java 對象。
業務方法的參數的注解形式比較:
@PathVariable:
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") int id){
return studentRepository.findById(id);
}
通路服務的url格式:http://localhost:8080/findById/1
@RequestParam:
@GetMapping("/findById")
public Student findById(@RequestParam int id){
return studentRepository.findById(id);
}
通路服務的url格式:http://localhost:8080/findById?id=1,當然@RequestParam:是可以省略的!
@RequestBody:
@GetMapping("/saveByStu")
public Student findById(@RequestBody Student stu){
return studentRepository.findById(stu);
}
通路服務的url格式:http://localhost:8080/saveByStu,我是用postman測試的,傳入josn格式的資料。如果不寫這個注解,是資料添加不進去的。因為參數壓根就沒有解析拿到。
2.SpringBoot+MyBatis
目錄結構:
與jdbcTemplate相比,MyBatis主要差別在于不用再java中寫sql語句,而是用xml語句完成,靈活性和擴充性更好。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>www.gosang</groupId>
<artifactId>springbootMyBatis</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
username: root
password: xxxx
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: /mapping/*.xml
type-aliases-package: com.gosang.entity
配置了實體類和mapping的映射。
Application
package com.gosang;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.gosang.repository")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
啟動類與jdbc不同的是加了@MapperScan(“com.gosang.repository”),掃描,把這些代理類交給Spring管理。
其他的業務代碼就大差不差了。如下:
StudentRepository.java
public interface StudentRepository {
List<Student> findAll();
Student findById(int id);
void save(Student student);
void update(Student student);
void delete(int id);
}
StudentRepository.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gosang.repository.StudentRepository">
<select id="findAll" resultType="Student">
select * from student
</select>
<select id = "findById" parameterType = "int" resultType = "Student">
select * from Student where id = #{id}
</select>
<insert id="save" parameterType="Student">
insert into Student(name) VALUES (#{name});
</insert>
<update id="update" parameterType="Student">
update Student set name = #{name} where id = #{id}
</update>
<delete id="delete" parameterType="int">
delete from Student where id = #{id}
</delete>
</mapper>
StudentHandler.java
@RestController
public class StudentHandler {
@Autowired
StudentRepository studentRepository;
@GetMapping("/findAll")
public List<Student> fingAll(){
return studentRepository.findAll();
}
@GetMapping("/findById")
public Student findById(int id){
return studentRepository.findById(id);
}
@PostMapping("/save")
public void save(@RequestBody Student student){
studentRepository.save(student);
}
@PutMapping("/update")
public void update(@RequestBody Student student){
studentRepository.update(student);
}
@DeleteMapping("/delete")
public void delete(int id){
studentRepository.delete(id);
}
}
同上在postman中去測試。
http://localhost:8080/findAll
http://localhost:8080/findById?id=1
**小結:**與jdbc那種在java檔案中寫sql式的寫死方式相比MyBatis就顯得更加靈活,耦合度更低。
3.SpringBoot+Spring Date JPA
Spring Date JPA是Spring提供的持久層解決方案,但它本身并不是一個具體的實作,它是比較上層的封裝,底層還是基于Hibernate。
雖然JdbcTemplate同樣是Spring提供的,但他隻是一個模闆。Spring Date JPA是一個體系更大的基于Hibernate的持久層實作。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.southwind</groupId>
<artifactId>springboot+springdatajpa</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: xxx
url: jdbc:mysql://localhost:3306/mybatis
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
Application
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
entity實體類
@Data
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
}
這裡實體類的寫法就和前兩種有所差別了。能自動完成映射這些注解少不了。
StudentRepository
public interface StudentRepository extends JpaRepository<Student,Long> {
public Student findByName(String name);
}
用這個方案和Hibernate一樣,連sql語句都不用寫了,都是JpaRepository會提供的。我們隻要繼承這個接口就可以使用的,開箱即用。要注意的是,起名字一定要規範,才能自動識别到對應類型的sql。如public Student findByName(String name);。
StudentHandler
@RestController
public class StudentHandler {
@Autowired
private StudentRepository studentRepository;
@GetMapping("/findAll")
public List<Student> findAll(){
return studentRepository.findAll();
}
@GetMapping("/findById/{id}")
public Student findById(@PathVariable("id") Long id){
return studentRepository.findById(id).get();
}
@PostMapping("/save")
public void save(@RequestBody Student student){
studentRepository.save(student);
}
@PutMapping("/update")
public void update(@RequestBody Student student){
studentRepository.save(student);
}
@DeleteMapping("/deleteById/{id}")
public void deleteById(@PathVariable("id") Long id){
studentRepository.deleteById(id);
}
@GetMapping("/findByName/{name}")
public Student findByName(@PathVariable("name") String name){
return studentRepository.findByName(name);
}
}