Mybatis入门学习对比JDBC实现数据库增删改查CRUD
一.前言
1.使用JDBC简介
JDBC编程的步骤:
1、 加载数据库驱动
2、 创建并获取数据库链接
3、 创建jdbc statement对象
4、 设置sql语句
5、 设置sql语句中的参数(使用preparedStatement)
6、 通过statement执行sql并获取结果
7、 对sql执行结果进行解析处理
8、 释放资源(resultSet、preparedstatement、connection)
2.Mybatis对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编程中对
结果的解析处理过程。
3.使用Mybatis简介
其执行过程:
1、 mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在
SqlMapConfig.xml中加载。
2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执
行器、一个是缓存执行器。
5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。
mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通
过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对
preparedStatement设置参数。
7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通
过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中
对结果的解析处理过程
二.创建一个Spring-Mybatis项目实现对数据简单的CRUD
1.新建工程
选择springInitializr,JDK1.8版本。在dependency中勾选上web,JDBC,Mybatis,MYSQL Sever
2修改添加配置文件
application.properties文件为默认项目配置文件,默认为空的,我们可以在配置文件中配置端口、名字等一般属性,也可以配置自定义属性、参数引用、多环境配置等,可以参考 https://www.jianshu.com/p/c023083f51b4 一文说明介绍。 application.properties文件在项目-src-main-resources下。可以在文件中添加端口、数据源、mydatis等相关数据,下面为文件内容。
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=root
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
3主程序编写
1.在项目中创建四个package分别controller,entity,mapper,service
entity是项目的实体类,其中创建user类变量名字和类型对应你要操作中的数据库中的类型。
controller中是控制项目所访问的域名对其进行操作
Mapper映射操作UserMapper类
service创建UserService类
与此同时在resource 中创建一个mapper文件夹其中创建UserMapper.xml对应的映射文件
2.点击页面右上角测试
发现程序可以正常运行,在浏览器中打开localhost:8080/user/getAllUser
发现可以正常返回所需要的内容。
对最基本的例子程序测试完成,现在继续完成除了查询剩下的功能
3.完善CRUD剩余功能
完整UserMapper类
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
public List<User> findAllUser();
public List<User> findUserByUserId(int userid);
public List<User> findUserByUsername(String username);
public int insertUser(User user);
public int updateUser(User user);
public int deleteUser(User user);
}
完整UserService类
package com.example.demo.service;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired(required=false)
public UserMapper userMapper;
public List<User> findAllUser(){
return userMapper.findAllUser();
}
public List<User> findUserByUserId(int userid){
return userMapper.findUserByUserId(userid);
}
public List<User> findUserByUsername(String username){
return userMapper.findUserByUsername(username);
}
public User insertUser(User user){
userMapper.insertUser(user);
return user;
}
public int updateUser(User user){
return userMapper.updateUser(user);
}
public int deleteUser(User user){
return userMapper.deleteUser(user);
}
}
完整UserController类
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
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("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getAllUser")
public List<User> findAll(){
return userService.findAllUser();
}
@RequestMapping("/getUserByUserID/{userid}")
public List<User> findUserByUserId(@PathVariable int userid){
return userService.findUserByUserId(userid);
}
@RequestMapping("/getUserByUsername/{username}")
public List<User> findUserByUsername(@PathVariable String username){
return userService.findUserByUsername(username);
}
@RequestMapping("/insertUser")
public User insertUser(User user){
return userService.insertUser(user);
}
@RequestMapping("/updateUser")
public int updateUser(User user){
return userService.updateUser(user);
}
@RequestMapping("/deleteUser")
public int deleteUser(User user){
return userService.deleteUser(user);
}
}
完整UserMapper.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.demo.mapper.UserMapper">
<resultMap id="result" type="com.example.demo.entity.User">
<result column="userid" jdbcType="INTEGER" property="userid" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="password" jdbcType="VARCHAR" property="password" />
</resultMap>
<select id="findAllUser" resultType="com.example.demo.entity.User">
select * from users;
</select>
<select id="findUserByUserId" resultType="com.example.demo.entity.User">
select * from users where userid=#{userid};
</select>
<select id="findUserByUsername" resultType="com.example.demo.entity.User">
select * from users where username=#{username};
</select>
<insert id="insertUser" parameterType="com.example.demo.entity.User" keyProperty="userid" useGeneratedKeys="true">
insert into users(username,password) values (#{username},#{password});
</insert>
<update id="updateUser" parameterType="com.example.demo.entity.User">
update users set username=#{username},password=#{password} where userid=#{userid};
</update>
<delete id="deleteUser" parameterType="com.example.demo.entity.User">
delete from users where userid=#{userid};
</delete>
</mapper>
通过测试发现完美运行。
三.对比JDBC和通过Mybatis实现数据库操作的代码
1.创建一个项目通过JDBC实现数据库操作。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.*;
@SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//加载驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
//创建连接
//java10为数据库名
String url="jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=UTC";
String username="root";
String userpwd="root";
Connection conn = DriverManager.getConnection(url,username,userpwd);
//创建Statement,执行sql
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select password,userid from users");
while(rs.next()){
System.out.println("名字"+rs.getString("password"));
System.out.println("年齡"+rs.getInt("userid"));
}
//关闭连接
rs.close();
st.close();
conn.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
发现JDBC对数据库操作十分繁琐,基于Mybatis的话更加方便而且便于修改,并且由于框架可以直接将数据传到前端。