本文目录导读:

我来为你提供一个完整的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>
注意事项
- 必须包含WHERE条件:避免误更新全表
- 选择性更新优势:使用
<set>标签只更新非空字段 - 版本控制:建议添加乐观锁字段防止并发问题
- 大数据量批量更新:避免一次性更新过多数据,建议分批处理
- 事务管理:涉及多条更新操作时,务必使用事务
这个案例涵盖了MyBatis修改操作的常见场景,你可以根据实际需求选择合适的方式。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播