1、MyBatis简介
1.1 MyBatis历史
(1)MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁
移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。代码于
2013年11月迁移到Github。
(2)iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。 iBatis提供的持久层框架
包括SQL Maps和Data Access Objects(DAO)。
1.2 MyBatis特性
1)MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
2)MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
3)MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java
Objects,普通的Java对象)映射成数据库中的记录
4)MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
2、搭建MyBatis
2.1 MySQL不同版本的注意事项
(1)驱动类driver-class-name
①MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver
②MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
(2)连接地址url
①MySQL 5版本的url:jdbc:mysql://localhost:3306/ssm
②MySQL 8版本的url:jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
2.2 创建MyBatis的映射文件
(1)相关概念:ORM(Object Relationship Mapping)对象关系映射。
①对象:Java的实体类对象
②关系:关系型数据库
③映射:二者之间的对应关系
(2)映射文件的命名规则:
①表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
②MyBatis映射文件用于编写SQL,访问以及操作表中的数据
③MyBatis映射文件存放的位置是src/main/resources/mappers目录下
(3) MyBatis中可以面向接口操作数据,要保证两个一致:
①mapper接口的全类名和映射文件的命名空间(namespace)保持一致
②mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
(4)测试实例
//获取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(); //sqlSession.commit();提交事务,默认是回滚的;所以看不到结果,开启提交事务才可以看到结果 System.out.println("结果:"+result);
①SqlSession:代表Java程序和数据库之间的会话(HttpSession是Java程序和浏览器之间的会话)
②SqlSessionFactory:是“生产”SqlSession的“工厂”。
工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的
相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
3、核心配置文件详解
(1)核心配置文件中的标签必须按照固定的顺序:
properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,
reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?
<?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> <!--引入properties文件--> <properties resource="jdbc.properties" /> <!--设置类型别名--> <typeAliases> <!-- typeAlias:设置某个类型的别名 属性: type:设置需要设置别名的类型 alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名, 即类名,且不区分大小写 --> <!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>--> <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写--> <package name="com.atguigu.mybatis.pojo"/> </typeAliases> <!-- environments:配置多个连接数据库的环境 属性: default:设置默认使用的环境的id --> <environments default="development"> <!-- environment:配置某个具体的环境 属性: id:表示连接数据库的环境的唯一标识,不能重复 --> <environment id="development"> <!-- transactionManager:设置事务管理方式 属性:type="JDBC|MANAGED" JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事 务的提交或回滚需要手动处理 MANAGED:被管理,例如Spring --> <transactionManager type="JDBC"/> <!-- dataSource:配置数据源 属性: type:设置数据源的类型 type="POOLED|UNPOOLED|JNDI" POOLED:表示使用数据库连接池缓存数据库连接 UNPOOLED:表示不使用数据库连接池 JNDI:表示使用上下文中的数据源 --> <dataSource type="POOLED"> <!--设置连接数据库的驱动--> <property name="driver" value="${jdbc.driver}"/> <!--设置连接数据库的连接地址--> <property name="url" value="${jdbc.url}"/> <!--设置连接数据库的用户名--> <property name="username" value="${jdbc.username}"/> <!--设置连接数据库的密码--> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--引入映射文件--> <mappers> <!--<mapper resource="mappers/UserMapper.xml"/>--> <!-- 以包为单位引入映射文件 要求: 1、mapper接口所在的包要和映射文件所在的包一致 2、mapper接口要和映射文件的名字一致 --> <package name="com.atguigu.mybatis.mapper"/> </mappers> </configuration>
4、MyBatis获取参数值的两种方式
MyBatis获取参数值的两种方式:${}和#{}
(1)${}的本质就是字符串拼接,#{}的本质就是占位符赋值
(2)${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单
引号;
(3)但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动
添加单引号
4.1 单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型
此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号
4.2 多个字面量类型的参数
若mapper接口中的方法参数为多个时此时MyBatis会自动将这些参数放在一个map集合中,
(1)以arg0,arg1…为键,以参数为值;
(2)以param1,param2…为键,以参数为值;
因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值
注意${}需要手动加单引号
4.3 map集合类型的参数
若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中。
只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
(1)UserMapper.java
User checkLoginByMap(Map<String,Object> map);
(2)UserMapper.xml
<select id="checkLoginByMap" resultType="User"> select * from t_user where username = #{username} and password = #{password} </select>
(3) 测试
Map<String,Object> map = new HashMap<>(); map.put("username","admin"); map.put("password","123456"); User user = mapper.checkLoginByMap(map);
4.4 实体类类型的参数
若mapper接口中的方法参数为实体类对象时
此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号
4.5 使用@Param标识参数
可以通过@Param注解标识mapper接口中的方法参数
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;
只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
5、MyBatis特殊的SQL执行
5.1 查询多条数据为map集合
(1)方式一
将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,此
时可以将这些map放在一个list集合中获取
①Mapper.java
List<Map<String, Object>> getAllUserToMap();
②Mapper.xml
<select id="getAllUserToMap" resultType="map"> select * from t_user </select>
(2)方式二
将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,并
且最终要以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对
应的map集合
①Mapper.java
@MapKey("id") Map<String, Object> getAllUserToMap();
②Mapper.xml
<select id="getAllUserToMap" resultType="map"> select * from t_user </select>
③结果如下
{ 1={password=123, sex=男, id=1, age=23, username=admin}, 2={password=416, sex=男, id=2, age=24, username=张三}, 3={password=341, sex=男, id=3, age=25, username=李四} }
5.2 模糊查询
<select id="testMohu" resultType="User"> <!-- 方式一 --> select * from t_user where username like '%${mohu}%' <!-- 方式二 --> select * from t_user where username like concat('%',#{mohu},'%') <!-- 方式三 --> select * from t_user where username like "%"#{mohu}"%" </select>
5.3 批量删除
(1)Mapper.java
/** * 批量删除 * @param ids * @return */ int deleteMore(@Param("ids") String ids);
(2)Mapper.xml
<!--int deleteMore(@Param("ids") String ids);--> <delete id="deleteMore"> delete from t_user where id in (${ids}) </delete>
5.4 动态设置表名
(1)Mapper.java
/** * 动态设置表名,查询所有的用户信息 * @param tableName * @return */ List<User> getAllUser(@Param("tableName") String tableName);
(2)Mapper.xml
<select id="getAllUser" resultType="User"> select * from ${tableName} </select>
5.5 添加功能获取自增的主键
(1)Mapper.java
/** * useGeneratedKeys:设置使用自增的主键 * keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参 数user对象的某个属性中 */ int insertUser(User user);
(2)Mapper.xml
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> insert into t_user values(null,#{username},#{password},#{age},#{sex}) </insert>
6、自定义映射resultMap
6.1 当字段名和属性名不一致的时候,如何处理映射关系?
(1)为查询的字段设置别名,和属性名保持一致
<select id="getEmpById" resultType="Emp"> select emp_id empId,emp_name empName,age,gender from t_emp where emp_id = #{empId} </select>
(2)当字段符合Mysql的要求使用下划线“_”,而实体类的属性符合Java的要求使用驼峰;
此时可以在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"> <configuration> <settings> <!-- 将下划线映射为驼峰 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> </configuration>
(3)通过resultMap设置自定义映射
<!-- resultMap: 设置自定义的映射关系 id:唯一标识 type: 处理映射关系的实体类的类型 常用的标签: id:处理主键和实体类中属性的映射关系 result:处理普通字段和实体类中属性的映射关系 column:设置映射关系中的字段名,必须是SQL查询出的某个字段 property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名 --> <resultMap id="AddressEntityMap" type="com.cy.store.entity.Address"> <id column="aid" property="aid"/> <result column="province_code" property="provinceCode"/> <result column="province_name" property="provinceName"/> <result column="city_code" property="cityCode"/> <result column="city_name" property="cityName"/> <result column="area_code" property="areaCode"/> <result column="area_name" property="areaName"/> <result column="is_default" property="isDefault"/> <result column="created_user" property="createdUser"/> <result column="created_time" property="createdTime"/> <result column="modified_user" property="modifiedUser"/> <result column="modified_time" property="modifiedTime"/> </resultMap> <select id="findByAid" resultMap="AddressEntityMap"> SELECT * FROM t_address WHERE aid = #{aid} </select>
6.2 多对一映射处理
6.2.1 级联方式处理映射关系
<resultMap id="empDeptMap" type="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="sex" property="sex"></result> <result column="dept_id" property="dept.deptId"></result> <result column="dept_name" property="dept.deptName"></result> </resultMap> <!--EmpgetEmpAndDeptByEid(@Param("eid")int eid);--> <select id="getEmpAndDeptByEid" resultMap="empDeptMap"> select emp.*,dept.* from t_emp emp left join t_dept dept on emp.dept_id=dept.dept_id where emp.emp_id= #{empId} </select>
6.2.2 使用association处理映射关系
(1)association:处理多对一的映射关系(处理实体类类型的属性)
(2)property:设置需要处理映射关系的属性的属性名
(3)JavaType:设置要处理的属性的类型
<resultMap id="empDeptMap" type="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="sex" property="sex"></result> <association property="dept" javaType="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> </association> </resultMap>
6.2.3 分步查询
分步查询员工和对应的部门
@Data public class Emp{ private Integer empId; private String empName; private Integer age; private String gender; private Dept dept; }
(1)通过分步查询员工以及对应的部门信息的第一步
①EmpMapper.java
Emp getEmpAndDeptByStepOne(Integer empId);
②EmpMapper.xml
<resultMap id="empAndDeptByStepResultMap" type="Emp"> <id column="emp_id" property="empId" ></id> <result column="emp_name" property="empName" ></result> <result column="age" property="age"></result> <result column="gender" property="gender"></result> <!-- property: 设置需要处理映射关系的属性的属性名 select: 设置分步查询的sql的唯一标识 column: 将查询出的某个字段作为分步查询的sql的条件 --> <association property="dept" select="com.spring.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="dept_id"></association> </cresultMap> <select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap"> select * from t_emp where emp_id = #{empId} </select>
(2)通过分步查询员工以及对应的部门信息的第二步
①DeptMapper.java
Dept getEmpAndDeptByStepTwo(Integer deptId);
②DeptMapper.xml
<mapper namespace="com.spring.mybatis.mapper.DeptMapper"> <select id="getEmpAndDeptByStepTwo" resultType="Dept"> select * from t_dept where dept_id = #{deptId} </select> </mapper>
(3)分步查询的优点:
可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息;
①lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
②aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,
每个属性会按需加载
<settings> <!-- 开启延迟加载 --> <setting name="lazyLoadingEnabled" value="true"> <!--按需加载,默认就是false--> <setting name="aggressiveLazyLoading" value="false"> </settings>
注意:以上是全局配置,通过association和collection中的fetchType属性设置当前的分步查询是否使用
延迟加载, fetchType="lazy(延迟加载)|eager(立即加载)
6.3 一对多映射处理
一个Dept部门有多个emp员工
public class Dept { private Integer deptId; private String deptName; private List<Emp> emps; }
6.3.1 collection
<resultMap id="deptAndEmpResultMap" type="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> <collection property="emps" ofType="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="gender" property="gender"> </collection> </resultMap> <selcet id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap"> select * from t_dept left join t_emp on t_dept.dept_id = t_emp.dept_id where t_dept.dept_id = #{deptId} </select>
6.3.2 分步查询
(1)第一步
<resultMap id="deptAndEmpResultMapByStep" type="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"> <collection property="emps" select="com.spring.myatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="dept_id"></collection> </resultMap> <selcet id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep"> select * from t_dept where dept_id = #{deptId} </selcet>
(2)第二步
<select id="getDeptAndEmpByStepTwo" resultType="Emp"> select * from t_emp where dept_id = #{deptId} </select>
7.动态SQL
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了
解决 拼接SQL语句字符串时的痛点问题。
7.1 if
if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之,
标签中的内容不会执行
<!--List<Emp> getEmpListByCondition(Emp emp);--> <select id="getEmpListByMoreTJ" resultType="Emp"> select * from t_emp where 1=1 <if test="ename != '' and ename != null"> and ename = #{ename} </if> <if test="age != '' and age != null"> and age = #{age} </if> <if test="sex != '' and sex != null"> and sex = #{sex} </if> </select>
7.2 where
where和if一般结合使用:
(1)若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
(2)若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余
的and去掉
注意: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>
7.3 trim
trim用于去掉或添加标签中的内容
常用属性:
(1)prefix:在trim标签中的内容的前面添加某些内容
(2)prefixOverrides:在trim标签中的内容的前面去掉某些内容
(3)suffix:在trim标签中的内容的后面添加某些内容
(4)suffixOverrides:在trim标签中的内容的后面去掉某些内容
<select id="getEmpListByMoreTJ" resultType="Emp"> select * from t_emp <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>
7.4 choose、when、otherwise
choose、when、 otherwise相当于if…else if…else
when至少设置一个,otherwise最多设置一个
<select id="getEmpListByChoose" resultType="Emp"> select * from t_emp <where> <choose> <when test="empName != null and empName != ''"> emp_name = #{empName} </when> <when test="age != null and age != ''"> age = #{age} </when> <when test="gender != null and gender != ''"> gender = #{gender} </when> </choose> </where> </select>
7.5 foreach
(1)collection:设置要循环的数组或集合;该属性是必须指定的,在不同的情况下,该属性的值是不一样的,
主要有以下3种情况:
①如果传入的是单参数且参数类型是一个List集合的时候,collection的属性值为list
②如果传入的是单参数且参数类型是一个Array数组的时候,collection的属性值为array
③如果传入的参数是多个的时候,我们就需要把它封装成一个Map了,当然单参数也可以
(2)item:用一个字符串表示数组或集合中的每一个数据
(3)separator:设置每次循环的数据之间的分隔符
(4)open:循环的所有内容以什么开始
(5)close:循环的所有内容以什么结束
<!-- 批量添加 void insertMoreEmp(@Param("emps") List<Emp> emps); --> <insert id="insertMoreEmp"> insert into t_emp values <foreach collection="emps" item="emp" separator=","> (null,#{emp.empName},#{emp.age},#{emp.gender}) </foreach> </insert> <!-- 批量删除 void deleteMoreEmp(@Param("empIds") Integer[] empIds); --> <delete id="deleteMoreEmp"> delete from t_emp where emp_id in <foreach collection="empIds" item="empId" separator=",",open="(",close=")"> #{empId} </foreach> </delete>
7.6 SQL片段
sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
<sql id="empColumns"> eid,ename,age,sex,did </sql> select <include refid="empColumns"></include> from t_emp
8.MyBatis的缓存
8.1 MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就
会从缓存中直接获取,不会从数据库重新访问。一级缓存默认是开启的
使一级缓存失效的四种情况:
(1) 不同的SqlSession对应不同的一级缓存
(2) 同一个SqlSession但是查询条件不同
(3) 同一个SqlSession两次查询期间执行了任何一次增删改操作
(4) 同一个SqlSession两次查询期间手动清空了缓存
SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.clearCache();
8.2 MyBatis的二级缓存
(1)二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被
缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
(2)二级缓存开启的条件:
①在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
②在映射文件中设置标签
③二级缓存必须在SqlSession关闭或提交之后有效
④查询的数据所转换的实体类类型必须实现序列化的接口
(3)使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
8.3 二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置一些属性:
(1)eviction属性:缓存回收策略,默认的是 LRU。
①LRU(Least Recently Used)最近最少使用的:移除最长时间不被使用的对象。
②FIFO(First in First out)先进先出:按对象进入缓存的顺序来移除它们。
③SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
④WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
(2)flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
(3)size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出
(4)readOnly属性:只读,true/false
①true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重
要的性能优势。
②false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
8.4 MyBatis缓存查询的顺序
(1)先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
(2)如果二级缓存没有命中,再查询一级缓存
(3)如果一级缓存也没有命中,则查询数据库
(4)SqlSession关闭之后,一级缓存中的数据才会写入二级缓存
9、MyBatis的逆向工程
(1)正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向
工程的。
(2)逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
①Java实体类
②Mapper接口
③Mapper映射文件
(3) 创建步骤
①添加依赖和插件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.atmybatis</groupId> <artifactId>mybatis_hpu</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <!-- 依赖MyBatis核心包 --> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- log4j日志 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies> <!-- 控制Maven在构建过程中相关配置 --> <build> <!-- 构建过程中用到的插件 --> <plugins> <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.0</version> <!-- 插件的依赖 --> <dependencies> <!-- 逆向工程的核心依赖 --> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.2</version> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
②创建逆向工程的配置文件(文件名必须是: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/hnlg? serverTimezone=UTC" userId="root" password="root"> </jdbcConnection> <!-- javaBean的生成策略--> <javaModelGenerator targetPackage="com.ssm.mybatis.pojo" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- SQL映射文件的生成策略 --> <sqlMapGenerator targetPackage="com.ssm.mybatis.mapper" targetProject=".\src\main\resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- Mapper接口的生成策略 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.ssm.mybatis.mapper" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- 逆向分析的表 --> <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName --> <!-- domainObjectName属性指定生成出来的实体类的类名 --> <table tableName="emp" domainObjectName="Emp"/> <table tableName="dept" domainObjectName="Dept"/> <table tableName="student" domainObjectName="Student"/> <table tableName="t_clazz" domainObjectName="Clazz"/> <table tableName="t_user" domainObjectName="User"/> <!-- <table tableName="*"/>--> </context> </generatorConfiguration>
10、分页插件
10.1 分页插件的使用步骤
(1)添加依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>
(2)配置分页插件(在MyBatis的核心配置文件中配置插件)
<plugins> <!--设置分页插件--> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins
10.2 分页插件的使用
(1)在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能
Page<Object> page = PageHelper.startPage(1,4);
①pageNum:当前页的页码
②pageSize:每页显示的条数
(2)在查询获取list集合之后,使用
PageInfo pageInfo = new PageInfo<>(List list, int navigatePages)获取分页相关数据
①list:分页之后的数据
②navigatePages:导航分页的页码数
(3)分页相关数据
PageInfo{
pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8,
list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30,
pages=8, reasonable=false, pageSizeZero=false},
prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,
hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8,
navigatepageNums=[4, 5, 6, 7, 8]
}
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]