Java MyBatis修改案例怎么开发

wen java案例 23

本文目录导读:

Java MyBatis修改案例怎么开发

  1. 基础环境准备
  2. 实体类定义
  3. XML映射文件开发方式
  4. 注解开发方式
  5. Service层实现
  6. 完整测试案例
  7. 性能优化建议
  8. 注意事项

我来为你提供一个完整的MyBatis修改(更新)操作案例,包含从基础到进阶的开发方式。

基础环境准备

1 数据库表结构

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `status` tinyint(4) DEFAULT '1',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2 Maven依赖

<dependencies>
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <!-- 连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.20</version>
    </dependency>
</dependencies>

实体类定义

// User.java
public class User {
    private Long id;
    private String username;
    private String password;
    private String email;
    private String phone;
    private Integer status;
    private Date createTime;
    private Date updateTime;
    // getters and setters... (省略具体实现)
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", phone='" + phone + '\'' +
                ", status=" + status +
                '}';
    }
}

XML映射文件开发方式

1 Mapper接口

// UserMapper.java
public interface UserMapper {
    // 根据ID更新
    int updateById(User user);
    // 选择性更新(只更新非空字段)
    int updateSelective(User user);
    // 批量更新
    int batchUpdate(List<User> userList);
    // 根据条件更新
    int updateByCondition(@Param("user") User user, 
                         @Param("condition") UserCondition condition);
}

2 XML映射文件

<!-- 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="com.example.mapper.UserMapper">
    <!-- 基础更新 -->
    <update id="updateById">
        UPDATE user 
        SET username = #{username},
            password = #{password},
            email = #{email},
            phone = #{phone},
            status = #{status},
            update_time = NOW()
        WHERE id = #{id}
    </update>
    <!-- 选择性更新(动态SQL) -->
    <update id="updateSelective">
        UPDATE user
        <set>
            <if test="username != null">username = #{username},</if>
            <if test="password != null">password = #{password},</if>
            <if test="email != null">email = #{email},</if>
            <if test="phone != null">phone = #{phone},</if>
            <if test="status != null">status = #{status},</if>
            update_time = NOW()
        </set>
        WHERE id = #{id}
    </update>
    <!-- 批量更新 -->
    <update id="batchUpdate">
        <foreach collection="list" item="user" separator=";">
            UPDATE user
            <set>
                <if test="user.username != null">username = #{user.username},</if>
                <if test="user.password != null">password = #{user.password},</if>
                <if test="user.email != null">email = #{user.email},</if>
                <if test="user.phone != null">phone = #{user.phone},</if>
                update_time = NOW()
            </set>
            WHERE id = #{user.id}
        </foreach>
    </update>
    <!-- 根据条件更新 -->
    <update id="updateByCondition">
        UPDATE user
        <set>
            <if test="user.username != null">username = #{user.username},</if>
            <if test="user.email != null">email = #{user.email},</if>
            <if test="user.phone != null">phone = #{user.phone},</if>
            update_time = NOW()
        </set>
        <where>
            <if test="condition.id != null">AND id = #{condition.id}</if>
            <if test="condition.username != null">AND username = #{condition.username}</if>
            <if test="condition.status != null">AND status = #{condition.status}</if>
        </where>
    </update>
</mapper>

注解开发方式

// UserMapperAnnotation.java
public interface UserMapperAnnotation {
    @Update("UPDATE user SET username=#{username}, email=#{email}, " +
            "phone=#{phone}, update_time=NOW() WHERE id=#{id}")
    int updateById(User user);
    @Update({
        "<script>",
        "UPDATE user",
        "<set>",
        "<if test='username != null'>username=#{username},</if>",
        "<if test='email != null'>email=#{email},</if>",
        "<if test='phone != null'>phone=#{phone},</if>",
        "update_time=NOW()",
        "</set>",
        "WHERE id=#{id}",
        "</script>"
    })
    int updateSelective(User user);
    @Update({
        "<script>",
        "<foreach collection='list' item='user' separator=';'>",
        "UPDATE user",
        "<set>",
        "<if test='user.username != null'>username=#{user.username},</if>",
        "<if test='user.email != null'>email=#{user.email},</if>",
        "update_time=NOW()",
        "</set>",
        "WHERE id=#{user.id}",
        "</foreach>",
        "</script>"
    })
    int batchUpdate(List<User> userList);
}

