天天看點

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

文章目錄

        • 概念
        • 1.SpringBoot+jdbctemplate
        • 2.SpringBoot+MyBatis
        • 3.SpringBoot+Spring Date JPA

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 執⾏,以及結果集的解析。

目錄結構:

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

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

目錄結構:

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

與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

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

**小結:**與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);
    }
}
           

繼續閱讀