Java MyBatis新增案例如何实现

wen java案例 28

本文目录导读:

Java MyBatis新增案例如何实现

  1. 基础新增实现
  2. 获取生成的主键
  3. 批量新增
  4. 高级新增场景
  5. 完整示例代码
  6. 最佳实践
  7. 常见问题处理

我来详细说明Java MyBatis新增数据的实现方法,包括常见场景和最佳实践。

基础新增实现

1 Mapper接口定义

public interface UserMapper {
    // 单个新增
    int insert(User user);
    // 返回自增主键
    int insertWithKey(User user);
    // 选择性新增(不为null的字段才插入)
    int insertSelective(User user);
}

2 XML映射文件

<!-- 基础新增 -->
<insert id="insert" parameterType="User">
    INSERT INTO user(name, age, email, create_time)
    VALUES(#{name}, #{age}, #{email}, #{createTime})
</insert>
<!-- 返回自增主键 -->
<insert id="insertWithKey" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user(name, age, email, create_time)
    VALUES(#{name}, #{age}, #{email}, #{createTime})
</insert>
<!-- 选择性新增 -->
<insert id="insertSelective" parameterType="User">
    INSERT INTO user
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="name != null">name,</if>
        <if test="age != null">age,</if>
        <if test="email != null">email,</if>
        <if test="createTime != null">create_time,</if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
        <if test="name != null">#{name},</if>
        <if test="age != null">#{age},</if>
        <if test="email != null">#{email},</if>
        <if test="createTime != null">#{createTime},</if>
    </trim>
</insert>

获取生成的主键

1 使用自增主键

// 方式一:自动获取(推荐)
@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
// 使用
User user = new User("张三", 25);
userMapper.insert(user);
System.out.println("生成的主键:" + user.getId()); // 直接获取

2 使用UUID主键

<!-- 在插入前生成UUID -->
<insert id="insertWithUUID">
    <selectKey keyProperty="id" resultType="String" order="BEFORE">
        SELECT REPLACE(UUID(), '-', '')
    </selectKey>
    INSERT INTO user(id, name, age)
    VALUES(#{id}, #{name}, #{age})
</insert>

批量新增

1 使用foreach

<!-- 批量新增 -->
<insert id="batchInsert" parameterType="java.util.List">
    INSERT INTO user(name, age, email)
    VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.name}, #{item.age}, #{item.email})
    </foreach>
</insert>

2 MyBatis Plus批量新增

// 使用MyBatis Plus
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> 
    implements UserService {
    // 批量保存(分批插入)
    @Transactional
    public boolean batchSave(List<User> userList) {
        return saveBatch(userList, 1000); // 每批1000条
    }
}

高级新增场景

1 联合插入(多表)

<!-- 插入用户和角色关联 -->
<insert id="insertUserAndRole">
    <!-- 插入用户 -->
    <selectKey keyProperty="userId" resultType="Long" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
</insert>
<insert id="insertUserRole">
    INSERT INTO user_role(user_id, role_id)
    VALUES(#{userId}, #{roleId})
</insert>

2 存在则更新,不存在则插入

<insert id="insertOrUpdate">
    INSERT INTO user(name, age, email)
    VALUES(#{name}, #{age}, #{email})
    ON DUPLICATE KEY UPDATE
    age = VALUES(age),
    email = VALUES(email)
</insert>

完整示例代码

1 实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

2 Service层

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public User createUser(User user) {
        // 补全信息
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        // 执行新增
        int result = userMapper.insert(user);
        if (result > 0) {
            return user; // 包含生成的主键
        }
        throw new RuntimeException("新增用户失败");
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateUsers(List<User> userList) {
        // 批量处理
        userList.forEach(user -> {
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
        });
        // 分批插入,每批500条
        int batchSize = 500;
        for (int i = 0; i < userList.size(); i += batchSize) {
            int end = Math.min(i + batchSize, userList.size());
            List<User> batch = userList.subList(i, end);
            userMapper.batchInsert(batch);
        }
    }
}

3 Controller层

@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping
    public Result<User> createUser(@Valid @RequestBody UserCreateDTO dto) {
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        User created = userService.createUser(user);
        return Result.success(created);
    }
    @PostMapping("/batch")
    public Result<Void> batchCreateUsers(@RequestBody List<UserCreateDTO> dtos) {
        List<User> users = dtos.stream()
            .map(dto -> {
                User user = new User();
                BeanUtils.copyProperties(dto, user);
                return user;
            })
            .collect(Collectors.toList());
        userService.batchCreateUsers(users);
        return Result.success();
    }
}

最佳实践

1 参数校验

@PostMapping
public Result<User> createUser(@Valid @RequestBody UserCreateDTO dto) {
    // 业务校验
    if (userService.existsByEmail(dto.getEmail())) {
        return Result.error("邮箱已存在");
    }
    // ... 执行新增
}

2 事务管理

@Transactional(rollbackFor = Exception.class)
public User createUserWithRoles(User user, List<Long> roleIds) {
    // 插入用户
    userMapper.insert(user);
    // 插入角色关联
    if (CollectionUtils.isNotEmpty(roleIds)) {
        userRoleMapper.batchInsert(user.getId(), roleIds);
    }
    return user;
}

3 性能优化

// 批量插入时关闭自动提交
@Transactional
public void batchInsertOptimized(List<User> list) {
    SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
    try {
        UserMapper mapper = session.getMapper(UserMapper.class);
        for (User user : list) {
            mapper.insert(user);
        }
        session.commit();
    } finally {
        session.close();
    }
}

常见问题处理

1 特殊字符转义

<!-- 使用CDATA转义 -->
<insert id="insertWithSpecialChar">
    <![CDATA[
    INSERT INTO user(name, description)
    VALUES(#{name}, #{description})
    ]]>
</insert>

2 时间字段处理

// 使用数据库默认值
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
// 或手动设置
user.setCreateTime(LocalDateTime.now());

通过以上方式,你可以根据具体场景选择合适的MyBatis新增实现方案,建议在实际开发中结合业务需求、数据量大小和性能要求来选择合适的方式。

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