本文将通过一个学生管理系统的案例,详细讲解如何使用MyBatis实现动态SQL查询、批量操作等核心功能。以下是完整的代码实现和关键解析。
src/
├── main/
│ ├── java/
│ │ ├── com.qcby.dao/
│ │ │ └── StudentDao.java # DAO接口
│ │ ├── com.qcby.entity/
│ │ │ └── Student.java # 实体类
│ │ └── resources/
│ │ ├── SqlMapConfig.xml # MyBatis主配置
│ │ └── StudentMapper.xml # SQL映射文件
├── test/
│ └── java/
│ └── StudentTest.java # 单元测试类
场景:根据姓名、年龄动态过滤学生
测试用例:
@Test
public void FindAllStudent() {
Student condition = new Student();
condition.setName("huahua"); // 设置查询条件
List students = mapper.FindAllStudent(condition);
students.forEach(System.out::println);
}
输出示例:
Student{id=1, name='huahua', sex='F', age=18, password=123, phone=''}
场景:一次性插入多条学生记录
INSERT INTO student (name, age, password)
VALUES
(#{student.name}, #{student.age}, #{student.password})
测试用例:
@Test
public void insermoreList() {
List students = Arrays.asList(
new Student("张三", 20, 123),
new Student("李四", 22, 456)
);
mapper.insermoreList(students);
session.commit(); // 提交事务
}
生成SQL:
INSERT INTO student (name, age, password)
VALUES ('张三', 20, 123), ('李四', 22, 456)
场景:根据ID列表批量删除学生
DELETE FROM student
WHERE id IN
#{id}
测试用例:
@Test
public void deletemoreList() {
Integer[] ids = {29, 30};
mapper.deletemoreList(ids);
session.commit();
}
生成SQL:
DELETE FROM student WHERE id IN (29, 30)
SELECT LAST_INSERT_ID()
INSERT INTO Student(name, sex, age, phone, password)
VALUES (#{name}, #{sex}, #{age}, #{phone}, #{password})
测试用例:
@Test
public void insertgetid() {
Student student = new Student();
student.setName("王五");
student.setSex("M");
student.setAge(25);
mapper.insertgetid(student);
session.commit();
System.out.println("插入ID:" + student.getId()); // 输出自增ID
}
问题现象:设置的条件未过滤数据
检查点:
确保实体类字段与
的test
属性匹配
检查数据库字段是否与实体类属性名一致(如驼峰转换)
典型错误:
SQLSyntaxErrorException: You have an error in your SQL syntax
解决方案:
检查SQL是否缺少VALUES
关键字
验证数据库字段是否允许为空(如sex
字段)
错误示例:
int insermoreList(@Param(students) List students);
修复方法:
int insermoreList(@Param("students") List students);
启用MyBatis日志
在SqlMapConfig.xml
中添加:
防御性编程
对动态SQL参数做空值检查
批量操作时限制数据量(避免单次提交过多数据)