一、mybatis知识体系
mybatis框架
mybatis-generator(逆向工程)
mybatis plus(简称MP)
tk.mybatis(通用mapper)
PageHelper 。。。
二、认识Mybatis框架原理
框架原理:更加利于程序员进行开发使用
程序员使用持久层框架,完成CRUD操作
java中的持久层框架,都是对JDBC进行的封装
public void test() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据库链接connection = DriverManager
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",
"root", "root");
// 定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
// 获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
// 设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的
preparedStatement.setString(1, "王五");
// 向数据库发出 sql 执行查询,查询出结果集
rs = preparedStatement.executeQuery();
// 遍历查询结果集
while (rs.next()) {
System.out.println(rs.getString("id") + " " + rs.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
}
}
三、mybatis框架分析(两大流程)
全局配置文件:
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="phase01/UserMapper.xml" />
</mappers>
</configuration>
mapper映射文件:
<mapper namespace="test">
<select id="findUserById" parameterType="int"
resultType="com.kkb.mybatis.phase01.po.User" statementType="STATEMENT">
SELECT * FROM user WHERE id = #{id} AND username = #{username}
<if test="">
AND age = #{age}
</if>
</select>
</mapper>
注意事项:
sql解析流程,不是一边执行,一边解析,而是需要一次性的先解析完成配置文件,将所有解析出来的数据封装到Configuration对象中。
sql解析流程(从配置文件中获取JDBC需要的数据信息)
-
完成全局配置文件的读取和解析工作,最终将解析出来的信息,封装到【Configuration】对象中
a)运行时环境信息,其实在此指DataSource的配置信息,将DataSource封装到Configuration对象中存储。
b)在加载全局配置文件的时候,就会触发映射文件的加载。
c)映射文件的加载,先去针对每个select标签进行解析,获取 【id值(statementId),sql语句,参数类型,结果类型,statement类型】最终将解析出来的信息,封装到【MappedStatement】对象,将该对象封装到Map集合中,key为statementID,value就是该对象,然后将集合存储到【Configuration】对象中
d)MappedStatement对象中存储sql信息,是通过【SQLSource】进行存储的。
SqlSource对象,不只是存储sql信息,而且还提供对存储的sql信息进行处理的功能
e)SqlSource是通过一个SqlNode集合数据来封装sql信息。SQL执行流程(使用JDBC代码,加上从配置文件中读取的SQL相关信息,就可以完成CRUD的执行过程)
【获取数据源对象(需要driverclassname、url、username、password)提升创建Connection的性能】 【获取Configuration对象,从该对象中获取DataSource对象】 【有了DataSource对象,就可以从该对象中获取Connection对象】 // 加载数据库驱动 Class.forName(driverclassName); // 通过驱动管理类获取数据库链接connection = DriverManager connection = DriverManager.getConnection(url,username, password); 【获取JDBC可以执行的SQL语句,其实此处获取的是BoundSql,此时其实调用的就是【SqlSource】的SQL解析功能】 【从BoundSql中获取SQL语句】 // 定义sql语句 ?表示占位符 String sql = sqlStr; 【从MappedStatement对象中获取statement的类型:simple、prepared、callable】 【根据不同的statement去创建不同的Statement对象】 // 获取预处理 statement preparedStatement = connection.prepareStatement(sql); 【从BoundSql中获取参数集合信息List<ParameterMapping>】 【遍历给参数赋值,先需要读取ParameterMapping中的属性名称从入参对象中获取指定属性的值】 【调用JDBC代码,完成属性设置】 // 设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的 preparedStatement.setString(1, "王五"); 【执行statemement,并获取结果集ResultSet】 // 向数据库发出 sql 执行查询,查询出结果集 rs = preparedStatement.executeQuery(); 【从MappedStatement对象中获取输出结果类型,也就是结果要映射的类型】 【遍历结果集,获取结果集中每一行的数据】 【获取结果集中每一行每一列的数据,获取列的名称】 【根据列的名称,通过反射,去设置要映射的java类型的指定属性值】 // 遍历查询结果集 while (rs.next()) { System.out.println(rs.getString("id") + " " + rs.getString("username")); }