SpingBoot整合jdbctemplate/MyBatis/Srping Data-比較

SpringBoot提供的數據持久層的解決方案:

  1. SpringBoot+jdbctemplate(用的很少,自己demo用用挺好,輕量級,功能比較少)
  2. SpringBoot+MyBatis(實際開發中使用最多)
  3. 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 執⾏,以及結果集的解析。
目錄結構:
在這裏插入圖片描述
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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章