从 JDBC 到 Mybatis
一、JDBC 和 Mybatis
MyBatis
是对JDBC
的封装。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
JDBC
的问题及改进:
-
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能
解决
:数据库连接的获取和关闭我们可以使用数据库连接池来解决资源浪费的问题。通过连接池就可以反复利用已经建立的连接去访问数据库了。减少连接的开启和关闭的时间。 -
Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决
: Mybatis将SQL语句写在配置文件中通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。这样当需要更改SQL时,只需要更改配置文件。 -
使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
解决
:同上,配置文件。 -
对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
解决
:Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
二、Spring Boot 整合 Mybatis 测试
1. 新建项目
选择SpringInitializr
:
填写Group
等,Next
选择项目依赖:
Finish
:
2. 配置项目并编写代码
数据库定义可查看Java JDBC 连接 MySQL8.0:
根据自己的数据库名、用户名和密码,修改application.properties
:
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
在com.example.demo
下创建四个package
(controller
、entity
、mapper
、service
):
在entity
下创建类Student
: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
: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
:
在刚刚创建的resources
下的mapper
下创建StuMapper.xml
文件:
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
: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
: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);
}
}
所有结构如下:
3. 测试
运行项目:
成功运行:
打开http://localhost:8080/student/getAllStudent:
打开http://localhost:8080/student/getStudentByStudentID/1001:
测试成功!
三、总结
使用Mybatis
,对于sql
语句会更加灵活,减少了大量冗余代码,并能很好的与Spring
集成。
参考
IDEA2019开发Spring Boot整合Mybatis实现User的CRUD(增读更删)