1. MyBatis单表操作的核心价值与适用场景
在Java持久层框架的选型中,MyBatis因其灵活的SQL掌控能力而备受开发者青睐。单表增删改查(CRUD)作为数据库操作的基础单元,看似简单却蕴含着许多值得深究的技术细节。我在实际项目中发现,即使是经验丰富的开发者也常在这些基础操作上踩坑——或是过度封装导致灵活性丧失,或是裸写SQL引发安全隐患。
MyBatis处理单表操作时提供了多种实现路径:原生XML映射、注解方式、以及流行的MyBatis-Plus扩展。每种方式都有其最佳实践场景,比如简单的用户管理模块适合用注解快速开发,而复杂的分页查询可能更需要XML的动态SQL能力。近期奇安信安全扫描频繁报出的SQL注入漏洞,很多正是源于开发者在${}和#{}参数传递上的错误选择。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础环境搭建与配置
2.1 项目依赖配置
以Maven项目为例,基础依赖需包含mybatis核心库和数据库驱动。建议锁定版本号以避免兼容性问题:
xml复制<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
注意:当与其他框架(如Flowable工作流)集成时,需检查是否存在配置覆盖问题。我曾遇到flowable-ui的自动配置覆盖了自定义MyBatis设置的情况,解决方案是在启动类添加@MapperScan明确指定扫描路径。
2.2 数据源与SqlSessionFactory配置
在application.yml中配置数据源时,建议开启SQL日志以便调试:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
对于XML映射文件的位置,我习惯在resources下建立层级目录结构(如mapper/user/UserMapper.xml),这样既保持了整洁又便于多模块管理。需要在配置中明确指定映射文件路径:
java复制@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/**/*.xml"));
return sessionFactory.getObject();
}
3. 单表CRUD的四种实现方式
3.1 XML映射文件方式
这是最传统的MyBatis使用方式,适合复杂SQL场景。以用户表操作为例,首先定义UserMapper接口:
java复制public interface UserMapper {
User selectById(@Param("id") Long id);
List<User> selectAll();
int insert(User user);
int update(User user);
int delete(@Param("id") Long id);
}
对应的UserMapper.xml需要严格遵循MyBatis的DTD规范:
xml复制<mapper namespace="com.example.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.example.entity.User">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="username" property="username" jdbcType="VARCHAR"/>
<result column="email" property="email" jdbcType="VARCHAR"/>
</resultMap>
<select id="selectById" resultMap="BaseResultMap">
SELECT * FROM user WHERE id = #{id}
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user(username, email)
VALUES(#{username}, #{email})
</insert>
</mapper>
关键细节:insert操作中的useGeneratedKeys和keyProperty配合使用,可以自动将数据库生成的主键回填到实体对象中,这是很多新手容易忽略的实用特性。
3.2 注解方式开发
对于简单的CRUD,可以使用注解替代XML。这种方式代码更集中,但复杂SQL可读性会下降:
java复制public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(Long id);
@Insert("INSERT INTO user(username,email) VALUES(#{username},#{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE user SET username=#{username}, email=#{email} WHERE id=#{id}")
int update(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
int delete(Long id);
}
3.3 MyBatis-Plus的Active Record模式
MyBatis-Plus的Active Record模式让单表操作更加简洁:
java复制@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String email;
public void save() {
this.insert();
}
}
// 使用示例
User user = new User();
user.setUsername("test");
user.setEmail("test@example.com");
user.save();
3.4 动态SQL构建
对于条件查询,MyBatis提供了强大的动态SQL能力。以下是使用
