一、什么是Mybatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建 statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。
作为一个半ORM框架,MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中
sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java
对象并返回。(从执行sql到返回result的过程)。
由于MyBatis专注于SQL本身,灵活度高,所以比较适合对性能的要求很高,或者需求变化较多的
项目,如互联网项目。
1.1什么是ORM
ORM(Object-relational mapping),即对象关系映射,是一种为了解决面向对象与关系数据库存
在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,
将程序中的对象自动持久化到关系数据库中。
1、O->R add/insert/save
studentDao.insert(student)
把一个java对象保存到数据库中的一行记录
2、R->O selectById/findById/listById
Student student = sudentDao.findById(id)
把数据库里面的一行记录封装成一个java对象
1.2 Mybaits的优缺点
优点
基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在
XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并
可重用。
与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库
MyBatis都支持)。
能够与Spring很好的集成; 提供映射标签,支持对象与数据库的ORM字段关系映射;
提供对象关系映射标签,支持对象关系组件维护。
缺点
SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定
要求。
SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
二、Mybatis声明接口
MyBatis 通过接口与 SQL 语句进行映射,无需实现类即可直接调用。接口通常与 Mapper 绑定,定义数据操作方法。
2.1CourseMapper接口
@Mapper // 标识该接口为MyBatis映射器,MyBatis会动态生成其实现类
public interface CourseMapper {
// 根据课程ID查询课程信息
Course getByID(@Param("id") Integer id);
// 根据条件动态查询课程列表
List<Course> list(@Param("course") Course course);
// 新增课程信息
int add(@Param("course") Course course);
// 修改课程信息
int edit(@Param("course") Course course);
// 删除课程信息
int delete(@Param("course") Course course);
}
2.2TeacherMapper 接口
@Mapper // MyBatis映射器接口
public interface TeacherMapper {
// 新增单个教师信息
int add(@Param("teacher") Teacher teacher);
// 批量新增教师信息
int addTeachers(@Param("teachers") List<Teacher> teachers);
// 根据ID删除教师信息
int delete(@Param("id") Integer id);
// 修改教师信息
int edit(@Param("teacher") Teacher teacher);
// 查询所有教师列表
List<Teacher> list();
// 根据ID查询教师信息
Teacher getByID(@Param("id") Integer id);
// 动态条件查询教师列表
List<Teacher> listSearch(@Param("teacher") Teacher teacher);
}
三、绑定sql方式
以及两种方式的增删改查
3.1. 注解方式实现
直接在接口方法上使用注解编写 SQL(StudentMapper):
@Repository // 标识为Spring数据访问层组件
@Mapper // MyBatis映射器接口
public interface StudentMapper {
// 根据学生ID查询学生信息(使用注解SQL)
@Select("SELECT * FROM student WHERE student_id = #{stuid}")
Student getStudentByid(@Param("stuid") Integer id);
// 新增学生信息(使用注解SQL)
@Insert("INSERT INTO student(student_name, birthday, gender, age) " +
"VALUES (#{student.student_name}, #{student.birthday}, #{student.gender}, #{student.age})")
int addStudent(@Param("student") Student student);
// 根据学生ID删除学生信息(使用注解SQL)
@Delete("DELETE FROM student WHERE student_id = #{stuid}")
int deleteStudent(@Param("stuid") Integer id);
// 修改学生信息(使用注解SQL)
@Update("UPDATE student SET student_name = #{student.student_name}, " +
"gender = #{student.gender}, age = #{student.age} WHERE student_id = #{student.student_id}")
int editStudent(@Param("student") Student student);
// 动态条件查询学生列表(XML配置SQL)
List<Student> list1(@Param("student") Student student);
}
3.2 XML 文件方式实现
创建对应的 Mapper XML 文件(teacherMapper.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">
<!– 查询 –>
<select id="getUserById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT id, name, age, email FROM user WHERE id = #{id}
</select>
<!– 新增 –>
<insert id="insertUser" parameterType="com.example.entity.User"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO user(name, age, email) VALUES(#{name}, #{age}, #{email})
</insert>
useGeneratedKeys="true":告诉 MyBatis,当前插入操作的主键是由数据库自动生成的
keyProperty="id":指定将数据库生成的主键值,赋值给传入参数对象的id属性。
<!– 更新 –>
<update id="updateUser" parameterType="com.example.entity.User">
UPDATE user SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}
</update>
<!– 删除 –>
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>
四、动态sql语句的标签
动态 SQL 用于根据条件动态生成 SQL 片段,常用标签:
动态 SQL 是 MyBatis 提供的一种强大功能,允许根据运行时条件动态生成 SQL 语句片段。以下是常用标签的详细说明和使用示例:
<if> 标签
用于条件判断,根据条件动态包含 SQL 片段。示例:
<select id="findUsers" resultType="User">
SELECT * FROM users
WHERE 1=1
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</select>
<where> 标签
自动处理 WHERE 子句中的 AND/OR 关键字,避免语法错误。示例:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<set> 标签
用于 UPDATE 语句,自动处理 SET 子句中的逗号分隔。示例:
<update id="updateUser">
UPDATE users
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age},
</if>
</set>
WHERE id = #{id}
</update>
<foreach> 标签
遍历集合,常用于 IN 条件或批量插入。示例:
<select id="findUsersByIds" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="ids" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<choose> <when> <otherwise> 标签
实现多条件分支选择,类似 Java 的 switch-case 结构。示例:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="name != null">
AND name = #{name}
</when>
<when test="email != null">
AND email = #{email}
</when>
<otherwise>
AND status = 'ACTIVE'
</otherwise>
</choose>
</where>
</select>
<trim> 标签
提供更灵活的 SQL 片段拼接控制,可自定义前缀、后缀和分隔符处理。示例:
<select id="findUsers" resultType="User">
SELECT * FROM users
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
OR age = #{age}
</if>
</trim>
</select>
<bind> 标签
定义变量并赋值,通常用于简化复杂表达式或兼容不同数据库语法。示例:
<select id="findUsers" resultType="User">
<bind name="pattern" value="'%' + name + '%'" />
SELECT * FROM users
WHERE name LIKE #{pattern}
</select>
四、# $的取值和取参数的区别,分别用在什么地方?
4.1#{}
- 原理:预编译处理,将参数替换为 ?,通过 PreparedStatement 执行,防止 SQL 注入。
- 取值方式:会自动根据参数类型添加引号(如字符串加单引号)。
- 适用场景:大多数参数传递,如查询条件、新增 / 修改的字段值等。
<!– #{}示例 – 安全的参数传递 –>
<select id="getUserByName" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT id, name, age, email FROM user WHERE name = #{name}
<!– 会被预编译为: SELECT * FROM user WHERE name = ? –>
</select>
4.2${}
- 原理:字符串拼接,直接将参数嵌入 SQL 语句,不做预编译,有 SQL 注入风险。
- 取值方式:不会添加引号,适用于动态拼接表名、列名等。
- 适用场景:动态 SQL 片段(如表名、排序字段),需确保参数安全(避免用户输入)。
- 示例:
<!– ${}示例 – 动态表名 –>
<select id="findUsersByTableName" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT id, name, age, email FROM ${tableName}
<!– 会直接拼接字符串,如参数为"user_2025",则SQL为: SELECT * FROM user_2025 –>
</select>
<!– 动态排序字段 –>
<select id="findUsersWithOrder" parameterType="java.util.Map" resultMap="BaseResultMap">
SELECT id, name, age, email FROM user
ORDER BY ${orderByColumn} ${orderType}
</select>
评论前必须登录!
注册