mybatis源码解析(一)环境准备和测试
1、准备环境
项目结构

maven依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
</dependencies>
mybatis-config.xml
<?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>
<properties resource="jdbc.properties"></properties>
<settings>
<setting name="logImpl" value="LOG4J"/></settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com.whf/UserMapper.xml"/>
</mappers>
</configuration>
jdbc.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo
username=root
password=admin
log4j.properties
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
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.whf.mapper.UserMapper">
<select id="selectById" resultType="com.whf.entity.User">
select * from user where id = #{id}
</select>
</mapper>
UserMapper
public interface UserMapper {
User selectById(Integer id);
@Select("select * from user")
List<User> selectAll();
}
User
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
数据库

测试类 MybatisDemo
public class MybatisDemo {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectById(3);
System.out.println(user);
List<User> users = mapper.selectAll();
System.out.println(users);
}
}
运行main方法,获得输出结果
DEBUG [main] (JdbcTransaction.java:136) - Opening JDBC Connection
DEBUG [main] (PooledDataSource.java:424) - Created connection 258931371.
DEBUG [main] (JdbcTransaction.java:100) - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f6efaab]
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Preparing: select * from user where id = ?
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Parameters: 3(Integer)
DEBUG [main] (BaseJdbcLogger.java:143) - <== Total: 1
User{name='fc26d', age=18}
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Preparing: select * from user
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Parameters:
DEBUG [main] (BaseJdbcLogger.java:143) - <== Total: 8
[User{name='86b30', age=18}, User{name='20d79', age=18}, User{name='fc26d', age=18}, User{name='a711a', age=18}, User{name='1274f', age=18}, User{name='6774b', age=18}, User{name='b19c9', age=18}, User{name='68f29', age=18}]
看输出说明成功用mybatis查询数据库,先简单分析下main方法,下一篇再开始深入分析源码
1)SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory 主要作用就是初始化mybatis,扫描xml文件并且读取配置文件,最终转化为java对象(Configuration),最终SqlSessionFactory 持有Configuration对象,每个应用只有一个SqlSessionFactory和Configuration对象
2)SqlSession session = sqlSessionFactory.openSession();
SqlSession 是操作sql的对象,操作sql肯定会考虑到事务,所以SqlSession会创建事务。
如何操作sql? => CRUD ,所以会有执行器去执行sql, 也就是Executor对象,执行器有三种类型
public enum ExecutorType {
SIMPLE, // 简单类型
REUSE, // 重用类型
BATCH // 批量处理类型
}
3)UserMapper mapper = session.getMapper(UserMapper.class);
获取UserMapper 对象,由于UserMapper定义的是接口,没有实现类,所以想要调用方法操作数据库,所以这个对象肯定是代理对象了。mybatis底层使用的是jdk动态代理。
4)User user = mapper.selectById(3);
动态代理调用方法一般都是进入InvocationHandler的invoke方法,到时直接分析invoke方法即可。看mybatis是如何执行sql的
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)