MyBatis增删改查操作详解
2025/9/17大约 6 分钟
MyBatis增删改查操作详解
前置知识
在开始本教程之前,建议您已经完成:
- MyBatis基础入门教程
- MyBatis核心配置详解
- 了解SQL基础语法
基础CRUD操作
创建Mapper接口
package com.example.mybatis.mapper;
import com.example.mybatis.bean.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserMapper {
// 添加用户
int insertUser();
// 删除用户
int deleteUser();
// 修改用户
int updateUser();
// 查询单个用户
User getUserById();
// 查询所有用户
List<User> getUserList();
}
创建映射文件
<?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.mybatis.mapper.UserMapper">
<!-- 添加用户 -->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
</insert>
<!-- 删除用户 -->
<delete id="deleteUser">
delete from t_user where id = 6
</delete>
<!-- 修改用户 -->
<update id="updateUser">
update t_user set username = '张三' where id = 5
</update>
<!-- 查询单个用户 -->
<select id="getUserById" resultType="com.example.mybatis.bean.User">
select * from t_user where id = 2
</select>
<!-- 查询所有用户 -->
<select id="getUserList" resultType="com.example.mybatis.bean.User">
select * from t_user
</select>
</mapper>
重要说明
- 查询的标签select必须设置属性resultType或resultMap
- resultType:自动映射,用于属性名和表中字段名一致的情况
- resultMap:自定义映射,用于一对多或多对一或字段名和属性名不一致的情况
- 当查询的数据为多条时,不能使用实体类作为返回值,只能使用集合
参数传递方式
MyBatis获取参数值的两种方式:${}
和 #{}
${}
:本质就是字符串拼接#{}
:本质就是占位符赋值
单个字面量类型的参数
// Mapper接口
User getUserByUsername(String username);
<!-- 使用#{} -->
<select id="getUserByUsername" resultType="User">
select * from t_user where username = #{username}
</select>
<!-- 使用${} -->
<select id="getUserByUsername" resultType="User">
select * from t_user where username = '${username}'
</select>
多个字面量类型的参数
// Mapper接口
User checkLogin(String username, String password);
<!-- 使用arg0,arg1... -->
<select id="checkLogin" resultType="User">
select * from t_user where username = #{arg0} and password = #{arg1}
</select>
<!-- 使用param1,param2... -->
<select id="checkLogin" resultType="User">
select * from t_user where username = '${param1}' and password = '${param2}'
</select>
Map集合类型的参数
// Mapper接口
User checkLoginByMap(Map<String, Object> map);
<select id="checkLoginByMap" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
// 测试代码
@Test
public void checkLoginByMap() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("password", "123456");
User user = mapper.checkLoginByMap(map);
System.out.println(user);
}
实体类类型的参数
// Mapper接口
int insertUser(User user);
<insert id="insertUser">
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
// 测试代码
@Test
public void insertUser() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(null, "Tom", "123456", 12, "男", "123@321.com");
mapper.insertUser(user);
}
使用@Param注解
// Mapper接口
User checkLoginByParam(@Param("username") String username, @Param("password") String password);
<select id="checkLoginByParam" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
// 测试代码
@Test
public void checkLoginByParam() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.checkLoginByParam("admin", "123456");
}
查询功能详解
查询单个实体类对象
// Mapper接口
User getUserById(@Param("id") int id);
<select id="getUserById" resultType="User">
select * from t_user where id = #{id}
</select>
查询List集合
// Mapper接口
List<User> getUserList();
<select id="getUserList" resultType="User">
select * from t_user
</select>
查询单个数据
// Mapper接口
int getCount();
<select id="getCount" resultType="_integer">
select count(id) from t_user
</select>
查询Map集合
// Mapper接口 - 查询单个Map
Map<String, Object> getUserToMap(@Param("id") int id);
// Mapper接口 - 查询多个Map
List<Map<String, Object>> getAllUserToMap();
// Mapper接口 - 使用@MapKey注解
@MapKey("id")
Map<String, Object> getAllUserToMap();
<!-- 查询单个Map -->
<select id="getUserToMap" resultType="map">
select * from t_user where id = #{id}
</select>
<!-- 查询多个Map -->
<select id="getAllUserToMap" resultType="map">
select * from t_user
</select>
查询结果说明
- 单个Map结果:
{password=123456, sex=男, id=1, age=23, username=admin}
- 多个Map结果:
[{password=123456, sex=男, id=1, age=23, username=admin}, {password=123456, sex=男, id=2, age=23, username=张三}]
- @MapKey结果:
{1={password=123456, sex=男, id=1, age=23, username=admin}, 2={password=123456, sex=男, id=2, age=23, username=张三}}
特殊SQL执行
模糊查询
// Mapper接口
List<User> getUserByLike(@Param("username") String username);
<select id="getUserByLike" resultType="User">
<!-- 方式一:使用${} -->
<!-- select * from t_user where username like '%${username}%' -->
<!-- 方式二:使用concat函数 -->
<!-- select * from t_user where username like concat('%',#{username},'%') -->
<!-- 方式三:使用字符串拼接(推荐) -->
select * from t_user where username like "%"#{username}"%"
</select>
批量删除
// Mapper接口
int deleteMore(@Param("ids") String ids);
<delete id="deleteMore">
delete from t_user where id in (${ids})
</delete>
// 测试代码
@Test
public void deleteMore() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int result = mapper.deleteMore("1,2,3,8");
System.out.println(result);
}
批量删除注意事项
只能使用${}
,如果使用#{}
,则解析后的sql语句为delete from t_user where id in ('1,2,3')
,这样是将1,2,3
看做是一个整体。
动态设置表名
// Mapper接口
List<User> getUserByTable(@Param("tableName") String tableName);
<select id="getUserByTable" resultType="User">
select * from ${tableName}
</select>
动态表名注意事项
只能使用${}
,因为表名不能加单引号。
添加功能获取自增的主键
// Mapper接口
void insertUser(User user);
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
</insert>
// 测试代码
@Test
public void insertUser() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(null, "ton", "123", 23, "男", "123@321.com");
mapper.insertUser(user);
System.out.println(user);
// 输出:user{id=10, username='ton', password='123', age=23, sex='男', email='123@321.com'}
// 自增主键存放到了user的id属性中
}
自增主键配置说明
useGeneratedKeys
:设置使用自增的主键keyProperty
:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参数user对象的某个属性中
参数传递总结
参数传递最佳实践
建议分成两种情况进行处理:
- 实体类类型的参数:直接使用属性名
- 使用@Param标识参数:明确指定参数名,提高代码可读性
参数类型 | 获取方式 | 示例 |
---|---|---|
单个字面量 | #{任意名称} 或 ${任意名称} | #{username} |
多个字面量 | #{arg0} 或 #{param1} | #{arg0}, #{arg1} |
Map集合 | #{map的key} | #{username}, #{password} |
实体类 | #{属性名} | #{username}, #{age} |
@Param注解 | #{@Param的value值} | #{username}, #{password} |
测试工具类
package com.example.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true);
}
}
总结
本教程详细介绍了MyBatis的增删改查操作,包括:
- ✅ 基础CRUD操作:增删改查的基本实现
- ✅ 参数传递方式:五种不同的参数传递方式
- ✅ 查询功能:各种查询结果的返回类型
- ✅ 特殊SQL执行:模糊查询、批量删除、动态表名等
- ✅ 自增主键获取:配置和使用方法
- ✅ 最佳实践:参数传递的推荐方式
下一步学习
- 学习MyBatis的映射关系处理
- 了解resultMap的使用
- 掌握多对一、一对多映射
在下一篇文章中,我们将学习MyBatis的映射关系处理,包括resultMap的使用、多对一映射、一对多映射和延迟加载等高级特性。