之前简单介绍了 MyBatis 持久层框架对于数据的持久化操作。这一篇是对上篇的补充,介绍几个相关的知识点。
MyBatis 架构
- mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。 - 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
- 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
- Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
原始的Dao开发
原始Dao开发方法需要程序员编写Dao接口和Dao实现类。
Dao
public interface UserDao {
public User findUserByIdTest(Integer id);
}
DaoImpl
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserByIdTest(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession.selectOne("userMapper.findUserById",id );
}
}
编写映射文件User.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="findUserById" parameterType="int" resultType="main.java.bean.User">
select * from user where id = #{id}/*#占位符里面随便用*/
</select>
测试类----充当Service层的角色
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() {
String resource = "main/resources/mybatis-config.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
@Test
public void testDao(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserByIdTest(1);
System.out.println(user);
}
}
配置文件 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="main/resources/jdbc.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.DriverClassName}" />
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- Mapper的位置 Mapper.xml 写Sql语句的文件的位置 -->
<mappers>
<mapper resource="main/resources/mapper/User.xml"/>
</mappers>
</configuration>
原始Dao开发中存在以下问题:
- Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
- 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。
Mapper动态代理方式
Mapper接口开发方法只需要编写Mapper接口,由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
1、Mapper.xml文件中的 namespace 与 mapper 接口的类路径相同。
2、Mapper接口方法名和 Mapper.xml 中定义的每个 statement 的id相同
3、Mapper接口方法的输入参数类型和 mapper.xml 中定义的每个sql 的 parameterType 的类型相同
4、Mapper接口方法的输出参数类型和 mapper.xml 中定义的每个sql的 resultType 的类型相同
谨记以上4点就不会有错误
书写接口
public interface UserMapper {
public User findUserById(int id);
}
映射文件 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="main.java.maping.UserMapper">
<select id="findUserById" parameterType="int" resultType="main.java.bean.User">
select * from user where id = #{id}
</select>
测试文件
public class MapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() {
String resource = "main/resources/mybatis-config.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}
@Test
public void test(){
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
}
mybatis官方推荐使用mapper代理方法开发mapper接口
mappers(映射器)
Mapper配置的几种方法:
<mapper resource=" " />
使用相对于类路径的资源(现在的使用方式)
如: < mapper resource=“main/resources/mapper/User.xml” />
<mapper class=" " />
使用mapper接口类路径
如: < mapper class=“main.java.maping.UserMapper”/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<package name=""/>
注册指定包下的所有mapper接口
如:< package name=“main.java.maping”/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。