一、传统开发方式
1. 编写UserMapper接口
public interface UserMapper {
public List<User> findAll() throws Exception;
}
2. 编写UserMapper实现
public class UserMapperImpl implements UserMapper {
@Override
public List<User> findAll() throws Exception {
// 加载配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 获取SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 获取SqlSe会话对象
// openSession(boolean autoCommit) 参数为是否自动提交,true:不需要手动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(); // 手动提交事务
// 执行sql
List<User> list = sqlSession.selectList("UserMapper.findAll");
// 释放资源
sqlSession.close();
return list;
}
}
3. 编写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="UserMapper">
<!--查询所有-->
<select id="findAll" resultType="user">select * from user</select>
</mapper>
存在思考:
1.
实现类中,存在
mybatis
模板代码重复
2.
实现类调用方法时,
xml
中的
sql statement
硬编码到
java
代码中
?:能否只写接口,不写实现类。只编写接口和
Mapper.xml
即可?
因为在
dao
(
mapper
)的实现类中对
sqlsession
的使用方式很类似。因此
mybatis
提供了接口的动态代理。
二、代理开发方式
介绍:基于接口代理方式的开发只需要编写 Mapper 接口,Mybatis 框架会为我们动态生成实现类的对象。
开发规范:
1. 编写UserMapper接口
public interface UserMapper {
public List<User> findAll() throws Exception;
}
2. 编写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="UserMapper">
<!--查询所有-->
<select id="findAll" resultType="user">select * from user</select>
</mapper>
3. 测试
@Test
public void testFindAll() throws Exception {
// 加载核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 获得SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 获得SqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获得Mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询
List<User> list = userMapper.findAll();
for (User user : list) {
System.out.println(user);
}
// 释放资源
sqlSession.close();
}
4. 代理方式的内部实现原理
- 代理的mapper对象是有MapperProxy代理产生的:
- 追踪MapperProxy代码中的invoke方法,发现最终调用的是mapperMethod.execute(sqlSession, args)
- 进入execute方法,最终工作的还是sqlSession