- 一辈子很长、要去做一些浪漫的事。去看一些风景、读一些书、培养一两个爱好。
最近学习了MyBatis
的源码教程【书籍<< 手写mybatis:渐进式源码实践 >>】、本着把知识从输入转为输出的心态,打算按照如下的过程整理一下相关知识。
- 使用JDBC操作数据库
- MyBatis框架基础使用教程
- 结合参考书籍提供的mini版本的MyBatis、分析这一部分的实现以及对应的源码框架。这一部分会给出方法级别的图示,超级详细。
其中第一部分就一篇文章、主要用于回顾一下JDBC
相关操作,解释为什么使用MyBatis
框架。
第二部分主要内容为mybatis
相关框架的使用、会使用大量示例代码。
第三部分主要就是借助参考书籍 <<手写mybatis渐进式源码实践>> 以及其他源码相关书籍去分析MyBatis
的源码。会给出详细的注释以及图示。
本文主要内容就是回顾一下JDBC
的相关操作。主要内容有
- 使用JDBC操作数据库步骤
Statement
和PrepareStatement
的区别
JDBC操作数据库步骤
不管做什么事、首先第一步就是和目标建立连接、因此使用JDBC
操作数据库也是、引入相关依赖。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
第一步:注册数据库驱动、获取数据库连接
public class JdbcUtils {
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/master";
private static final String USER = "root";
private static final String PASSWORD = "root123!";
private static final Logger logger = LoggerFactory.getLogger(JdbcUtils.class);
public static Connection getConnection() {
try {
Class.forName(DRIVER);
return DriverManager.getConnection(URL, USER, PASSWORD);
} catch (ClassNotFoundException | SQLException e) {
logger.error("数据库连接失败");
throw new RuntimeException(e);
}
}
}
通过Class.forName()
注册数据库驱动、通过DriverManager
获取数据连接。这样我们的程序就和MySQL数据库建立起连接了。
第二步:通过获取的连接创建Statement
或者PrepareStatement
对象,后者对前者进行了扩展,推荐使用后者主要原因有以下几点:
Statement | PrepareStatement | |
---|---|---|
参数设置 | 字符串拼接、会有sql注入的风险 | 通过占位符、自动绑定参数 |
性能 | 每一次执行时都会重新编译 | 编译后缓存,适合重复执行相同的 SQL |
安全性 | 容易受到 SQL 注入攻击 | 容易受到 SQL 注入攻击 |
PrepareStatement
:会预编SQL,这是指的在数据库层面、以MySQL
为例、预编译过程如下:
# 1.执行预编译语句
prepare selectUser from 'select * from user where user_name like ?';
#2.设置变量,例如:
set @username='%小明%';
#3.执行语句,例如:
execute selectUser using @username;
一般使用PrepareStatement
对象进行数据库操作,可以采用如下的方式获取:
String sql = "insert into user(user_name,password) values(?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
第三步参数设置:
statement.setString(1, "晚风也很温柔_123");
statement.setString(2, "123456");
相反如果使用Statement对象
:
Statement statement = connection.createStatement();
String sql = "insert into user(user_name,password) values("+"晚风也很温柔_123"+"123456"+")";
SQL
就需要我们进行手动拼接、如果代码"有毒",则会造成极大的生产事故。比如如下的SQL
语句:
String sql = "insert into user(user_name,password) values("+"晚风也很温柔_123"+"123456"+");" +
"delete FROM user where 1=1;";
第四步执行SQL语句:
statement.execute();
int updateCount = statement.getUpdateCount();
// 如果执行的是查询操作就可以通过如下的方式获取值、并装配到JavaBean中去。
ResultSet resultSet = statement.getResultSet();
while (resultSet.next()) {
System.out.println(resultSet.getString("user_name"));
}
到这里就可以把数据库的记录封装为JavaBean
对象,也就把数据从数据库中加载到我们的Java
应用中了。
上面只是一个简单的插入方法示例,当我们需要编写多个方法时,可以看到很多的步骤都是重复操作的,具体的步骤如下:
- 注册驱动
- 获取链接【重复操作】
- 编辑sql
- 参数设置
- 执行sql【重复操作】
- 获取返回结果【重复操作】
重复的操作往往可以优化、因此这就是我们使用MyBatis
的优点之一,上述重复的操作都不需要我们手动编码,只需要正确填写配置文件之后,编写mapper文件中的sql语句即可。极大的简化了我们的编码、提高了开发速度。
使用MyBatis操作数据库
引入MyBatis
,Maven
坐标如下:
<!--mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<!--mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
</dependency>
<!--单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
编写主配置文件mybatis-config-datasource.xml
:配置、数据库连接、缓存、插件、Mapper
等信息。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 全局缓存:true/false -->
<setting name="cacheEnabled" value="true"/>
<!--缓存级别:SESSION/STATEMENT-->
<setting name="localCacheScope" value="STATEMENT"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root123!"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper.XML 配置 -->
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
主配置文件和UserMapper.xml
的位置关系:
编写IUserMapper
接口以及对应的Mapper
文件:
public interface IUserMapper {
SysUser getUserById(Integer id);
}
他们之间的关系以及文件含义放在下一篇文章详细说明:
namespace
: 指向接口的全限定名称id
:和接口的方法名称一致相对应即可
<?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.supersist.mybatis.tutorial.mapper.IUserMapper">
<select id="getUserById" resultType="com.supersist.mybatis.tutorial.pojo.SysUser">
select * from user where id = #{id}
</select>
</mapper>
实体类:
public class SysUser{
private Integer id;
private String userName;
// 省略get、set方法
}
使用:
// 加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config-datasource.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取mapper
IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);
// 调用相关方法
SysUser user = mapper.getUserById(1);
System.out.println(user);
通过上述两个对比,很明显mybatis
对数据库的操作比纯jdbc
的操作要简单得多,缺点就是需要学习一下相关的知识、才能正确使用MyBatis
。
下一章:<< 【MyBatis_01】第一个MyBatis程序 >>