Service层实现

// UserService.java
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    // 完整更新
    public boolean updateUser(User user) {
        if (user.getId() == null) {
            throw new IllegalArgumentException("ID不能为空");
        }
        return userMapper.updateById(user) > 0;
    }
    // 选择性更新(推荐使用)
    public boolean updateUserSelective(User user) {
        if (user.getId() == null) {
            throw new IllegalArgumentException("ID不能为空");
        }
        return userMapper.updateSelective(user) > 0;
    }
    // 批量更新
    public int batchUpdateUsers(List<User> userList) {
        if (CollectionUtils.isEmpty(userList)) {
            return 0;
        }
        return userMapper.batchUpdate(userList);
    }
    // 带事务的更新
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserWithTransaction(User user) {
        // 先更新
        int result = userMapper.updateSelective(user);
        // 记录日志(假设有日志表)
        // logMapper.insertUpdateLog(user.getId(), "更新用户信息");
        return result > 0;
    }
}

完整测试案例

// MyBatisUpdateTest.java
@SpringBootTest
@RunWith(SpringRunner.class)
public class MyBatisUpdateTest {
    @Autowired
    private UserService userService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L);
        user.setUsername("新用户名");
        user.setEmail("newemail@example.com");
        user.setPhone("13800138000");
        user.setStatus(1);
        boolean success = userService.updateUser(user);
        Assert.assertTrue("更新失败", success);
    }
    @Test
    public void testUpdateSelective() {
        // 只更新邮箱和电话
        User user = new User();
        user.setId(1L);
        user.setEmail("updated@example.com");
        user.setPhone("13900139000");
        boolean success = userService.updateUserSelective(user);
        Assert.assertTrue("更新失败", success);
    }
    @Test
    public void testBatchUpdate() {
        List<User> userList = new ArrayList<>();
        User user1 = new User();
        user1.setId(1L);
        user1.setEmail("user1@example.com");
        User user2 = new User();
        user2.setId(2L);
        user2.setEmail("user2@example.com");
        userList.add(user1);
        userList.add(user2);
        int result = userService.batchUpdateUsers(userList);
        Assert.assertEquals(2, result);
    }
    @Test
    public void testUpdateWithTransaction() {
        User user = new User();
        user.setId(1L);
        user.setUsername("事务更新测试");
        user.setEmail("transaction@example.com");
        boolean success = userService.updateUserWithTransaction(user);
        Assert.assertTrue("事务更新失败", success);
    }
    @Test
    public void testSqlSessionFactoryUpdate() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setId(1L);
            user.setEmail("session@example.com");
            int result = mapper.updateSelective(user);
            sqlSession.commit();
            Assert.assertEquals(1, result);
        } finally {
            sqlSession.close();
        }
    }
}

性能优化建议

1 批量更新优化

// 使用批量更新时,建议开启批量执行模式
@Configuration
public class MyBatisConfig {
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        // 配置批量执行器
        org.apache.ibatis.session.Configuration configuration = 
            new org.apache.ibatis.session.Configuration();
        configuration.setDefaultExecutorType(ExecutorType.BATCH);
        sessionFactory.setConfiguration(configuration);
        return sessionFactory.getObject();
    }
}

2 使用批量更新语句

<!-- 使用CASE WHEN进行批量更新(更高效) -->
<update id="batchUpdateByCase">
    UPDATE user
    SET email = CASE id
        <foreach collection="list" item="item">
            WHEN #{item.id} THEN #{item.email}
        </foreach>
    END,
    phone = CASE id
        <foreach collection="list" item="item">
            WHEN #{item.id} THEN #{item.phone}
        </foreach>
    END,
    update_time = NOW()
    WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</update>

注意事项

  1. 必须包含WHERE条件:避免误更新全表
  2. 选择性更新优势:使用<set>标签只更新非空字段
  3. 版本控制:建议添加乐观锁字段防止并发问题
  4. 大数据量批量更新:避免一次性更新过多数据,建议分批处理
  5. 事务管理:涉及多条更新操作时,务必使用事务

这个案例涵盖了MyBatis修改操作的常见场景,你可以根据实际需求选择合适的方式。

抱歉,评论功能暂时关闭!