MyBatis通过动态代理自动生成Mapper接口实现类,运行时将接口方法绑定到SQL语句,结合XML映射文件中的SQL与参数配置,由SqlSession执行并返回结果,避免了手动编写实现类的繁琐过程。

MyBatis 的 Mapper 接口实际上并不需要我们手动去写实现类,它的工作方式有点像“魔法”,但背后是扎实的框架机制在支撑。简单来说,MyBatis 通过动态代理,在运行时生成接口的实现类,并将 SQL 语句绑定到这些实现类的方法上。
解决方案:
MyBatis 的 Mapper 接口工作流程主要依赖于以下几个核心机制:
接口定义: 首先,你需要定义一个 Mapper 接口,这个接口中的方法对应着你想要执行的 SQL 操作。接口方法可以接受参数,也可以返回结果。
public interface UserMapper {
User getUserById(int id);
List<User> getAllUsers();
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}SQL 映射文件: 然后,你需要创建一个 XML 映射文件,这个文件与 Mapper 接口对应,并且包含了 SQL 语句和接口方法之间的映射关系。
<mapper namespace="com.example.UserMapper">
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="getAllUsers" resultType="com.example.User">
SELECT * FROM users
</select>
<insert id="insertUser" parameterType="com.example.User">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
<update id="updateUser" parameterType="com.example.User">
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>动态代理: 当你通过
SqlSession
方法拦截和 SQL 执行: 当代理对象拦截到方法调用时,它会根据方法名和参数,在 XML 映射文件中查找对应的 SQL 语句。然后,它会使用
SqlSession
结果返回: 最后,代理对象会将执行结果返回给调用者。
为什么没有实现类?因为 MyBatis 在运行时动态生成了实现类。 这避免了大量重复的样板代码,也使得代码更加简洁和易于维护。想象一下,如果每个 Mapper 接口都要手动写一个实现类,那将会是一场噩梦。
MyBatis 通过
SqlSessionFactoryBuilder
SqlSessionFactory
具体来说,MyBatis 会使用
XMLConfigBuilder
XMLMapperBuilder
XMLMapperBuilder
MappedStatement
MappedStatement
Configuration
如果你的Mapper文件没有正确加载,可能会遇到
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
Spring Boot 提供了
mybatis-spring-boot-starter
添加依赖: 首先,需要在
pom.xml
mybatis-spring-boot-starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version> <!-- 请使用最新版本 -->
</dependency>配置数据源: 然后,需要在
application.properties
application.yml
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase spring.datasource.username=root spring.datasource.password=password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
配置 MyBatis: 接下来,可以在
application.properties
application.yml
mybatis.mapper-locations=classpath:mapper/*.xml mybatis.configuration.map-underscore-to-camel-case=true
使用 Mapper 接口: 最后,可以使用
@Autowired
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUserById(int id) {
return userMapper.getUserById(id);
}
}注意, Spring Boot 会自动扫描 Mapper 接口,并将其注册为 Spring Bean。 如果你没有看到你的Mapper Bean被注入,检查你的启动类是否添加了
@MapperScan
@MapperScan("com.example.mapper")MyBatis 的动态 SQL 功能允许你根据不同的条件动态生成 SQL 语句,这在处理复杂的查询场景时非常有用。 动态 SQL 的实现依赖于 MyBatis 提供的各种标签,例如
<if>
<choose>
<when>
<otherwise>
<where>
<set>
<foreach>
<if>
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM blog
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select><choose>
<when>
<otherwise>
switch
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM blog
WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select><where>
WHERE
AND
OR
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM blog
<where>
state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select><set>
UPDATE
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
bio=#{bio}
</set>
where id=#{id}
</update><foreach>
IN
<select id="selectPostIn" resultType="Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>在使用动态 SQL 时,需要注意 SQL 注入的风险。 尽量使用
#
${}#
以上就是MyBatis 的Mapper接口是如何工作的?为什么没有实现类?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号