方式一:传统API方式

@Test
public void add() throws IOException {
// 1.通过Resources对象加载配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream );
// 3.通过SqlSessionFactory对象获取SQLSession对象
SqlSession session = factory.openSession();
User user = new User();
user.setName("dpb");
user.setAge(22);
// dpb.addUser 是映射文件中 namespace的内容加 id的内容,定位要执行的SQL
int count = session.insert("dpb.addUser", user);
System.out.println("影响的行数:"+count);
// 需要显示的提交
session.commit();
session.close();
}

1.怎么加载配置文件的

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

进入getResourceAsStream方法

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHP

扩展知识

2.怎么获取SqlSessionFactory对象的

// 2.获取SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(inputStream );

源码分析

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHP

3.获取SqlSession对象

SqlSession session = factory.openSession();

mybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

SimpleExecutor就是普通的执行器
ReuseExecutor执行器会重用预处理语句(prepared statements)
BatchExecutor批量执行器

mybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHP

创建执行器的过程

mybatis教程之原理剖析-LMLPHP

4.insert方法执行的过程

int i = session.insert("aaa.addUser", user);
<?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="aaa">
<insert id="addUser" parameterType="com.sxt.bean.User">
insert into t_user(name,age)values(#{name},#{age})
</insert>
</mapper>

代码跟踪:

mybatis教程之原理剖析-LMLPHP添加数据进入DefaultSqlSession方法后调用的还是update方法

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP

回到此处

mybatis教程之原理剖析-LMLPHP进入update方法 ==

mybatis教程之原理剖析-LMLPHP注意进入的是PreparedStatementHandler==

怎么会进入PreparedStatementHandler的?不是SimpleExecutor处理器,应该进入SimpleStatementHandler吗?

mybatis教程之原理剖析-LMLPHP参数在哪动态绑定的呢?

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP按照相同的方式可以跟踪下查询的方法,代码就在此不贴出来了。

SqlSessionFactory顶层API,提供SQLSession对象,获取的同时加载配置文件
configuration封装的有全局配置文件和各个映射文件的相关信息
SqlSession顶层API,和数据库交互完成增删改查操作
MappedStatement封装了一条insert|update|delete|select节点信息。
Executor执行器,调度核心,SimpleExecutor,ReuseExecutor,BatchExecutor.
StatementHandler封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合
BoundSql封装的有动态SQL及对应的参数信息。
TypeHandler类型处理器,java类型和数据库字段类型的转换
ResultSetHandler负责将jdbc的ResultSet的结果和java中List的数据相互转换

方式二:基于Mapper接口方式

@Test
public void add() throws IOException {
// 1.通过Resources对象加载配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream );
// 3.通过SqlSessionFactory对象获取SQLSession对象
SqlSession session = factory.openSession();
User user = new User();
user.setName("dpb");
user.setAge(22);
//通过Java动态代理自动提供了UserMapper的实现类
UserMapper mapper = session.getMapper(UserMapper.class);
int count = mapper.addUser(user);
System.out.println("影响的行数:"+count);
session.commit();
}

通过jdk动态代理简单实现

bean对象

	private int id;

	private String name;

	private int age;

接口文件

public interface UserMapper {

	public int addUser(User user);

	public int updateById(User user);

	public int deleteById(int id);

	public User queryById(int id);
}

接口实现类

public class UserDao implements UserMapper {

	@Override
public int addUser(User user) { return DBUtils.getInstall().openSession().insert("com.sxt.dao.UserMapper.addUser", user);
} @Override
public int updateById(User user) {
// TODO Auto-generated method stub
return DBUtils.getInstall().openSession().update("com.sxt.dao.UserMapper.updateById", user);
} @Override
public int deleteById(int id) {
// TODO Auto-generated method stub
return DBUtils.getInstall().openSession().delete("com.sxt.dao.UserMapper.deleteById", id);
} @Override
public User queryById(int id) {
// TODO Auto-generated method stub
return DBUtils.getInstall().openSession().selectOne("com.sxt.dao.UserMapper.queryById", 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.sxt.dao.UserMapper">
<insert id="addUser" parameterType="com.sxt.bean.User">
insert into t_user(name,age)values(#{name},#{age})
</insert> <delete id="deleteById" parameterType="java.lang.Integer">
delete from t_user where id=#{id}
</delete> <update id="updateById" parameterType="com.sxt.bean.User">
update t_user
set name=#{name},age=#{age}
where id=#{id}
</update> <select id="queryById" parameterType="java.lang.Integer"
resultType="com.sxt.bean.User">
select * from t_user where id=#{id}
</select>
</mapper>

目录结构

mybatis教程之原理剖析-LMLPHP

到此我们发现接口实现UserDao,其实就是个模板,没有特定的内容,这时我们可以将其删掉通过jdk代理的方式实现

测试文件

/**
* 代理方式
*/
@Test
public void test(){
UserMapper mapper = (UserMapper) Proxy.newProxyInstance(UserMapper.class.getClassLoader()
, new Class[]{UserMapper.class},new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(UserMapper.class.getName()+"."+method.getName());
Object id = null;
for (Object object : args) {
System.out.println(object);
id = object;
} // 实现逻辑
return DBUtils.getInstall().openSession().selectOne(UserMapper.class.getName()+"."+method.getName(), id);
}
} );
System.out.println(mapper.queryById(5));
}

mybatis教程之原理剖析-LMLPHP测试成功

源码跟踪

mybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHPmybatis教程之原理剖析-LMLPHP源码中看到jdk代理实现的代码。结束~~~

05-11 14:11