MyBatis简介
mybatis就是一层封装
作用:简化数据库操作的
运行效率 JDBC>MyBatis>Hibernate
这些都是对于JDBC的封装,封装的越多,效率越低
功能强大性能优异
什么是MyBatis?
MyBatis是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis消除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录.
MyBatis的特点
- 简化数据库访问:MyBatis通过XML或注解配置,简化了数据库访问操作,减少了代码量。
- 灵活的SQL:支持自定义SQL语句,开发者可以完全控制SQL的执行。
- 高级映射:支持复杂的映射关系,包括一对一、一对多、多对多等。
- 动态SQL:支持动态SQL语句,可以根据条件生成不同的SQL。
- 缓存机制:内置一级缓存和二级缓存,提高了查询性能。
MyBatis的基本使用
- 引入依赖
在项目的pom.xml文件中添加MyBatis相关的依赖:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.17</version>
</dependency>- 配置SqlSessionFactory
使用XML配置文件来配置SqlSessionFactory:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>- 定义Mapper接口
创建一个Mapper接口,并在接口方法上使用注解或XML配置SQL语句:
public interface BlogMapper {
@Select("SELECT * FROM blog WHERE id = #{id}")
Blog selectBlog(int id);
}- 使用MyBatis
在代码中使用SqlSessionFactory获取SqlSession,并调用Mapper接口的方法:
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}MyBatis的应用场景
- 企业级应用开发:MyBatis适用于各种规模的企业级应用开发,特别是需要灵活控制SQL的场景。
- 复杂查询:MyBatis支持复杂的查询和映射关系,适用于需要复杂查询的应用。
- 高性能需求:MyBatis内置缓存机制,适用于对性能有较高要求的应用。
- 轻量级
示例
新建一个父工程
- 导入依赖
- 需要导入mybatis
- mysql驱动
- junit5测试
新建moudle
--
注意:mapper接口不能重载,因为它是根据方法名识别的
ibatis方式
我们可以声明接口来保证我们写的正确
MyBatis中的#{}和${}的区别
在MyBatis中,#{} 和${}是用于在SQL语句中插入参数的两种方式,它们有不同的用途和行为。
1. #{} (占位符 + 赋值 id=? ?=赋值) 推荐使用
- 用途:用于安全地插入参数,防止SQL注入。
- 行为:MyBatis会将
#{}中的参数替换为一个占位符(如?),并使用PreparedStatement来设置参数值。 - 只能替代值的位置,不能替代容器名(标签,列名,sql 关键字)
- 示例:
<select id="selectUser" parameterType="int" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
在这个示例中,#{id}会被替换为一个占位符?,并在执行SQL时将参数值设置为id的值。
2. ${}(字符串拼接)
- 用途:用于直接插入参数值,不进行预编译,适用于动态生成SQL语句的场景。
- 行为:MyBatis会将
${}中的参数直接替换为参数值,不进行任何转义或预编译。 - 示例:
<select id="selectUser" parameterType="String" resultType="User">
SELECT * FROM users WHERE name = '${name}'
</select>
在这个示例中,${name}会被直接替换为参数name的值。如果name的值是John,则生成的SQL语句为SELECT * FROM users WHERE name = 'John'。
区别总结
- 安全性:
#{}使用PreparedStatement,防止SQL注入;${}直接插入参数值,存在SQL注入风险。 - 性能:
#{}使用预编译SQL,性能较好;${}每次执行都会重新解析SQL,性能较差。 - 用途:
#{}适用于传递参数值;${}适用于动态生成SQL语句。
简单类型传入
key 值随便写,一般情况推荐使用参数名
单个实例对象传入
key=属性名即可
写传入对象的属性
传入多个简单类型数据如何取值
推荐使用注解
传入 map
key=map 的 key 即可
可以去官网查看文档 mybatis.org
事务管理器
使用 JDBC 就会自动开启管理事务,有事务相关的管理
使用 MANAGED 这个配置基本啥也不干
一般我们不使用 mybatis 的连接池,我们使用第三方的
性能好
开启日志输出
单个简单类型和定义别名
可以写全名或者简写
mybatis 给我们提供了 72 种类别名,如果没有我们可以自己定义或写类的全限定符号
写别名
单个简单类型
单个简单类型指的是Java中的基本数据类型及其包装类,如int、Integer、String、boolean、Boolean等。这些类型在MyBatis中可以直接作为参数和返回值使用。
示例:
<select id="selectUserName" parameterType="int" resultType="String">
SELECT name FROM users WHERE id = #{id}
</select>
parameterType指定了参数类型为int,resultType指定了返回值类型为String。
定义别名
MyBatis允许为Java类定义别名,以简化配置文件中的类型声明。别名可以通过<typeAlias>标签在MyBatis配置文件中定义,也可以通过注解方式定义。
XML配置方式:
<typeAliases>
<typeAlias alias="User" type="com.example.model.User"/>
</typeAliases>
User是com.example.model.User类的别名。在Mapper文件中,可以使用别名代替全限定类名。
注解方式:
@Alias("User")
public class User {
private int id;
private String name;
// getters and setters
}@Alias("User")注解为User类定义了别名。在Mapper文件中,可以使用别名代替全限定类名。
使用别名的示例:
<select id="selectUser" parameterType="int" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
resultType使用了别名User,MyBatis会将查询结果映射到User类的实例中。
单个实体类型输出
开启驼峰式自动映射
返回 map
列名 -> key
map
结果 -> 值
返回集合类型
切记:返回值是集合 resultType 不需要指定集合类型,只需要指定泛型即可
底层是使用集合去查的,所以我们只需要指定泛型
返回主键值
自增长主键
主键回显 获取插入数据的主键
1.自增长逐渐回显 mysql out_increment
int inserEmp(Employee employee);
非自增长主键维护
自己维护主键
非自增长的主键交给mybatis维护
MyBatis自定义映射关系和ResultMap
什么是自定义映射关系?
在MyBatis中,自定义映射关系是指将数据库查询结果映射到Java对象的过程。MyBatis允许开发者通过XML配置或注解的方式,自定义查询结果与Java对象属性之间的映射关系。这种映射关系可以处理复杂的查询结果,如一对一、一对多、多对多等。
什么是ResultMap?
ResultMap是MyBatis中用于定义自定义映射关系的核心组件。通过ResultMap,可以将查询结果中的列与Java对象的属性进行映射,从而实现复杂的映射关系。
ResultMap的基本使用
- 定义ResultMap
在MyBatis的XML配置文件中定义ResultMap:
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<result property="email" column="user_email"/>
</resultMap>在这个示例中,userResultMap定义了一个ResultMap,将查询结果中的user_id、user_name和user_email列分别映射到User对象的id、name和email属性。
- 使用ResultMap
在Mapper文件中使用ResultMap:
<select id="selectUser" resultMap="userResultMap">
SELECT user_id, user_name, user_email FROM users WHERE user_id = #{id}
</select>在这个示例中,selectUser查询使用了userResultMap,将查询结果映射到User对象。
复杂映射关系
- 一对一映射
一对一映射是指一个对象包含另一个对象的情况。例如,用户对象包含地址对象:
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<association property="address" javaType="com.example.model.Address">
<id property="id" column="address_id"/>
<result property="street" column="address_street"/>
<result property="city" column="address_city"/>
</association>
</resultMap>- 一对多映射
一对多映射是指一个对象包含多个子对象的情况。例如,用户对象包含多个订单对象:
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<collection property="orders" ofType="com.example.model.Order">
<id property="id" column="order_id"/>
<result property="amount" column="order_amount"/>
<result property="date" column="order_date"/>
</collection>
</resultMap>- 多对多映射
多对多映射是指一个对象包含多个子对象,每个子对象又包含多个父对象的情况。例如,学生对象包含多个课程对象,课程对象也包含多个学生对象:
<resultMap id="studentResultMap" type="com.example.model.Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<collection property="courses" ofType="com.example.model.Course">
<id property="id" column="course_id"/>
<result property="name" column="course_name"/>
</collection>
</resultMap>通过ResultMap,MyBatis可以灵活地处理各种复杂的映射关系,满足不同的业务需求。
列名和属性不一致的解决方案
在MyBatis中,当数据库列名和Java属性名不一致时,可以通过以下几种方案来解决映射问题:
方案1:使用别名
通过在SQL查询中使用别名,将数据库列名映射到Java属性名。
<select id="selectTeacher" parameterType="int" resultType="Teacher">
SELECT t.id AS tId, t.name AS tName FROM teacher WHERE t.id = #{tId}
</select>在这个示例中,t.id被映射为tId,t.name被映射为tName。
方案2:开启驼峰式映射
通过在MyBatis配置文件中开启驼峰式映射,将下划线命名的数据库列名自动映射为驼峰命名的Java属性名。
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>在这个示例中,数据库列名tid会自动映射为Java属性名tId。
方案3:使用ResultMap自定义映射
通过ResultMap自定义映射关系,可以精确控制数据库列名和Java属性名的映射。resultType和resultMap二选一使用。
<!-- 声明ResultMap标签,自定义映射规则 -->
<resultMap id="teacherResultMap" type="Teacher">
<id property="tId" column="id"/>
<result property="tName" column="name"/>
</resultMap>
<!-- 使用ResultMap -->
<select id="queryById" resultMap="teacherResultMap">
SELECT * FROM teacher WHERE id = #{tId}
</select>在这个示例中,teacherResultMap定义了自定义映射规则,将数据库列id映射为Java属性tId,将数据库列name映射为Java属性tName。
深层次对象结构映射
对于深层次的对象结构和多表查询,可以通过ResultMap进行复杂映射。
<resultMap id="orderResultMap" type="Order">
<id property="orderId" column="order_id"/>
<result property="orderName" column="order_name"/>
<association property="orderItem" javaType="OrderItem">
<id property="itemId" column="item_id"/>
<result property="orderId" column="order_id"/>
<result property="itemName" column="item_name"/>
</association>
</resultMap>
<select id="selectOrder" resultMap="orderResultMap">
SELECT o.order_id, o.order_name, i.item_id, i.order_id, i.item_name
FROM orders o
JOIN order_items i ON o.order_id = i.order_id
WHERE o.order_id = #{orderId}
</select>在这个示例中,orderResultMap定义了复杂的映射关系,将Order对象和OrderItem对象的属性与数据库列进行映射。
ResultMap标签,自定义映射关系,可以多层次,也可以单层次
通过注解生成对应的方法
MyBatis多表映射
在MyBatis中,多表映射是指将多个数据库表的数据映射到Java对象中。多表映射通常用于处理复杂的查询结果,如一对一、一对多、多对多等关系。以下是一些常见的多表映射方式:
一对一映射
一对一映射是指一个对象包含另一个对象的情况。例如,用户对象包含地址对象。
示例:
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<association property="address" javaType="com.example.model.Address">
<id property="id" column="address_id"/>
<result property="street" column="address_street"/>
<result property="city" column="address_city"/>
</association>
</resultMap>
<select id="selectUser" resultMap="userResultMap">
SELECT u.user_id, u.user_name, a.address_id, a.address_street, a.address_city
FROM users u
JOIN addresses a ON u.address_id = a.address_id
WHERE u.user_id = #{userId}
</select>在这个示例中,userResultMap定义了用户和地址之间的一对一映射关系。
一对多映射
一对多映射是指一个对象包含多个子对象的情况。例如,用户对象包含多个订单对象。
示例:
<resultMap id="userResultMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<collection property="orders" ofType="com.example.model.Order">
<id property="id" column="order_id"/>
<result property="amount" column="order_amount"/>
<result property="date" column="order_date"/>
</collection>
</resultMap>
<select id="selectUser" resultMap="userResultMap">
SELECT u.user_id, u.user_name, o.order_id, o.order_amount, o.order_date
FROM users u
JOIN orders o ON u.user_id = o.user_id
WHERE u.user_id = #{userId}
</select>在这个示例中,userResultMap定义了用户和订单之间的一对多映射关系。
多对多映射
多对多映射是指一个对象包含多个子对象,每个子对象又包含多个父对象的情况。例如,学生对象包含多个课程对象,课程对象也包含多个学生对象。
总结
对一 属性中包含对象方法
对多 属性中包含对象集合
示例:
<resultMap id="studentResultMap" type="com.example.model.Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<collection property="courses" ofType="com.example.model.Course">
<id property="id" column="course_id"/>
<result property="name" column="course_name"/>
</collection>
</resultMap>
<select id="selectStudent" resultMap="studentResultMap">
SELECT s.student_id, s.student_name, c.course_id, c.course_name
FROM students s
JOIN student_courses sc ON s.student_id = sc.student_id
JOIN courses c ON sc.course_id = c.course_id
WHERE s.student_id = #{studentId}
</select>在这个示例中,studentResultMap定义了学生和课程之间的多对多映射关系。
通过ResultMap,MyBatis可以灵活地处理各种复杂的映射关系,满足不同的业务需求.
若有多张表可以拆成双表
MyBatis动态语句
MyBatis动态语句允许开发者根据不同的条件动态生成SQL语句,从而提高查询的灵活性和可维护性。MyBatis提供了一系列的动态SQL标签,如<if>、<choose>、<when>、<otherwise>、<trim>、<where>、<set>和<foreach>,这些标签可以在Mapper XML文件中使用。
常用动态SQL标签
<if>标签- 用于根据条件动态生成SQL片段。
- 示例:
<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM users
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</select><choose>、<when>和<otherwise>标签- 类似于Java中的
switch语句,用于根据不同的条件生成不同的SQL片段。 - 示例:
- 类似于Java中的
<select id="findUser" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="name != null">
name = #{name}
</when>
<otherwise>
1 = 1
</otherwise>
</choose>
</where>
</select><trim>标签- 用于去除SQL片段的前后多余字符,如逗号、AND、OR等。
- 示例:
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<trim suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="email != null">email = #{email},</if>
</trim>
</set>
WHERE id = #{id}
</update><where>标签- 用于自动处理WHERE子句的AND/OR逻辑,避免SQL语句中出现多余的AND/OR。
- 示例:
<select id="findUserByConditions" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<if test="id != null">id = #{id}</if>
<if test="name != null">AND name = #{name}</if>
</where>
</select><set>标签- 用于动态生成UPDATE语句中的SET子句,自动去除多余的逗号。
- 示例:
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<if test="name != null">name = #{name},</if>
<if test="email != null">email = #{email},</if>
</set>
WHERE id = #{id}
</update><foreach>标签- 用于遍历集合生成SQL片段,常用于IN查询和批量操作。
- 示例:
<select id="findUsersByIds" parameterType="list" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>MyBatis动态SQL语句的使用
在MyBatis中,可以通过动态SQL语句来根据不同的条件生成不同的SQL查询。以下是如何使用动态SQL语句来实现条件查询的示例:
示例方法
List<Employee> query(@Param("name") String name, @Param("salary") Double salary);如果传入属性,就判断相等;如果不传入,则不加对应的条件。
动态SQL语句
使用<where>标签和<if>标签来实现动态SQL语句:
<select id="query" resultType="Employee">
SELECT * FROM employee
<where>
<if test="name != null">
emp_name = #{name}
</if>
<if test="salary != null and salary > 100">
AND emp_salary = #{salary}
</if>
</where>
</select>解释
<where>标签的作用:- 自动添加
WHERE关键字:如果<where>标签内部有任何一个<if>条件满足,则自动添加WHERE关键字;如果不满足,则去掉WHERE。 - 自动去掉多余的
AND和OR关键字:<where>标签会自动处理多余的AND和OR关键字,确保生成的SQL语句是正确的。
- 自动添加
<if>标签的作用:- 判断传入的参数,最终是否添加语句。
test属性内部做比较运算,如果结果为true,则将标签内的SQL语句进行拼接;如果为false,则不拼接标签内部语句。
注意事项
- 大于和小于符号:不推荐直接写符号,可以使用HTML实体符号,如
>(大于)和<(小于)。 - 避免错误的SQL语句:确保
<if>标签内部的条件判断正确,避免生成错误的SQL语句。例如,如果第一个条件不满足,而第二个条件满足,则会生成错误的SQL语句WHERE AND emp_salary = #{salary}。
通过使用动态SQL语句,可以根据不同的条件生成灵活的查询语句,提高查询的灵活性和可维护性。
MyBatis中的动态SQL标签
MyBatis提供了一系列动态SQL标签,用于根据不同的条件动态生成SQL语句。以下是一些常用的动态SQL标签及其用法:
1. <set>标签
- 用途:用于动态生成
UPDATE语句中的SET子句,自动去除多余的逗号。 - 示例:
<update id="updateUser" parameterType="User">
UPDATE users
<set>
<if test="name != null">name = #{name},</if>
<if test="email != null">email = #{email},</if>
</set>
WHERE id = #{id}
</update>在这个示例中,<set>标签会根据条件动态生成SET子句,并自动去除多余的逗号。
2. <trim>标签
- 用途:用于去除SQL片段的前后多余字符,如逗号、AND、OR等。
- 属性:
prefix:在生成的SQL片段前添加的字符串。suffix:在生成的SQL片段后添加的字符串。prefixOverrides:去除生成的SQL片段前的指定字符。suffixOverrides:去除生成的SQL片段后的指定字符。
- 示例:
<update id="updateUser" parameterType="User">
UPDATE users
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="email != null">email = #{email},</if>
</trim>
WHERE id = #{id}
</update>在这个示例中,<trim>标签会在生成的SQL片段前添加SET,并去除多余的逗号。
3. <choose>、<when>和<otherwise>标签
- 用途:类似于Java中的
switch语句,用于根据不同的条件生成不同的SQL片段。 - 示例:
<select id="findUser" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="name != null">
name = #{name}
</when>
<otherwise>
1 = 1
</otherwise>
</choose>
</where>
</select>在这个示例中,<choose>标签会根据不同的条件生成不同的SQL片段。
它和if的区别,这个只能一个满足,if可以多个
4. <foreach>标签
- 用途:用于遍历集合生成SQL片段,常用于IN查询和批量操作。
- 属性:
item:集合中每个元素的别名。collection:要遍历的集合。open:在生成的SQL片段前添加的字符串。separator:在生成的SQL片段之间添加的分隔符。close:在生成的SQL片段后添加的字符串。
- 示例:
<select id="findUsersByIds" parameterType="list" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>在这个示例中,<foreach>标签会遍历集合list,生成IN查询的SQL片段。
在数据库url后面加?allowMultiQueries=true允许多语句执行
update把整体的更新语句都遍历一遍,注意,要先允许多语句执行
MyBatis中的SQL片段
在MyBatis中,SQL片段(SQL Fragments)是一种用于重用SQL代码的机制。通过定义和引用SQL片段,可以避免重复编写相同的SQL代码,提高代码的可维护性和可读性。SQL片段通常使用<sql>和<include>标签来定义和引用。
定义SQL片段
使用<sql>标签定义一个SQL片段。<sql>标签通常放在Mapper XML文件的顶部。
<sql id="userColumns">
user_id, user_name, user_email
</sql>在这个示例中,定义了一个名为userColumns的SQL片段,包含了用户表的三个列名。
引用SQL片段
使用<include>标签引用一个SQL片段。<include>标签可以放在任何需要引用SQL片段的地方。
<select id="selectUser" resultType="User">
SELECT <include refid="userColumns"/>
FROM users
WHERE user_id = #{id}
</select>在这个示例中,使用<include>标签引用了userColumns SQL片段,从而避免了重复编写列名。
动态SQL片段
SQL片段也可以包含动态SQL标签,如<if>、<choose>等,从而实现更复杂的SQL重用。
<sql id="dynamicUserColumns">
user_id,
<if test="includeName">
user_name,
</if>
user_email
</sql>
<select id="selectUser" resultType="User">
SELECT <include refid="dynamicUserColumns"/>
FROM users
WHERE user_id = #{id}
</select>在这个示例中,dynamicUserColumns SQL片段包含了一个动态SQL标签<if>,根据条件决定是否包含user_name列。
MyBatis Mapper按包批量扫描
在MyBatis中,Mapper按包批量扫描是一种简化配置的方式,通过指定包路径,自动扫描并注册Mapper接口。这样可以避免手动一个一个地配置Mapper接口,提高开发效率。
配置步骤
建议使用第二种,上下创建相同结构的配置文件
注意,创建的时候要写斜杠,不然就是一个文件夹
编译产物
- 引入依赖
在项目的pom.xml文件中添加MyBatis和Spring Boot相关的依赖:
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
</dependencies>- 配置Mapper扫描
在Spring Boot配置类中使用@MapperScan注解,指定Mapper接口所在的包路径:
@SpringBootApplication
@MapperScan("com.example.mapper")
public class MyBatisApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisApplication.class, args);
}
}- 定义Mapper接口
在指定的包路径下定义Mapper接口,并使用MyBatis的注解或XML文件配置SQL语句:
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User selectUser(int id);
}- 使用Mapper接口
在Service类中注入Mapper接口,并调用其方法:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUserById(int id) {
return userMapper.selectUser(id);
}
}通过以上配置,Spring Boot会自动扫描com.example.mapper包下的所有Mapper接口,并将其注册为Spring Bean,从而简化了Mapper接口的配置过程。
MyBatis插件机制
MyBatis插件机制允许开发者通过编写插件来拦截和修改MyBatis的核心行为,如SQL执行、参数处理和结果映射等。插件机制使得MyBatis具有很高的可扩展性,能够满足各种复杂的业务需求。
插件的基本原理
MyBatis插件通过实现Interceptor接口,并使用@Intercepts和@Signature注解来定义拦截点。拦截点可以是MyBatis的四种核心对象的方法:
- Executor:执行器,负责SQL语句的执行。
- ParameterHandler:参数处理器,负责SQL参数的处理。
- ResultSetHandler:结果集处理器,负责结果集的处理。
- StatementHandler:语句处理器,负责SQL语句的预处理。
插件的实现步骤
- 实现
Interceptor接口
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class MyPlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 在这里编写拦截逻辑
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 设置插件属性
}
}- 注册插件
在MyBatis配置文件中注册插件:
<plugins>
<plugin interceptor="com.example.MyPlugin">
<property name="someProperty" value="value"/>
</plugin>
</plugins>PageHelper分页插件
PageHelper是一个MyBatis的分页插件,能够简化分页查询的实现。它通过拦截SQL语句,在执行查询前后自动添加分页逻辑,从而实现分页功能。
PageHelper的使用步骤
- 引入依赖
在项目的pom.xml文件中添加PageHelper的依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>- 配置PageHelper
在Spring Boot配置类中配置PageHelper:
@Configuration
public class MyBatisConfig {
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
return pageHelper;
}
}- 使用PageHelper进行分页查询
在Service层或Mapper接口中使用PageHelper进行分页查询:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public PageInfo<User> getUsers(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
return new PageInfo<>(users);
}
}通过以上配置和代码,PageHelper会自动拦截SQL语句,并在执行查询前后添加分页逻辑,从而实现分页功能。
注意:正常编写语句即可,切记不要写分号结尾
MyBatis的ORM介绍和逆向工程
什么是ORM?
ORM(Object-Relational Mapping,面向对象关系映射)是一种技术,用于在面向对象编程语言(如Java、C#)和关系数据库之间建立映射关系。ORM通过将数据库中的表映射为编程语言中的类,将表中的记录映射为类的实例,从而简化了数据库操作,使开发者可以使用面向对象的方式来操作数据库。
ORM的优点
- 提高开发效率:通过自动生成SQL语句,减少了手动编写SQL的工作量。
- 增强可维护性:通过面向对象的方式操作数据库,使代码更加清晰、易于维护。
- 减少错误:通过自动生成SQL语句,减少了手动编写SQL时可能出现的错误。
- 跨数据库支持:ORM框架通常支持多种数据库,使得应用程序可以更容易地切换数据库。
常见的ORM框架
- Hibernate:一个流行的Java ORM框架,提供了强大的映射功能和丰富的配置选项。
- MyBatis:一个半自动化的ORM框架,允许开发者手动编写SQL语句,同时提供了自动映射功能。
- Entity Framework:一个用于.NET的ORM框架,提供了强大的数据库操作功能。
MyBatis逆向工程
什么是逆向工程?
逆向工程(Reverse Engineering)是一种技术,通过分析现有的系统或代码,生成相应的设计文档或模型。在数据库开发中,逆向工程通常指的是从现有的数据库结构生成相应的代码,如实体类、Mapper接口等。
MyBatis逆向工程
MyBatis提供了逆向工程工具,可以根据数据库表结构自动生成相应的实体类、Mapper接口和XML配置文件,从而简化开发过程。
使用MyBatis逆向工程的步骤
- 引入依赖
在项目的pom.xml文件中添加MyBatis逆向工程相关的依赖:
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>- 配置逆向工程
创建一个逆向工程配置文件generatorConfig.xml,配置数据库连接信息和生成代码的路径:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="MySQLTables" targetRuntime="MyBatis3">
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mydatabase"
userId="root"
password="password"/>
<javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"/>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper" targetProject="src/main/java"/>
<table tableName="users"/>
</context>
</generatorConfiguration>- 运行逆向工程
使用MyBatis Generator插件运行逆向工程,生成相应的代码:
mvn mybatis-generator:generate通过以上步骤,MyBatis逆向工程工具会根据数据库表结构自动生成相应的实体类、Mapper接口和XML配置文件,从而简化开发过程.
我们可以直接在idea中安装逆向插件
自动生成的
半自动,单表自动生成mapper接口和xml文件配置





































































