目录
一.从JDBC到Mybatis的改进
1.什么是Mybatis?
MyBatis支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的
JDBC代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的XML或注
解,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
2.从JDBC到Mybatis的改进是什么
通过问题阐述,来描述改进的过程:
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编程中对
结果的解析处理过程。
二.IDEA环境下Mybatis对JDBC进行改造示例对比
1.JDBC操作数据库
1.所用工具navicat,选择数据库test1,新建查询
2.输入代码,新建user表,点击运行
代码如下:
create table users(
id int primary key auto_increment,
name varchar(40),
password varchar(40),
email varchar(60),
birthday date
)character set utf8 collate utf8_general_ci;
3.点击新建查询,进行插入数据
代码如下:
insert into users(name,password,email,birthday) values('zs','123456','zs@sina.com','1999-12-04');
insert into users(name,password,email,birthday) values('lisi','123456','lisi@sina.com','2001-12-04');
insert into users(name,password,email,birthday) values('wangwu','123456','wangwu@sina.com','2003-12-04');
4.在IDEA中新建java项目,创建好后在src中新建java class
5.在DatabaseLink中输入以下代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DatebaseLink {
static final String driverName="org.gjt.mm.mysql.Driver";
static final String dbUrl="jdbc:mysql://localhost:3306/test";
static final String userName="root";
static final String password="2652693155";
public static void main(String[] args) {
// TODO Auto-generated method stub
// MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
Connection conn = null;
Statement stmt = null;
try{
// 注册 JDBC 驱动
Class.forName(driverName);
// 打开链接
System.out.println("连接数据库...");
conn = DriverManager.getConnection(dbUrl,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!");
}
}
6.引入JDBC的jar包
7.引用成功后可查看到
8.点击运行,查看结果
2.MyBatis应用
读取功能实现
1.在IDEA中新建项目
2.在navicat中新建学生表
create table student(
no int primary key auto_increment,
name varchar(40),
age int
)character set utf8 collate utf8_general_ci;
3.插入数据
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');
4.可以查看到数据已经插入
5.在IDEA中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=2652693155
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
6.项目src-main-java下分别创建包:controller、entity、mapper、service,用来实现控制层、实体层、映射层、业务层,src-main-resources下创建mapper包用于存放*Mapper.xml文件:
7.创建entity实体类Student
package com.example.databasedemo.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 + '\'' +
'}';
}
}
8.创建Mapper映射操作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();
List<Student> findStudentByno(int no);
}
9.创建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.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 student;
</select>
<select id="findStudentByno" resultType="com.example.databasedemo.entity.Student">
select * from student where no=#{no};
</select>
</mapper
10.创建service业务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);
}
}
11.创建 controller控制层UserController类:
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")
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);
}
}
12.点击运行
13.测试结果
打开浏览器输入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 student;
</select>
<select id="findStudentByno" resultType="com.example.databasedemo.entity.Student">
select * from student where no=#{no};
</select>
<select id="findStudentByname" resultType="com.example.databasedemo.entity.Student">
select * from student where name=#{name};
</select>
<insert id="insertStudent" parameterType="com.example.databasedemo.entity.Student" keyProperty="no" useGeneratedKeys="true">
insert into student(name,age) values (#{name},#{age});
</insert>
<update id="updateStudent" parameterType="com.example.databasedemo.entity.Student">
update student set name=#{name},age=#{age} where no=#{no};
</update>
<delete id="deleteStudent" parameterType="com.example.databasedemo.entity.Student">
delete from where no=#{no};
</delete>
</mapper>
功能测试
1.运行程序
2.按姓名查找,输入http://localhost:8080/Student/getStudentByname/王二
3.修改一信息
http://localhost:8080/Student/updateStudent?no=5&name=like&age=20
查看结果http://localhost:8080/Student/getStudentByno/5
4.插入一条信息http://localhost:8080/Student/insertStudent?name=just&age=66
5.删除一条信息
输入http://localhost:8080/Student/deleteStudent?no=6进行删除
输入http://localhost:8080/Student/getAllStudent/查看删除是否成功
三.总结
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。MyBatis使用SqlSessionFactoryBuilder来连接完成 JDBC需要代码完成的数据库获取和连接,减少了代码的重复。