后端学习 - MyBatis

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的 持久层框架


零 常见问题

1 #{} 和 ${} 的区别

  • #{} 基于占位符替换,会自动给参数添加引号
  • ${} 基于字符串的拼接,要手动加上单引号
  • 优先使用 #{} 的方式传递参数,因为它有预编译机制,可以防止 SQL 注入
    • SQL 注入发生在编译时,通过改变参数值从而改变整个 SQL 语句的意图
    • 使用 ${} 会在参数拼接完成后,再编译整个 SQL 语句
    • 使用 #{} 会先执行预编译(编译后 SQL 语句的意图已经确定),完成后再用参数替换占位符,之后不再执行编译
    • 由于 SQL 语句已经被预编译过,其 SQL 意图将无法通过非法的参数内容实现更改,其参数中的内容无法变为 SQL 命令的一部分
  • 参数不能添加引号时,只能用 ${} 而不能用 #{},例如 ORDER BY 子句

2 MyBatis 分页效率问题

  • MyBatis 可以通过分页插件实现分页查询,原理是拦截 SQL 查询,自动为其添加 LIMIT pageSize*pageNum, pageSize 的分页条件
    • 这么做的问题是,当偏移量非常大时,会读取很多行并丢弃,效率降低
  • 为了避免大偏移量的问题,可以使用 延迟关联 的方法手动实现分页
    • 利用索引覆盖,首先找到目标行的所有 id
    • 再根据 id 关联原表,取出目标行的数据

一 基于配置文件的 MyBatis 搭建

1 搭建过程(增删改)

  • 配置过程:核心配置文件通过配置 mappers 找到映射文件,映射文件通过全类名和方法名定位到具体的接口和方法
    在这里插入图片描述
  1. 创建 maven 工程,引入依赖
  2. src/main/resources 目录下创建核心配置文件 mybatis-config.xml:核心配置文件主要用于配置连接数据库的环境,以及 MyBatis 的全局配置信息(整合 Spring 之后,配置文件可以省略)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
        
<configuration>
    <!--设置连接数据库的环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/learn"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    
    <!--引入UserMapper.xml的映射文件-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
        <!--其他映射文件...-->
    </mappers>
