从 JDBC 到 Mybatis

从 JDBC 到 Mybatis


一、JDBC 和 Mybatis

MyBatis是对JDBC的封装。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。

MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。


JDBC的问题及改进:

  1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能
    解决:数据库连接的获取和关闭我们可以使用数据库连接池来解决资源浪费的问题。通过连接池就可以反复利用已经建立的连接去访问数据库了。减少连接的开启和关闭的时间。

  2. Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
    解决: Mybatis将SQL语句写在配置文件中通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。这样当需要更改SQL时,只需要更改配置文件。

  3. 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
    解决:同上,配置文件。

  4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
    解决:Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。


二、Spring Boot 整合 Mybatis 测试


1. 新建项目


选择SpringInitializr:
从 JDBC 到 Mybatis


填写Group等,Next
从 JDBC 到 Mybatis


选择项目依赖:
从 JDBC 到 Mybatis
从 JDBC 到 Mybatis


Finish:
从 JDBC 到 Mybatis


2. 配置项目并编写代码


数据库定义可查看Java JDBC 连接 MySQL8.0:
从 JDBC 到 Mybatis

根据自己的数据库名、用户名和密码,修改application.properties:
从 JDBC 到 Mybatis

server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

从 JDBC 到 Mybatis


com.example.demo下创建四个package(controllerentitymapperservice):
从 JDBC 到 Mybatis


entity下创建类Student:
从 JDBC 到 Mybatis
Student:

package com.example.demo.entity;

public class Student {
    private int stu_id;
    private String stu_name;
    private int stu_age;

    public int getStu_id() {
        return stu_id;
    }

    public void setStu_id(int stu_id) {
        this.stu_id = stu_id;
    }

    public String getStu_name() {
        return stu_name;
    }

    public void setStu_name(String stu_name) {
        this.stu_name = stu_name;
    }

    public int getStu_age() {
        return stu_age;
    }

    public void setStu_age(int stu_age) {
        this.stu_age = stu_age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuID=" + stu_id +
                ", stuName='" + stu_name + "'" +
                ", stuAge=" + stu_age +
                "}";
    }
}

mapper下创建接口StuMapper:
从 JDBC 到 Mybatis
StuMapper:

package com.example.demo.mapper;


import com.example.demo.entity.Student;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface StuMapper {
    public List<Student> findAllStudent();
    public List<Student> findStudentByStudentID(int stuID);
}

resources下创建目录mapper
从 JDBC 到 Mybatis

在刚刚创建的resources下的mapper下创建StuMapper.xml文件:
从 JDBC 到 Mybatis
从 JDBC 到 Mybatis

StuMapper:

<?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.example.demo.mapper.StuMapper">
    <resultMap id="result" type="com.example.demo.entity.Student">
        <result column="stu_id" jdbcType="INTEGER" property="stu_id" />
        <result column="stu_name" jdbcType="VARCHAR" property="stu_name" />
        <result column="stu_age" jdbcType="INTEGER" property="stu_age" />
    </resultMap>

    <select id="findAllStudent" resultType="com.example.demo.entity.Student">
        select * from student;
    </select>

    <select id="findStudentByStudentID" resultType="com.example.demo.entity.Student">
        select * from student where stu_id=#{stuID};
    </select>
</mapper>

在包Service下创建类StudentService:
从 JDBC 到 Mybatis
StudentService:

package com.example.demo.service;


import com.example.demo.entity.Student;
import com.example.demo.mapper.StuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentService {
    @Autowired(required = false)
    public StuMapper stuMapper;

    public List<Student> findAllStudent(){
        return stuMapper.findAllStudent();
    }

    public List<Student> findStudentByStuID(int stuID){
        return stuMapper.findStudentByStudentID(stuID);
    }

}

在包controller下创建类StudentController:
从 JDBC 到 Mybatis
StudentController

package com.example.demo.controller;


import com.example.demo.entity.Student;
import com.example.demo.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;

    @RequestMapping("/getAllStudent")
    public List<Student> findAll(){
        return studentService.findAllStudent();
    }

    @RequestMapping("/getStudentByStudentID/{stuID}")
    public List<Student> findStudentByStudentID(@PathVariable int stuID){
        return studentService.findStudentByStuID(stuID);
    }


}

所有结构如下:
从 JDBC 到 Mybatis


3. 测试

运行项目:
从 JDBC 到 Mybatis

成功运行:
从 JDBC 到 Mybatis


打开http://localhost:8080/student/getAllStudent:
从 JDBC 到 Mybatis

打开http://localhost:8080/student/getStudentByStudentID/1001:
从 JDBC 到 Mybatis

测试成功!


三、总结

使用Mybatis,对于sql语句会更加灵活,减少了大量冗余代码,并能很好的与Spring集成。


参考

IDEA2019开发Spring Boot整合Mybatis实现User的CRUD(增读更删)

【Mybatis】从JDBC到Mybatis的改进

从 JDBC 到 Mybatis,看这篇就够了

上一篇:数据库21/10/16


下一篇:Java Web实战详细教程(十四)新增功能的实现