Mybatis 的代理开发方式
MyBatis 的 代理开发方式(Mapper 接口代理)是其核心特性之一,通过动态代理技术,将 Mapper 接口的方法调用自动映射到 XML 或注解中定义的 SQL 语句。这种方式避免了手动编写 DAO 实现类,极大简化了持久层代码。
1.代理开发的核心原理
-
动态代理机制
MyBatis 在运行时通过 JDK 动态代理 为 Mapper 接口生成代理对象。当调用接口方法时,代理对象会根据方法名、参数和返回类型,找到对应的 SQL 并执行。 -
映射规则
- XML 映射:接口方法名与 XML 中的
<select|insert|update|delete>
标签的id
匹配。 - 注解映射:直接在接口方法上使用
@Select
、@Insert
等注解定义 SQL。
- XML 映射:接口方法名与 XML 中的
-
核心组件
- Mapper 接口:定义数据库操作方法。
- 映射文件/注解:绑定 SQL 与接口方法。
- SqlSession.getMapper():获取接口的代理对象。
2.代理开发步骤(XML方式)
2.1定义Mapper接口
public interface UserMapper {
// 根据ID查询用户
User selectById(int id);
// 插入用户
int insert(User user);
// 更新用户
int update(User user);
// 删除用户
int delete(int id);
}
2.2创建XML映射文件
在resource/mapper/UserMapper.xml中编写SQL:
<?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.example.mapper.UserMapper">
<!-- 根据ID查询 -->
<select id="selectById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<!-- 插入用户 -->
<insert id="insert" parameterType="User">
INSERT INTO user (name, age)
VALUES (#{name}, #{age})
</insert>
<!-- 更新用户 -->
<update id="update" parameterType="User">
UPDATE user SET name = #{name}, age = #{age}
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="delete" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>
2.3配置myBatis核心文件
在mybatis-config.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.example.mapper.UserMapper">
<!-- 根据ID查询 -->
<select id="selectById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<!-- 插入用户 -->
<insert id="insert" parameterType="User">
INSERT INTO user (name, age)
VALUES (#{name}, #{age})
</insert>
<!-- 更新用户 -->
<update id="update" parameterType="User">
UPDATE user SET name = #{name}, age = #{age}
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="delete" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>
2.4获取对象并调用方法
// 1. 获取 SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 2. 获取 Mapper 代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 3. 调用接口方法执行 SQL
User user = userMapper.selectById(1);
int rows = userMapper.insert(new User("Alice", 25));
// 4. 提交事务并关闭会话
sqlSession.commit();
sqlSession.close();
3.代理开发方式(注解方式)
3.1使用注解定义SQL
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(int id);
@Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
int update(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int delete(int id);
}
3.2配置扫描mapper接口
在mybatis-config.xml中指定包接口路径
<mappers>
<package name="com.example.mapper"/>
</mappers>
4.注意事项
Mapper接口开发方法只需要编写Mapper接口(相当于DAO接口),由MyBatis框架根据接口定义创建接口的动态代理对象。
Mapper接口开发需要遵循以下规范:
- Mapper.xml文件中的namespace与mapper接口的全限定名相同
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的patameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType类型相同