</configuration>
  1. 创建实体类型,以及数据库中对应的表
  2. 创建 mapper 接口:mapper 接口相当于 dao,但是 mapper 仅仅是接口,不需要提供实现类,具体的 SQL 命令写在 映射文件 xxxMapper.xml 中(xxx和类名保持一致)
  3. 创建 MyBatis 映射文件,在对应的位置标注全类名和方法(两个一致:mapper接口的全类名和映射文件的 namespace 保持一致 ,mapper 接口中方法的方法名和映射文件中编写 SQL 的标签的 id 属性保持一致
<?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的全类名-->
<mapper namespace="hello.mapper.UserMapper">
    <!--对应的方法-->
    <insert id="insertUser">
        insert into user values (null, "伍佰", "500", 50, "男", "500@gmail.com")
    </insert>
</mapper>
  1. 测试
    @Test
    public void helloTest() throws IOException {
        //读取MyBatis的核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);

        //创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //通过代理模式创建UserMapper接口的代理实现类对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配映射文件中的SQL标签,并执行标签中的SQL语句
        int result = userMapper.insertUser();
    }

2 查询操作

映射文件 UserMapper.xml 中,为了设置实体类和数据库表的映射,查询功能的标签必须指定 resultType(自动映射,用于属性名和表中字段名一致的情况) 或 resultMap(自定义映射,用于一对多 / 多对一 / 字段名和属性名不一致 的情况) 属性

  • 查询单个对象(单个对象也可以使用 List)
	接口定义方法:
	User getUserById();
	
	映射文件:
    <select id="getUserById" resultType="hello.pojo.User">
        select * from user where id = 1
    </select>
  • 查询多个对象
	接口定义方法:
	List<User> getAllUser();
	
	映射文件:
    <select id="getAllUser" resultType="hello.pojo.User">
        select * from user
    </select>

3 特殊操作

  • 模糊查询
<select id="fuzzy" resultType="User">
	select * from user where username like "%"#{name}"%"
</select>
  • 批量删除:不能使用 #{ } 是因为它会自动添加单引号
<!--int deleteMore(@Param("ids") String ids);-->
<delete id="batchDelete">
	delete from user where id in (${ids})  <!--示例:delete from user where id in (1, 2, 3)-->
</delete>

二 MyBatis 获取参数值的方式

  • #{ } 对应占位符赋值;${ } 对应字符串拼接,外侧需要加单引号
  • 不关心接口中方法的形参命名

1 单个字面量类型的参数

  • 可以以任意的名称获取参数的值,不在乎接口中的方法形参的名字,但最好见名知意
接口方法:
public interface ParamMapper {
    // 根据用户名查询用户信息
    User getUserByName(String username);
}

映射文件:
<select id="getUserByName" resultType="param.pojo.User">
    select * from user where username = #{notmatters}
    select * from user where username = '${notmatters}'  <!--等价-->
</select>

2 多个字面量类型的参数

  • 接口中的方法参数为多个,MyBatis 会自动将这些参数放在一个 map 集合中(以arg0, arg1…为键,以参数为值 或 以 param1, param2…为键,以参数为值),通过键访问参数
接口方法:
public interface ParamMapper {
    // 验证登录
    User checkLogin(String username, String password);
}

映射文件:
<select id="checkLogin" resultType="param.pojo.User">
    select * from user where username = #{arg0} and password = #{arg1}
    select * from user where username = #{param1} and password = #{param2}  <!--等价-->
</select>

3 Map 类型的参数

  • 方法参数为一个 Map 时,使用自定义的 key 访问 value
接口方法:
public interface ParamMapper {
    // 验证登录 参数为Map
    User checkLoginByMap(Map<String, Object> mapParam);
}

映射文件:
<select id="checkLoginByMap" resultType="param.pojo.User">
    select * from user where username = #{usernameKey} and password = #{passwordKey}
</select>

测试:
...
Map param = new HashMap<String, Object>();
param.put("usernameKey", "伍佰");
param.put("passwordKey", "500");
userMapper.checkLoginByMap(param);

4 实体类类型的参数

  • 通过访问实体类对象中的属性名获取属性值
接口方法:
public interface ParamMapper {
    // 添加用户
    int insertUser(User paramUser);
}

映射文件:
<insert id="insertUser">
    insert into user values (#{id}, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>

5 使用 @Param 注解的参数

  • 可以替代情况1和2
  • 作用是指定 map 的键:通过 @Param 注解标识接口中的方法参数,会将这些参数放在 map 集合中,以 @Param 注解的 value 属性值为键,以参数为值,替换键 arg0, arg1…
接口方法:
public interface ParamMapper {
    // 验证登录 参数使用注解
    User checkLoginByAnnotation(@Param("u") String username, @Param("p") String password);
}

映射文件:
<select id="checkLoginByAnnotation" resultType="param.pojo.User">
    select * from user where username = #{u} and password = #{p}
</select>

三 自定义查询结果 resultMap

  • resultMap:设置自定义映射
    包含属性:
    id:表示自定义映射的唯一标识
    type:查询的数据要映射的实体类的类型

  • resultMap 的子标签:
    id:设置主键的映射关系
    result:设置普通字段的映射关系
    association:设置多对一的映射关系
    collection:设置一对多的映射关系
    每个标签包含属性:
    property:设置映射关系中实体类中的属性名
    column:设置映射关系中表中的字段名

1 处理表的字段和属性的映射关系

  • 若字段名和实体类中的属性名不一致,则可以通过 resultMap 设置自定义映射
  • 所有映射需要全部设置
  • 略有臃肿,可以使用别名的方式,只对不一致的表字段起别名
    select id, user_name userName, password, age, sex from user where user_name like "%"#{mohu}"%"
<resultMap id="userMap" type="param.pojo.User">
	<id property="id" column="id"></id>
	<result property="userName" column="user_name"></result>
	<result property="password" column="password"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
</resultMap>

<select id="testFuzzy" resultMap="userMap">
	select * from user where user_name like "%"#{fuzzy}"%"
</select>

2 处理多对一关系

示例:根据员工id,查询员工信息和部门信息

  • POJO(省略 Lombok 注解)
public class Employee {
    private Integer eid;
    private String ename;
    private Department department;
}

public class Department {
    private Integer did;
    private String dname;
}
  • 接口方法
public interface ResultMapMapper {

    Employee getEmpAndDept(@Param("eid") Integer eid);
    
}
  • 映射文件:使用 association 子标签后,左表 employee 可以访问属性 didassociation 标签需要指明属性 javaType
<mapper namespace="glad.mapper.ResultMapMapper">
    <resultMap id="myResultMap" type="glad.pojo.Employee">
        <id property="eid" column="eid"></id>
        <result property="ename" column="ename"></result>
        <association property="department" javaType="glad.pojo.Department">
            <id property="did" column="did"></id>
            <result property="dname" column="dname"></result>
        </association>
    </resultMap>
    
    <select id="getEmpAndDept" resultMap="myResultMap">
    	<!--使用 association 后,employee 可以访问属性 did-->
        select * from employee left join department on employee.did = department.did where employee.eid = #{eid}
    </select>
</mapper>
  • 查询结果
    在这里插入图片描述

3 处理一对多关系

示例:根据部门id,查询其员工信息

  • POJO(省略 Lombok 注解)
public class Employee {
    private Integer eid;
    private String ename;
    private Integer did;
}

public class Department {
    private Integer did;
    private String dname;
    List<Employee> emps;
}
  • 接口方法
public interface ResultMapMapper {

    Deptartment getDeptAndEmp(@Param("did") Integer did);
    
}
  • 映射文件:使用 collection 标签声明类的 List 属性,并设置标签的 ofType 属性(代表容器内元素的属性)
<mapper namespace="glad.mapper.ResultMapMapper">
    <resultMap id="myResultMap" type="glad.pojo.Department">
        <id property="did" column="did"></id>
        <result property="dname" column="dname"></result>
        <collection property="emps" ofType="glad.pojo.Employee">
            <id property="eid" column="eid"></id>
            <result property="ename" column="ename"></result>
        </collection>
    </resultMap>

    <select id="getDeptAndEmp" resultMap="myResultMap">
        select * from department left join employee on department.did = employee.did where department.did = #{did}
    </select>
</mapper>

四 动态 SQL

1 if 标签

满足指定条件时,才会将 if 标签中的 SQL 加入

  • POJO:省略 Lombok 注解,和表中的属性名以 X 区分,注意在映射文件的各处访问的是表还是传入的参数
public class User {
    private Integer idX;
    private String usernameX;
    private String passwordX;
    private Integer ageX;
    private String sexX;
    private String emailX;
}
  • 接口方法
public interface DynamicMapper {

	// 根据任意信息查询
    List<User> getInfo(User user);

}
  • 映射文件:
    数据库表的字段,和类的属性名不一致时,使用 resultMap,否则查询结果一直为 null
    为了保证格式正确,需要在 where 后加一个恒成立条件
<mapper namespace="dynamic.mapper.DynamicMapper">
    <resultMap id="myResultMap" type="dynamic.pojo.User">
        <id property="idX" column="id"></id>
        <result property="usernameX" column="username"></result>
        <result property="passwordX" column="password"></result>
        <result property="ageX" column="age"></result>
        <result property="sexX" column="sex"></result>
        <result property="emailX" column="email"></result>
    </resultMap>
    <select id="getInfo" resultMap="myResultMap">
        select * from user where 1 = 1
        <if test="idX != '' and idX != null">
            and id = #{idX}
        </if>
        <if test="usernameX != '' and usernameX != null">
            and username = #{usernameX}
        </if>
        <if test="passwordX != '' and passwordX != null">
            and password = #{passwordX}
        </if>
        <if test="ageX != '' and ageX != null">
            and age = #{ageX}
        </if>
        <if test="sexX != '' and sexX != null">
            and sex = #{sexX}
        </if>
        <if test="emailX != null and emailX !=''">
            and email = #{emailX}
        </if>
    </select>
</mapper>

2 where 标签

一般和 if 标签结合使用:
where 标签中的 if 子标签条件都不满足,则 where 标签没有任何功能,即不会添加 where 关键字;
where 标签中的 if 子标签条件满足,则 where 标签会自动添加 where 关键字,并将条件最前方多余的 and 去掉

<select id="getEmpListByMoreTJ2" resultType="Emp">
	select * from t_emp
	<where>
		<if test="ename != '' and ename != null">
			ename = #{ename}
		</if>
		<if test="age != '' and age != null">
			and age = #{age}
		</if>
		<if test="sex != '' and sex != null">
			and sex = #{sex}
		</if>
	</where>
</select>

3 trim 标签

trim 用于去掉或添加标签中的内容

属性作用
prefixtrim 标签中的内容的前面添加某些内容
prefixOverridestrim 标签中的内容的前面去掉某些内容
suffixtrim 标签中的内容的后面添加某些内容
suffixOverridestrim 标签中的内容的后面去掉某些内容
  • 映射文件
<select id="getEmpListByMoreTJ" resultType="Emp">
	select * from t_emp
	<!--在以下部分的开头添加where,末尾删去and-->
	<trim prefix="where" suffixOverrides="and">
		<if test="ename != '' and ename != null">
			ename = #{ename} and
		</if>
		<if test="age != '' and age != null">
			age = #{age} and
		</if>
		<if test="sex != '' and sex != null">
			sex = #{sex}
		</if>
	</trim>
</select>

4 choose, when, otherwise 标签

choosewhenotherwise 的父标签,组合使用的效果相当于 Java 的 if, else if, else

  • 映射文件
<!--List<Emp> getEmpListByChoose(Emp emp);-->
<select id="getEmpListByChoose" resultType="Emp">
	select * from t_emp
	<where>
		<choose>
			<when test="ename != '' and ename != null">
				ename = #{ename}
			</when>
			<when test="age != '' and age != null">
				age = #{age}
			</when>
			<when test="sex != '' and sex != null">
				sex = #{sex}
			</when>
			<when test="email != '' and email != null">
				email = #{email}
			</when>
		</choose>
	</where>
</select>

5 foreach 标签

用于执行批量操作

属性作用
collection设置要循环的数组或集合
item表示集合或数组中的每一个数据
separator设置元素之间的分隔符
open设置 foreach 标签中的内容的开始符
close设置 foreach 标签中的内容的结束符
  • 映射文件
<!--int insertMoreEmp(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreEmp">
	insert into t_emp values
	<foreach collection="emps" item="emp" separator=",">
		(null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)
	</foreach>
</insert>

<!--int deleteMoreByArray(@Param("eids") int[] eids);-->
<delete id="deleteMoreByArray">
	delete from t_emp where eid in
	<foreach collection="eids" item="eid" separator="," open="(" close=")">
		#{eid}
	</foreach>
</delete>

6 sql 标签

提取 SQL 语句的公共部分

<sql id="empColumns">
	eid, ename, age, sex, did
</sql>

引用:
select <include refid="empColumns"></include> from t_emp

五 MyBatis 缓存

1 一级缓存

  • 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
  • 使一级缓存失效的四种情况:
    1. 不同的 SqlSession 对应不同的一级缓存
    2. 同一个 SqlSession 但是查询条件不同
    3. 同一个 SqlSession 两次查询期间执行了任何一次增删改操作
    4. 同一个 SqlSession 两次查询期间手动清空了缓存

2 二级缓存

  • 二级缓存是 SqlSessionFactory 级别,通过同一个 SqlSessionFactory 创建的 SqlSession 查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
  • 使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
  • 开启二级缓存的步骤:
    1. 在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
    2. 在映射文件中设置标签 <cache>
    3. 二级缓存必须在 SqlSession 关闭或提交之后有效:一个 SqlSession 写入二级缓存,当第一个 SqlSession 关闭或提交后,供相同 SqlSessionFactory 创建的另一个 SqlSession 使用
    4. 查询的数据所转换的实体类类型必须实现序列化的接口 Serializable

3 查询顺序

  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  • 如果二级缓存没有命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession 关闭之后,一级缓存中的数据会写入二级缓存

六 逆向工程

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成 Java 实体类、Mapper 接口、Mapper 映射文件

  1. 引入依赖、配置核心配置文件
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
        <!-- 构建过程中用到的插件 -->
        <plugins>
            <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <!-- 插件的依赖 -->
                <dependencies>
                    <!-- 逆向工程的核心依赖 -->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.4.0</version>
                    </dependency>
                    <!-- 数据库连接池 -->
                    <dependency>
                        <groupId>com.mchange</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.2</version>
                    </dependency>
                    <!-- MySQL驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.20</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
  1. 创建逆向工程的配置文件,必须命名为 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>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD
    MyBatis3: 生成带条件的CRUD
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/learn?serverTimezone=UTC"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="mybatis.bean"
                            targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="mybatis.mapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="employee" domainObjectName="Employee"/>
        <table tableName="department" domainObjectName="Department"/>
    </context>
</generatorConfiguration>
  1. 运行插件,生成的 xxExample 用于添加约束,具体使用方法见4
    在这里插入图片描述
    在这里插入图片描述
  2. 执行 CRUD
public class MyTest {
    @Test
    public void reverseTest() throws IOException {
        // ...
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);

        // 使用QBC形式添加条件
        DepartmentExample departmentExample = new DepartmentExample();
        departmentExample.createCriteria().andDidEqualTo(1).andDnameEqualTo("保卫处");

        // 将之前添加的条件通过or拼接其他条件
        departmentExample.or().andDidIsNotNull();

        // 传入条件,执行sql
        System.out.println(departmentMapper.countByExample(departmentExample));
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 愿景我们的愿景是成为 MyBatis 超好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。 特性无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作 我们将通过理论与实操的方式来阐述 MyBatis-Plus 的强大功能,体验和学习MyBatis-Plus技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值