文章目录
一、概念入门
1.什么是Mybatis
- Mybatis是一个优秀的持久层框架,它对JDBC操作数据库的过程进行封装,使开发者只需要关注sql本身。
- 我们原来使用JDBC操作数据库,需要手动的写代码去注册驱动、获取connection、获取statement等等,现在Mybaits帮助我们把这些事情做了,我们只需要关注我们的业务sql即可,这样可以提高我们的开发效率。
- MyBatis属于半自动的ORM框架
Mybatis架构
2.JDBC编程的步骤
- 加载数据库驱动
- 创建并获取数据库链接
- 创建jdbc statement对象
- 设置sql语句
- 设置sql语句中的参数(使用preparedStatement)
- 通过statement执行sql并获取结果
- 对sql执行结果进行解析处理
- 释放资源(resultSet、preparedstatement、connection)
3.对比——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编程中对 结果的解析处理过程。
简而言之:MyBatis会帮我们把加载驱动、获取连接等过程进行封装,我们不再需要关注这些,只需要关注业务逻辑本身的sql即可,提高开发效率;MyBatis的sql语句在xml文件里面编写,改变sql语句不再需要重新编译。
4.Mybatis执行过程
- mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。- 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
- 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
- Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。 mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通 过Mapped
Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通 过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
二、JDBC和Mybatis操作数据库
1.JDBC操作数据库
这一部分的操作在我之前的博客中有介绍,这里就不赘述了,详见MySQL与JDBC学习
这里附上运行结果:
2.Mybatis操作数据库
①创建项目
new-peoject->springinitializr
项目依赖这里要选择多项
web->spring web
SQL->JDBC API,Mybatis,MySQL
②Mysql建表(Navicat)
建表代码
建表代码
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');
实际操作
③IDEA配置文件
上一步选择的依赖,在pom.xml文件中 已经自动添加到我们的文件中了。
所以我们只需要进行application.properties配置就可以了。
根据自己的数据库名、用户名和密码进行。
以下为代码(注意删除注释)
server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/student1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC //注意地址
spring.datasource.username=root //账号
spring.datasource.password=123456 //密码
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
④文件代码
项目src-main-java-com下分别创建包:controller、entity、mapper、service,用来实现控制层、实体层、映射层、业务层;
src-main-resources下创建mapper包用于存放*Mapper.xml文件;
创建entity实体类Student
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 + '\'' +
'}';
}
}
创建Mapper映射操作StudentMapper类
代码
package com.example.mybatis.mapper;
import com.example.mybatis.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);
}
创建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.mybatis.mapper.StudentMapper">
<resultMap id="result" type="com.example.mybatis.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.mybatis.entity.Student">
select * from student;
</select>
<select id="findStudentByno" resultType="com.example.mybatis.entity.Student">
select * from student where no=#{no};
</select>
</mapper>
创建service业务StudentService类
package com.example.mybatis.service;
import com.example.mybatis.entity.Student;
import com.example.mybatis.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);
}
}
创建 controller控制层UserController类
package com.example.mybatis.controller;
import com.example.mybatis.entity.Student;
import com.example.mybatis.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);
}
}
总架构
⑤运行结果
打开浏览器输入
http://localhost:8080/Student/getAllStudent/
http://localhost:8080/Student/getStudentByno/2
可以得到以下两种结果
⑥完整功能
以上为spring boot整合mybatis实现的Student读取,接下来是添加StudentMapper类的增加、更新和删除方法,配置StudentMapper.xml文件,添加StudentService和StudentController相关功能
StudentMapper类
package com.example.databasedemo.mapper;
import com.example.databasedemo.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface StudentMapper {
public List<Student> findAllStudent();
public List<Student> findStudentByno(int no);
public List<Student> findStudentByname(String name);
public int insertStudent(Student student);
public int updateStudent(Student student);
public int deleteStudent(Student student);
}
StudentService类
package com.example.databasedemo.service;
import com.example.databasedemo.entity.Student;
import com.example.databasedemo.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);
}
public List<Student> findStudentByname(String name){
return studentMapper.findStudentByname(name);
}
public Student insertStudent(Student student){
studentMapper.insertStudent(student);
return student;
}
public int updateStudent(Student student){
return studentMapper.updateStudent(student);
}
public int deleteStudent(Student student){
return studentMapper.deleteStudent(student);
}
}
StudentController类
package com.example.databasedemo.controller;
import com.example.databasedemo.entity.Student;
import com.example.databasedemo.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("/getStudentByno/{no}")
public List<Student> findUserByStudentId(@PathVariable int no){
return studentService.findStudentByno(no);
}
@RequestMapping("/getStudentByname/{name}")
public List<Student> findStudentByname(@PathVariable String name){
return studentService.findStudentByname(name);
}
@RequestMapping("/insertStudent")
public Student insertStudent(Student student){
return studentService.insertStudent(student);
}
@RequestMapping("/updateStudent")
public int updateStudent(Student student){
return studentService.updateStudent(student);
}
@RequestMapping("/deleteStudent")
public int deleteStudent(Student student){
return studentService.deleteStudent(student);
}
}
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.databasedemo.mapper.StudentMapper">
<resultMap id="result" type="com.example.databasedemo.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.databasedemo.entity.Student">
select * from student1;
</select>
<select id="findStudentByno" resultType="com.example.databasedemo.entity.Student">
select * from student1 where no=#{no};
</select>
<select id="findStudentByname" resultType="com.example.databasedemo.entity.Student">
select * from student1 where name=#{name};
</select>
<insert id="insertStudent" parameterType="com.example.databasedemo.entity.Student" keyProperty="no" useGeneratedKeys="true">
insert into student1(name,age) values (#{name},#{age});
</insert>
<update id="updateStudent" parameterType="com.example.databasedemo.entity.Student">
update student1 set name=#{name},age=#{age} where no=#{no};
</update>
<delete id="deleteStudent" parameterType="com.example.databasedemo.entity.Student">
delete from student1 where no=#{no};
</delete>
</mapper>
⑦输出结果
按姓名查找,输入http://localhost:8080/Student/getStudentByname/张三
修改一信息http://localhost:8080/Student/updateStudent?no=5&name=老五&age=99
查看结果http://localhost:8080/Student/getStudentByno/5
插入一条信息http://localhost:8080/Student/insertStudent?name=漩涡鸣人&age=23
删除一条信息http://localhost:8080/Student/deleteStudent?no=6
输入http://localhost:8080/Student/getAllStudent/查看删除成功
三、总结
mybatis相对于JDBC来说,使用更为方便快捷,没有JDBC那么多繁杂的步骤,mybatis的sql统一放在xml文件,更加便于管理,减少了大量的不必要代码,但是需要注意的是mybatis需要加入依赖,且需要配置,在某种意义上也算得上是各有千秋了。
参考链接
Mybatis(一):Mybatis是什么
【Mybatis】从JDBC到Mybatis的改进
IDEA2019开发Spring Boot整合Mybatis实现User的CRUD(增读更删)