目录
简单使用
引出主题
看图
提到看源码,很多同学内心的恐惧的,其实这个从人性的角度来说是非常正常的,因为人们对未知的事物,都是非常恐惧的,其次,你内心可能始终觉得,好像不会原理也还是能工作啊,你的潜意识里没有强烈的欲望.从阅读源码的经历来说,Java三大框架SSM中,Mybatis的源码是最适合入门的.
简单使用
这是一个简单的Mybatis保存对象的例子
@Test
public void testSave() throws Exception {//创建sessionFactory对象SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));//获取session对象SqlSession session = sf.openSession();//创建实体对象User user = new User();user.setUsername("toby");user.setPassword("123");user.setAge(23);//保存数据到数据库中session.insert("com.toby.mybatis.domain.UserMapper.add", user);//提交事务,这个是必须要的,否则即使sql发了也保存不到数据库中session.commit();//关闭资源session.close();
}
<mapper namespace="com.toby.mybatis.domain.UserMapper"><!--#{}在传入的对象中找对应的属性值--><!--parameterType传入的参数是什么类型--><insert id="add" parameterType="com.toby.mybatis.domain.User">INSERT INTO USER (username,password,age) VALUES (#{username},#{password},#{age})</insert>
</mapper>
引出主题
但是在实际中,我们都不是这样操作的,我们是通过Mapper接口,调用接口方法,就能实现CRUD操作,那么关键是,这个接口究竟做了什么事,才是我们关心的.
只要把下面这段代码究竟发生了什么事弄明白,就明白,这个Mapper接口究竟做了什么事.
public void testGetObject() throws Exception {SqlSession session = MybatisUtil.openSession();UserMapper mapper = session.getMapper(UserMapper.class);User user = mapper.get(5L);System.out.println(user);session.close();
}
public interface UserMapper {public void add(User user);public User get(Long id);
}
看图
但是我认为,一张流程图就能够看明白这期间所发生的事
1.invoke方法什么时候执行的?
jdk动态代理创建代理对象的时候需要传入三个参数,分别为(1)类加载器,(2)为哪些接口做代理(拦截什么方法),(3)把这些方法拦截到哪里处理,从图中我们得知,他是要把执行的方法拦截到MapperProxy类中的invoke方法处理,换句话说,该动态代理对象执行接口中的方法,都会调到MapperProxy类的invoke方法处理,这也就是为什么调用get方法的时候会调用invoke
2.执行过程
图中已经比较明显,那我还是文字给你简单描述一下原理.mapper文件中要定位到sql,需要两个条件,一个是namespace,一个是sql id.要想用这种mapper接口的方式调用也必须遵循一个约定,那就是namespace等于接口的全限定名.接口的方法名等于xml文件中的sql id,这就是为什么图中封装MapperMethod的时候,需要把这两个传进去的原因.确定了sql,传入参数mapperMethod.execute(args),拼接成一条完成sql,执行之.
心血来潮再补上一张时序图
想了解Mybatis缓存的移步Hibernate和Mybaitis缓存