目录
- SSM为SpringFramework + SpringMVC + MyBatis
- Spring的3大特性:IoC(控制反转),DI(依赖注入),AOP(面向切面编程)。
- 框架 = jar + 配置文件
MyBatis简介
简单来说,MyBatis是一款持久层框架,它可以简化我们对数据库的操作,它通过简单的XML或注解将原始类型、接口和Java的pojo类配置和映射为数据库中的数据。
MyBatis早期叫做iBatis,到iBatis3.x正式更名为MyBatis,因此在导依赖时可能会出现该单词。
本文章使用的MyBatis版本为3.5.11。
持久层框架对比
JDBC:
- 代码繁琐,耦合度高,不易维护。
Hibernate 和 JPA:
- 操作简单、开发效率高。
- 较复杂的sql需要绕过该框架。
- 内部生成的sql不容易优化。
- pojo中如果字段较多难以部分映射,数据库性能下降。
MyBatis:
- 轻量级,性能优秀。
- sql 和 java编码分开,功能边界清晰。java代码主业务,sql语句专注数据。
- 开发效率可以接受。
案例演示
1.创建数据库和表并添加数据。
create database mybatis_example;
use mybatis_example;
create table t_emp(
emp_id int auto_increment,
emp_name char(20),
emp_salary double(10,5),
primary key(emp_id)
);
insert into t_emp(emp_name,emp_salary) values ('tom',200.00),('jerry',666.66),('andy',777.77);
2.创建spring-mybatis项目并导入以下依赖。
<dependencies> <!-- mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency> <!-- mysql驱动,mybatis底层需要jdbc驱动,mybatis自带连接池--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <!-- junit5依赖--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.1</version> <scope>test</scope> </dependency> </dependencies>3.编写一个pojo类employee,包含以下属性
private Integer empId; private String empName; private Double empSalary;4.编写Mapper层(数据访问层)接口:EmployeeMapper
public interface EmployeeMapper { Employee queryById(Integer id); }5.在resources下创建EmployeeMapper.xml(一般与上方接口相同),以下为mybatis的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=""> </mapper>6.编写EmployeeMapper.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"> <!-- namespace = mapper对应接口的全限定符--> <mapper namespace="com.qiu.mapper.EmployeeMapper"> <!-- 每一个<curd>标签都对应一个方法 id值对应方法名,resultType对应返回类型 注意:mapper接口不能重载。 --> <select id="queryById" resultType="com.qiu.pojo.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=${id}; </select> </mapper>7.创建并编写mybatis配置文件
<?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"> <!-- 以上为mybatis配置文件的约束--> <configuration> <!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --> <environments default="development"> <!-- environment表示配置Mybatis的一个具体的环境 --> <environment id="development"> <!-- Mybatis的内置的事务管理器 --> <transactionManager type="JDBC"/> <!-- 配置数据源 --> <dataSource type="POOLED"> <!-- 建立数据库连接的具体信息 --> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis_example"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <!-- Mapper注册:指定Mybatis映射文件的具体位置 --> <!-- mapper标签:配置一个具体的Mapper映射文件 --> <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 --> <!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 --> <mapper resource="mappers/EmployeeMapper.xml"/> </mappers> </configuration>8.测试方法
public class MybatisTest { @Test public void testSelectEmployee() throws IOException, IOException, IOException { // 1.创建SqlSessionFactory对象 // ①声明Mybatis全局配置文件的路径 String mybatisConfigFilePath = "mybatis-config.xml"; // ②以输入流的形式加载Mybatis配置文件 InputStream inputStream = Resources.getResourceAsStream(mybatisConfigFilePath); // ③基于读取Mybatis配置文件的输入流创建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 2.使用SqlSessionFactory对象开启一个会话 SqlSession sqlSession = sqlSessionFactory.openSession(); // 3.根据EmployeeMapper接口的Class对象获取Mapper接口类型的对象(动态代理技术) EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class); // 4. 调用代理类方法既可以触发对应的SQL语句 Employee employee = mapper.queryById(1); System.out.println("employee = " + employee); // 4.关闭SqlSession sqlSession.commit(); //提交事务 [DQL不需要,其他需要] sqlSession.close(); //关闭会话 } }9.执行后输出如下:
employee = Employee{id=1, empName='tom', empSalary=200.0}
数据访问层之前叫Dao层,在mybatis中更偏向于叫做Mapper。
- 之前的实现方式为:
- XxxDao 接口 规定方法
- XxxDaoImpl 实现类 方法的具体实现(操作数据库)
- mybatis的实现方法为:
- XxxMapper 接口 规定方法,
- 但具体的实现有两种方式:
- XML方式:XxxMapper.xml 在xml中写接口对应方法的sql语句。
- 注解方式:不常用。
ibatis与Mybatis
Mybatis对数据库的curd是对ibatis功能的封装和优化
MyBatis基本使用
mybatis事务
当获取mybatis的SqlSession对象时使用SqlSessionFactory对象的openSession()获取的,会自动开启事务,但不会自动提交事务,需要使用Session对象的commit()方法手动提交。
可以使用SqlSessionFactory对象的openSession(true)方法获取Session对象,该对象会自动提交事务。
mybatis配置文件下的标签必须严格按照顺序编写:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
1.日志输出
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
可以设置的值有:SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING。
2.数据输入
- 在xml中sql语句的参数是可以使用${}或#{}传入的
- 如:
<select id="queryById" resultType="com.qiu.pojo.Employee"> select * from t_emp where emp_id=${id}(或者#{id}); </select>
- ${}:将直接把参数使用字符串拼接与sql语句拼接在一起
- #{}:将先使用 ? 占位符来把sql语句完成,在往占位符中赋值。可以防止【注入攻击】
- 推荐:当参数是数据值是使用#{},否则使用${}。(如:select * from t_emp where ${find}=#{id})
- 如:
- 传入的数据类型:
- 简单类型:简单来说就是在传入的数据中只能得到一个值。如:
- 基本数据类型:int,byte,short…
- 基本数据类型的包装类:Integer,Character,Double…
- 字符串类型:String…
- 复杂类型:可以在传入的数据中得到多个值。如:
- 实体类:Employee,Student…
- 集合类型:List,Set,Map…
- 数组类型:int[]…
- 复合类型:List<Employee>,实体类中包含数组…
- 简单类型:简单来说就是在传入的数据中只能得到一个值。如:
2.1 单个简单类型参数
在EmployeeMapper接口编写方法:
int deteleById(Integer id); List<Employee> queryBySalary(Double salary);
在EmployeeMapper.xml文件编写sql语句:
<!-- 传入单个简单类型时,#{key}或${key} 中 key 随便写,但一般写参数名--> <delete id="deleteById"> delete from t_emp where emp_id = #{id}; </delete> <!-- 返回值类似List<实体类>时,返回参数依然为实体类的全限定符--> <select id="queryBySalary" resultType="com.qiu.pojo.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_salary = #{salary}; </select>
2.2 实体类类型参数
接口方法:
int insertEmp(Employee employee);
xml文件的sql语句:
<!-- 传入实体类类型时,#{key}或${key} 中 key 写实体类的属性名--> <insert id="insertEmp"> insert into t_emp (emp_name,emp_salary) values (#{empName},#{empSalary}); </insert>
2.3 多个简单类型参数
接口方法:
List<Employee> queryByNameAndSalary(String name,Double salary);
方法1:
在接口方法的参数前加上@Param("name")注解来指定名称再到sql语句下传入:
List<Employee> queryByNameAndSalary(@Param("a") String name,@Param("b") Double salary);
<select id="queryByNameAndSalary" resultType="com.qiu.pojo.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name = #{a} emp_salary = #{b}; </select>
方式2:Mybatis默认机制会把参数按顺序设置为arg0,arg1…或param1,param2…。
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name = #{param1} emp_salary = #{param2}; select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name = #{arg0} emp_salary = #{arg1};
2.4 Map类型参数
传入Map类型时,#{key}或${key} 中 key 写Map中对应的key
3.数据输出
数据输出主要有两种:
- 增删改操作所影响到的行数:直接使用int或long接收
- 查询语句的查询结果
- 插入时可能需要主键回显
类型别名:
- 可以将Java类型缩写。
- Mybatis为一些常用的Java类型设置了简写:
- 基本数据类型:int double --> _int _double(前面加下划线)
- 包装数据类型:Integer Double ->int integer double
- 集合容器类型:Map List HashMap -> 小写即可 map list hashmap
如果Mybatis没有设置的类型,可以在Mybatis配置文件下自己设置别名或直接写全限定符:
<typeAliases> <!-- 直接设置类型别名--> <typeAlias type="com.qiu.pojo.Employee" alias="employee"/> <!-- 设置包别名,默认会把包下的Java Bean下的首字母小写作为它的别名--> <package name="com.qiu.pojo"/> </typeAliases>
resultType语法:
- 类的全限定符号
- 别名简称
3.1 返回单个简单类型
接口方法:
//如果是增删改语句直接使用int或long int delectById(Integer id); //查询语句 String queryNameById(Integer id); Double querySalaryById(Integer id);
xml文件sql语句:
<delete id="deleteById"> delete from t_emp where emp_id = #{id} </delete> <select id="queryNameById" resultType="java.lang.String"> select emp_name from t_emp where emp_id = #{id} </select> <select id="querySalaryeById" resultType="double"> select emp_salary from t_emp where emp_id = #{id} </select>
3.2 返回实体类对象
接口方法:
Employee queryById(Integer id);
xml文件sql语句:
<select id="queryById" resultType="com.qiu.pojo.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id = #{id}; </select>
3.3 返回Map类型
接口方法:
Map<String,Object> selectEmpNameAndMaxSalary();
xml文件sql语句:
<select id="selectEmpNameAndMaxSalary" resultType="map"> select emp_name 员工姓名, emp_salary 员工工资, (select AVG(emp_salary) from t_emp) 部门平均工资 from t_emp where emp_salary = (select MAX(emp_salary) from t_emp); </select>
有实体类时用实体类,没有时使用map。
3.4 返回List类型
返回值是集合,resultType不需要指定集合类型,只需要指定泛型。
接口方法:
List<Employee> queryAll();
xml文件sql语句:
<select id="queryAll" resultType="com.qiu.pojo.Employee"> select * from t_emp; </select>
3.5 返回主键值
1.自增长类型主键
sql语句
<insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId"> insert into t_emp (emp_name, emp_salary) values (#{empName},#{empSalary}); </insert>
测试代码:
…… Employee employee = new Employee(); employee.setEmpName("刘德华"); employee.setEmpSalary(1999.99); mapper.insertEmp(employee); System.out.println("row = " + employee.getId()); ……
2.非自增长类型主键
主键为字符串类型,可以自己维护,即自己在插入数据时自己来写它的主键。
也可以让mybatis帮我们维护:
<!-- <selectKey>标签可以在插入之前还是之后执行一段sql语句 order="BEFORE"或"AFTER" 表示在该sql是在插入语句执行前还是执行后执行 resultType 返回值类型,可以用别名 keyProperty 返回结果给哪个属性赋值 --> <insert id="insertTeacher"> <selectKey order="BEFORE" resultType="string" keyProperty="tId"> <!--获取一个UUID并把里面的'-'去掉--> select REPLACE(UUID(),'-',''); </selectKey> insert into teacher (t_id,t_name) values (#{tId},#{tName}); </insert>
*3.6 实体类属性和数据库字段对应关系
如果实体类的名与数据表的列名不一致的时候,可以:
方案1.起别名 select t_id tId, t_name tName from teacher where t_id = #{tId};
方案2.开启驼峰映射:t_id =>tId,t_name =>tName
方案3.resultMap标签:(在select标签中resultMap和resultType只能二选一)
resultType只有在开启驼峰映射时才会按照规则自动映射,而且只能映射一层结构。深层次的对象结构无法映射,多表查询的时候结果无法映射。
Order 数据库
orderId order_id
orderName order_name
OrderItem orderItem
itemId item_id ----->这两个不会映射
resultMap自定义映射:
<!-- resultMap的id标识 对应 <select>标签的resultMap=“id”,type标识 具体返回类型:全限定符或别名,集合只写泛型。 <id>标签 对应 主键映射关系 <result>标签 对应 普通列的映射关系 --> <resultMap id="tMap" type="teacher"> <id column="t_id" property="tId"/> <result column="t_name" property="tName"/> </resultMap> <select id="queryById" resultMap="tMap"> select t_id,t_name from teacher where t_id = #{tId}; </select>
驼峰映射
在获取数据时,数据库的字段一般使用下滑线,JavaBean一般使用驼峰命名法,每次写sql都要在sql语句中起别名太麻烦。但MyBatis可以设置驼峰映射:emp_id ->empId。
在MyBatis配置文件中设置settings:
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
开启后SQL语句可以简化:
<select id="queryById" resultType="com.qiu.pojo.Employee"> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id = #{id}; </select>
简化后:
<select id="queryById" resultType="com.qiu.pojo.Employee"> select * from t_emp where emp_id = #{id}; </select>
MyBatis多表映射
多表映射
当需要多表联查时,我们不会总有对应的实体类,因此需要进行多表映射。
- 1.定义sql语句
- 2.设计存储数据的实体类
- 3.指定查询返回的结果
- 4.自己定义结果集映射(字段->属性)(resultMap)
对一映射
对一关系:夫妻一方对应一方,一个订单对应一个客户。
实体类设计:对一关系下,类中只要包含单个对方对象类型属性即可。如:
public class Customer { private Integer customerId; private String customerName; } public class Order { private Integer orderId; private String orderName; private Customer customer;//一份订单对应一个客户 }
样例演示:
业务:在数据库的order表和customer表中查找到order_id为1 的 订单信息和对应的客户信息。
1.创建数据库表并插入数据
2.不考虑多表查询的创建与数据库表对应的实体类
3.考虑到业务需要,在Order类中加入Customer来获取查找到的数据的customer信息
4.在mapper接口中添加业务方法
5.设计sql语句
当id = 1时结果为:
这里tor.customer_id 和 tur.customer_id在执行时只会返回customer_id
6.在mapper.xml中编写sql语句
<resultMap id="orderMap" type="order"><!--id:要传入sel标签中的resultMap type:返回类型,此处使用别名--> <id column="order_id" property="orderId"/> <result column="order_name" property="orderName"/> <result column="customer_id" property="customerId"/> <!-- association标签作用是对一时给单个对象赋值 property:在主类型中次类型的属性名, javaType:次类型的类型,此处为别名--> <association property="customer" javaType="customer"> <id column="customer_id" property="customerId"/> <result column="customer_name" property="customerName"/> </association> </resultMap> <select id="queryOrderById" resultMap="orderMap"> select * from t_order tor join t_customer tur on tor.customer_id = tur.customer_id where tor.order_id = #{id}; </select>7.编写测试代码并执行
执行结果:
对多映射
对多关系:一个客户可以有多份订单,一个导师可以有多个学员。
实体类设计:对多关系下,类中只要包含对方类型集合属性即可。如:
public class Order { private Integer orderId; private String orderName; private Customer customer;//一份订单对应一个客户 } public class Customer { private Integer customerId; private String customerName; private List<Order> orderList;//一个客户有多份订单 }
样例演示:
业务:在数据库的order表和customer表中查找到customer_id为1 的 客户信息和对应的所有订单信息。
1.创建数据库表并插入数据
2.不考虑多表查询的创建与数据库表对应的实体类
3.考虑到业务需要,在Customer类中加入List<Order>来获取查找到的数据中的多个order信息
4.在mapper接口中添加业务方法
5.设计sql语句
当id = 1时结果为:
这里tor.customer_id 和 tur.customer_id在执行时只会返回customer_id
6.在mapper.xml中编写sql语句
<resultMap id="customerMap" type="customer"> <id column="customer_id" property="customerId"/> <result column="customer_name" property="customerName"/> <!-- collection标签作用是对多时给集合类型赋值, 注意这里类型的标识为ofType--> <collection property="orderList" ofType="order"> <id column="order_id" property="orderId"/> <result column="order_name" property="orderName"/> <result column="customer_id" property="customerId"/> <!-- 这里切记不要给order里的customer赋值--> </collection> </resultMap> <select id="queryCustomerById" resultMap="customerMap"> select * from t_customer tur join t_order tor on tor.customer_id = tur.customer_id where tur.customer_id = #{id}; </select>7.编写测试代码并执行
执行结果:
多表映射的注意点(推荐点)
- 对一关系只需要实体类在属性上包含对方对象
- 对多关系只需要实体类在属性上包含对方对象列表
- 只有发生多表联查时,才需要设计和修改实体类,否则不提前和修改设计实体类。
- 无论多少张表联查,实体类设计都是两两考虑。即考虑两个表之间是一对一还是一对多关系。
- 在查询映射是,只需要考虑本次查询相关的属性。如:上述两个类中,当查询订单数据时只考虑订单中的Customer属性,不再去深入查找Customer中的orderlist属性,不要形成死循环。
MyBatis动态语句
if 和 where 标签
接口方法:
Employee query(@Param("name") String name,@Param("salary") Double salary);
之前的sql语句
<select id="query" resultType="employee"> select * from t_emp where emp_id = #{name} and emp_salary=#{salary}; </select>
但为防止name为null或salary为null,MyBatis提供了<if>:
<!-- test 内部可以直接使用接口方法的参数名 test 内部做运算,为true则做拼接,为false则不拼接--> <select id="query" resultType="employee"> select * from t_emp where <if test="name != null"> emp_name = #{name} </if> <if test=""> and emp_salary=#{salary} </if> </select>
但上式如果第一个if为false,第二个为true,sql就会变为:
select * from t_emp where and emp_salary=#{salary};
为防止此情况,MyBatis提供了<where>:
<!-- where标签作用:1.自动添加where关键字,当where标签内部有一个if满足,自动添加where关键字,否则不添加 2.自动去掉多余的and和or--> <select id="query" resultType="employee"> select * from t_emp <where> <if test="name != null"> emp_name = #{name} </if> <if test=""> and emp_salary=#{salary} </if> </where> </select>
set标签
接口方法:
int update(Employee employee);
要求只有当employee中的name和salary不为null才执行语句
<!-- 当第一个成立,第二个不成立时,sql多一个逗号--> <update id="update"> update t_emp set <if test="empName != null"> emp_name = #{empName}, </if> <if test="empSalary != null"> emp_salary = #{empSalary} </if> where emp_id = #{empId}; </update>
<set>:1.自动去除多余的逗号 2.自动添加set关键字
<update id="update"> update t_emp <set> <if test="empName != null"> emp_name = #{empName}, </if> <if test="empSalary != null"> emp_salary = #{empSalary} </if> </set> where emp_id = #{empId}; </update>
trim标签(了解)
动态添加或去除前置词和后置词,可以替代where和set
choose/when/otherwise标签
在多个分支条件下,只选择一个。
判断顺序:从上往下判断,当有一个when为true就采纳,如果所有when都为false,执行otherwise
<select id="query1" resultType="employee"> select * from t_emp where <choose> <when test="empName!=null">emp_name = #{name}</when> <when test="empSalary > 100">and emp_salary=#{salary}</when> <otherwise>1=1</otherwise> </choose> </select>
foreach标签(重点)
当需要批量操作时可以使用foreach,如:插入多个数据,根据id批量查询。
当参数传入一个List集合类型时,需要使用@Param("值")来设置它的名称,不然在collection属性中默认使用collection,list或arg0来引用这个List集合。
接口方法:
List<Employee> queryBatch(@Param("ids")List<Integer> idList); int updateBatch(@Param("emps")List<Employee> empList);
xml文件sql:
<select id="queryBatch" resultType="employee"> select * from t_emp where emp_id in <!-- collection:要遍历的变量名,即传入的list参数名 open:遍历前添加的字符串 separator:每次遍历的分隔符,如果是最后一次遍历不会添加 close:遍历后添加的字符串 item:获取每个遍历项 在foreach标签中可以使用#{item} 获取list中的每个元素 --> <foreach collection="ids" open="(" separator="," close=")" item="id"> #{id} </foreach> </select>
<insert id="insertBatch"> insert into t_emp (emp_name, emp_salary) values <foreach collection="emps" open="" close="" separator="," item="emp"> (#{emp.empName},#{emp.empSalary}) </foreach> </insert>
当使用foreach操作update语句时,直接将整个sql语句包裹进去,此时将执行多次update语句,但需要设置MyBatis配置文件中连接数据库时的url,在url后面添加"?allowMultiQueries=true"(允许多语句执行)。
sql片段
抽取重复的sql片段:
<sql id="selectSQL"> select * from t_emp </sql> <select id="queryBatch" resultType="employee"> <include refid="selectSQL"/> where emp_id in <foreach collection="ids" open="(" separator="," close=")" item="id"> #{id} </foreach> </select>
MyBatis高级拓展
Mapper批量映射优化
如果有多个Mapper添加到MyBatis配置文件中mappers会十分繁琐,可以使用<package name=""
但要求MapperXML文件与mapper接口的命名必须相同并且最后打包后的位置要一致,都是在name指定的包下,有两种方法:
方法1:xml也放到mapper接口的包下(假设为src/main/java/com/qiu/mapper),但需要设置pom文件,不然项目编译打包时不会将java包下的xml文件打包。
<build> <resources> <!-- 将src/main/java下的所有文件都打包--> <resource> <directory>src/main/java</directory> <includes> <include>**/*.*</include> </includes> </resource> </resources> </build>
方法2:在resources文件夹创建与src/main/java下相同的文件夹结构com/qiu/mapper,这样打包时会把两个文件夹内容打包到一起。
插件和分页插件PageHelper
MyBatis对插件进行了标准化设计,并提供了一套可拓展的插件机制。插件可以在用于语句执行过程中进行拦截,并允许通过自定义处理程序来拦截和修改sql语句、映射语句结果等。
PageHelper插件
对select查询到的数据进行limit处理,即获取数据集里的一段数据。该插件会在sql正式执行前在后面拼接上limit x,y ,所以写sql时结尾不要加 ; 。
PageHelper插件使用:
1、导依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.11</version> </dependency>
2、在MyBatis配置文件里配置分页插件
<!-- com.github.pagehelper.PageInterceptor为分页插件的名称--> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 插件语法对应的数据库类型--> <property name="helperDialect" value="mysql"/> </plugin>
逆向工程和MybatisX插件
orm思维持久层框架
java是面向对象的编程思维,数据库是面向过程的编程思维。
而orm思维指的是使用面向对象思维进行数据库操作。
MyBatis框架提供了一些crud方法,由框架转换为对数据库的操作,但sql需要自己编写,所以MyBatis框架是半自动orm思维持久层框架
全自动orm思维持久层框架如hibernate,只需要把数据库数据和java实体类映射(配置),它就能提供crud方法,而且会自动生成对应的sql语句。
将半自动orm框架 ->全自动orm框架就叫做逆向工程(MyBatis->mybatis-plus)
逆向工程插件MybatisX插件
1.安装MyBatisX插件
2.idea连接数据库
3.选择数据库的表右键
4.进行以下操作: