又到了一年一度挪坑日,作为一个码畜,开始了新的复习java之路,除了巩固,更是为了活动下僵硬许久的CRUD操作。那么就从Mybatis这个相对简单的框架开始吧。
Mybatis的使用
由于太久没单独的使用这个框架了,甚至JDBC都有点忘记怎么写了。于是特意再不劳烦spring的前提下,用了下Mybatis查询了下数据库。
过程如下:
- 创建个java项目
- 引入mybatis的jar包和mysql的驱动jar包
- 拷贝过来一个mybatis的配置文件
- 写一个接口、一个实体类、一个mapper.xml文件、一个测试类
- 准备个Mysql数据库
然后启动,看到查询结果(并没有那么一帆风顺。一会找不到xml一会又找不到驱动的)。下面附上相关的准备事宜。
<dependencies>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
配置文件:(要放在resources下面哟,配置文件名字随便)
<?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>
<environments default="mysql">
<environment id="mysql">
<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/mybatislearn?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="xpar"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="EntityDao.xml"/>
</mappers>
</configuration>
接口、实体类
public class Entity {
private String name;
private String value;
private Integer revision;
set/get
}
public interface EntityDao {
Entity getEntity();
}
mapper文件
<?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="per.sjyang.dao.EntityDao">
<select id="getEntity" resultType="per.sjyang.entity.Entity">
select * from SJYANG_TEST01
</select>
</mapper>
测试类:
public class SimpleTest {
public static void main(String[] args) throws IOException {
String config = "mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建了SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6.【重要】指定要执行的sql语句的标识。 sql映射文件中的namespace + "." + 标签的id值
String sqlId = "per.sjyang.dao.EntityDao.getEntity";
//7.【重要】执行sql语句,通过sqlId找到语句
List<Entity> entityList = sqlSession.selectList(sqlId);
//8.输出结果
entityList.forEach( stu -> System.out.println(stu));
//9.关闭SqlSession对象
sqlSession.close();
}
}
别小看上面这些东西,我因为文件放错位置之类的,错了好多次呢。
好了接下来可以使用了之后,开始读一读源码。
Mybatis的架构设计
要读源码我们肯定要先从其架构上来分析,这样有助于我们阅读源码。直接上图:
从图上看,Mybatis框架划分为3层结构,其中各层作用如下:
接口层:
Mybatis的接口层对外提供用户对DB的访问,提供这一基础功能的是一个叫做SqlSession的接口类,它是Mybatis的门户,这个接口提供了一些对DB进行操作的基础API。
核心处理层
核心处理层的作用是处理接口层传进来的指令,并将这些指令转换成SQL语句,拼执行相关SQL,然后对结果集进行封装映射。 核心处理层的两个关键类是Configuration和Executor。
基础支持层:
接口层提供API操作,处理层处理API请求,除了这些外,还需要一些基础服务,比如日志记录、事务处理、加载配置文件信息、缓存支持等。比如处理层的将SQL语句、结果集等封装成java对象存储在Configuration,还有Mybatis的一级缓存、二级缓存以及整个架构的运行记录等。
Mybatis框架的作用
其实一个框架的出现都是为了简化大部分重复工作,从而提高工作效率。那么Mybatis的出现其实就是简化我们对数据的操作,让用户不用关注连接和关闭数据库等操作,而是关注实际的业务操作上。
所以说白了就是优化JDBC操作,不知道你是否还记得JDBC操作步骤:
1.加载驱动
2.获取连接
3.创建statement
4.执行查询获取结果
Connection con = null;// 创建一个数据库连接
PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
ResultSet result = null;// 创建一个结果集对象
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
System.out.println("开始尝试连接数据库!");
String url = "jdbc:oracle:" + "thin:@127.0.0.1:1521:XE";// 127.0.0.1是本机地址,XE是精简版Oracle的默认数据库名
String user = "system";// 用户名,系统默认的账户名
String password = "147";// 你安装时选设置的密码
con = DriverManager.getConnection(url, user, password);// 获取连接
System.out.println("连接成功!");
String sql = "select * from student where name=?";// 预编译语句,“?”代表参数
pre = con.prepareStatement(sql);// 实例化预编译语句
pre.setString(1, "刘显安");// 设置参数,前面的1表示参数的索引,而不是表中列名的索引
result = pre.executeQuery();// 执行查询,注意括号中不需要再加参数
while (result.next())
// 当结果集不为空时
System.out.println("学号:" + result.getInt("id") + "姓名:"
+ result.getString("name"));
}
catch (Exception e)
{
e.printStackTrace();
}
所以Mybatis就是优化上述内容,让用户关注sql就好了。具体Mybatis干的事情如图:
此时看着上面的图和一些相关的配置文件,我们是不是已经能够看到Mybatis大概要做的事情了。那么接下来就探究具体的实现内容吧。
源码阅读前的思考
在源码阅读前,我脑海中的问题有下面几点:
- 驱动什么时候加载的,因为讲道理加载一次就可以啦
- 连接在什么时机获取的,使用池技术还是每次都获取次连接
- 为什么定义个接口就能直接查询sql?我知道用了动态代理,但是这个代理具体实现了什么?
- spring具体整合了mybatis的什么内容
- mybaits查询有getMapper和直接query查询,实现方式区别?
后续的文章将根据实际阅读到的源码写进来。用来解答上述问题。