目录
一、初步了解Mybatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
(一)通过JDBC查询数据库数据步骤
- 加载JDBC驱动
- 建立并获取数据库连接
- 创建 JDBC Statements 对象
- 设置SQL语句的传入参数
- 执行SQL语句并获得查询结果
- 对查询结果进行转换处理并将处理结果返回
- 释放相关资源(关闭Connection,关闭Statement,关闭ResultSet)
(二)从JDBC到Mybatis的改进
- 问题描述一:
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能
解决问题:
数据库连接的获取和关闭我们可以使用数据库连接池来解决资源浪费的问题。通过连接池就可以反复利用已经建立的连接去访问数据库了。减少连接的开启和关闭的时间。 - 问题描述二:
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编程中对结果的解析处理过程。
(三)对JDBC的优化总结
- 使用数据库连接池对连接进行管理
- SQL语句统一存放到配置文件
- SQL语句变量和传入参数的映射以及动态SQL
- 动态SQL语句的处理
- 对数据库操作结果的映射和结果缓存
- SQL语句的重复
二、实例对比
(一)JDBC连接数据库
1.创建数据库新建表
打开Navicat工具,我直接在之前建的数据库里新建表,没有数据库的自己建。点击数据库test
,点新建查询,输入SQL语句,运行。
点击表列查看,成功新建。
输入以下SQL语句,插入数据,运行。
双击表名,可查看到数据插入成功。
2.创建项目
打开IDEA,点击新建。
选择Java,然后Next。
Next。
命名选择存放路径,然后Next。
右击src,新建包。
DatebaseLink代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DatebaseLink {
// MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
//static final String driverName="org.gjt.mm.mysql.Driver";
//static final String dbUrl="jdbc:mysql://localhost:3306/test";
// MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
static final String userName="root";
static final String password="lxl060908";
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn = null;
Statement stmt = null;
try{
// 注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 打开链接
System.out.println("连接数据库...");
conn = DriverManager.getConnection(DB_URL,userName,password);
// 执行查询
System.out.println(" 实例化Statement对象...");
stmt = (Statement) conn.createStatement();
String sql;
sql = "SELECT id, name, password, email FROM users";
ResultSet rs = stmt.executeQuery(sql);
// 展开结果集数据库
while(rs.next()){
// 通过字段检索
int id = rs.getInt("id");
String name = rs.getString("name");
String password = rs.getString("password");
String email = rs.getString("email");
// 输出数据
System.out.print("ID: " + id);
System.out.print(", 姓名: " + name);
System.out.print(", 密码: " +password);
System.out.print(", 邮箱: " +email);
System.out.print("\n");
}
// 完成后关闭
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
// 处理 JDBC 错误
se.printStackTrace();
}catch(Exception e){
// 处理 Class.forName 错误
e.printStackTrace();
}finally{
// 关闭资源
try{
if(stmt!=null) stmt.close();
}catch(SQLException se2){
}// 什么都不做
try{
if(conn!=null) conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
引入JDBC的jar包。
(二)Mybitis
1.创建数据库新建表
步骤同上。
创建学生表SQL语句:
create table student(
no int primary key auto_increment,
name varchar(40),
age int
)character set utf8 collate utf8_general_ci;
插入数据:
insert into student(no,name,age) values('1','张三','18');
insert into student(no,name,age) values('2','李四','21');
insert into student(no,name,age) values('3','王二','22');
insert into student(no,name,age) values('4','张飞','42');
insert into student(no,name,age) values('5','小米','74');
2.创建项目
打开IDEA,点击新建。
选择Spring Initializr->Next。
操作如图,然后Next。
选择Web->Spring Web。
点击SQL,如图选择,然后Next。
命名和选择项目路径,然后Finish。
配置application.properties
。
server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=lxl060908
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
在com下创建controller
、entity
、mapper
、service
四个包,包下分别新建UserController
、Student
、StudentMapper
、StudentService
类。
UserController
类:
package com.example.datebasedemo.controller;
import com.example.datebasedemo.entity.Student;
import com.example.datebasedemo.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")
class UserController {
@Autowired
private StudentService studentService;
@RequestMapping("/getAllStudent")
public List<Student> findAll(){
return studentService.findAllStudent();
}
@RequestMapping("/getStudentByno/{no}")
public List<Student> findUserByStudentId(@PathVariable int no){
return studentService.findStudentByno(no);
}
}
Student
类:
package com.example.datebasedemo.entity;
public class Student {
private int no;
private String name;
private int age;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
StudentMapper
类:
package com.example.datebasedemo.mapper;
import com.example.datebasedemo.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface StudentMapper {
public List<Student> findAllStudent();
List<Student> findStudentByno(int no);
}
StudentService
类:
package com.example.datebasedemo.service;
import com.example.datebasedemo.entity.Student;
import com.example.datebasedemo.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentService {
@Autowired(required = false)
public StudentMapper studentMapper;
public List<Student> findAllStudent() {
return studentMapper.findAllStudent();
}
public List<Student> findStudentByno(int no) {
return studentMapper.findStudentByno(no);
}
}
在resources下创建mappet
包用于存放Mapper.xml文件。
右击mapper,点击New->File,创建Mapper映射对应的StudentMapper.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.example.datebasedemo.mapper.StudentMapper">
<resultMap id="result" type="com.example.datebasedemo.entity.Student">
<result column="no" jdbcType="INTEGER" property="no" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap>
<select id="findAllStudent" resultType="com.example.datebasedemo.entity.Student">
select * from student;
</select>
<select id="findStudentByno" resultType="com.example.datebasedemo.entity.Student">
select * from student where no=#{no};
</select>
</mapper>
点击运行。
打开浏览器输入http://localhost:8080/Student/getAllStudent/
输入http://localhost:8080/Student/getStudentByno/1
运行测试成功。
三、总结
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
参考文献
从JDBC到Mybatis介绍
从JDBC到Mybatis改进
MyBatis-从JDBC到Spring整合MyBatis
IDEA实训——从JDBC到Mybatis