zhuduo  

1.什么是MyBatis?

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

2.MyBatis主要完成什么样的任务?

1.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old JavaObjects,普通的Java对象)映射成数据库中的记录

2.定制化SQL语句,定制化高级映射

3.MyBatis配置文件的主要内容

1.配置文件:

  • pom.xml项目总的配置文件:用于存放整个项目总体的驱动

  • mybatis-config.xml 是mybatis的配置文件:用于配置mybatis框架所需的信息,以包的方式引入mapper映射文件,但是必须满足两个条件: 1、mapper接口和映射文件所在的包必须一致 2、mapper接口的名字和映射文件的名字必须一致

  • UserMapper.xml是映射文件:用于编写sql语句,并且访问操作表中数据;一个映射文件对应一个实体类,对应一张表的操作

  • java概念数据库概念
    属性 字段
    对象 记录

2.mybatis配置文件中的标签:

  • MyBatis核心配置文件中的标签必须要按照指定的顺序配置:

      properties?,settings?,typeAliases?,typeHandlers?,
      objectFactory?,objectWrapperFactory?,reflectorFactory?,
      plugins?,environments?,databaseIdProvider?,mappers?
  • <!--引入properties文件,此后就可以在当前文件中使用${key}的方式访问value-->

     <properties resource="jdbc.properties" />
  • 设置别名

     <!--
     typeAliases:设置类型别名,即为某个具体的类型设置一个别名
     在MyBatis的范围中,就可以使用别名表示一个具体的类型

    --> <!-- type:设置需要起别名的类型 alias:设置某个类型的别名 --> <!--<typeAlias type="com.atguigu.mybatis.pojo.User" alias="abc"></typeAlias>--> <!--若不设置alias,当前的类型拥有默认的别名,即类名且不区分大小写--> <!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>--> <!--通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写-->

     <typeAliases>
     <package name="com.rensiyv.mybatis.pojo"/>
     </typeAliases>
     **作用:简化代码,见名知意**
  • 配置连接数据库的环境 <!-- 设置一个具体的连接数据库的环境 id:设置环境的唯一标识,不能重复 -->

    <!-- 任务管理器:设置任务管理方式 数据源:数据库连接类型 属性: type:设置事务管理方式 type=“JDBC/MANAGED” JDBC:表示使用JDBC中原生的事务管理方式:可以自动提交、回滚事务,也可以采用sqlsession中的方法手动回滚事务 MANAGED:被管理,例如Spring中的IOC和AOP-->

    <!-- dataSource:设置数据源 属性: type:设置数据源的类型 type="POOLED|UNPOOLED|JNDI" POOLED:表示使用数据库连接池 UNPOOLED:表示不使用数据库连接池 JNDI:表示使用上下文中的数据源 -->

     <environments default="development">
        <environment id="development">          
      <transactionManager type="JDBC"/>            
      <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>

    需要再创建一个jdbc.properties 文件作为连接数据库的驱动,注意文件前缀,用于区分多种properties文件。

4.MyBatis运行的主要原理

  • 测试类去调用mapper接口中的方法,mapper接口中的方法含有参数,由于mapper映射文件与mapper接口有着对应关系,并且映射文件需要获取接口方法中的参数,所以映射文件用${}和#{}两种方式去获取接口中的参数,然后再通过配置文件中的sql语句完成操作数据库的工作;返回值在接口方法和测试方法中,例如:User,值唯一。

  • SqlSession对象如何创建:SqlSessionFactoryBuilder调用build()方法得到SqlSessionFactory实例,SqlSessionFactory是SqlSession对象的工厂,通过openSession方法得到SqlSession实例,SqlSession 的作用有 3 个:

    • 获取 Mapper 接口。

    • 发送 SQL 给数据库。

    • 控制数据库事务。

    SqlSession 是应用程序与持久存储层之间执行交互操作的一个单线程对象,也是 Mybatis 执行持久化操作的关键对象。SqlSession 对象完全包含以数据库为背景的所有执行 SQL 操作的方法,它的底层封装了 JDBC 连接,可以用 SqlSession 实例来直接执行已映射的 SQL 语句。每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不能被共享,也是线程不安全的,绝对不能将 SqlSession 实例的引用放在一个类的静态字段甚至是实力字段中。也绝不能将 SqlSession 市里的引用放在任何类型的管理范围中,比如 Servlet 当中的 HttpSession 对象中。使用 SqlSession 之后关闭 Session 很重要,应该确保使用 finally 块来关闭它。

    SqlSessionFactory 是线程安全的,一旦被创建,应该在应用执行期间都存在。在应用运行期间不要重复创建多次,建议使用单例模式。

5.如何创建文件模板

创建文件模板

  • setting-->editor-->file and code templates-->file-->+

  • 注意此时创建的名称是模板名称,而不是将来实际创建的文件名称。

6.MyBatis获取参数值的两种情况

6.1MyBatis获取参数值的两种方式:${}#{}

#{}的本质就是占位符赋值,${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单

引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。

一般情况下我们使用#{}的方式获取数值,因为比较简便,但是某些情况下必须使用${},防止SQL注入,使用${}时务必添加单引号。

6.2把获取参数值归纳为两种情况

  • 第一种情况,实体类型参数,通过属性名获取属性值:若mapper接口中的方法参数为实体类对象时,可以使用${}和#{},通过访问实体类对象中的属性名获取属性值

  • 第二种情况,单个、多个字面量类型以及map集合类型的参数,最好统一使用@Param注解标识参数,方便手动设置键值,此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;或者以param1,param2...为键,以参数为值

6.3理清属性的概念

属性:get、set方法中,去掉get、set首字母小写才是属性,属性和参数并不完全相同。属性可以独立于成员变量而存在,大部分情况下属性由成员变量创建,这种情况下两者名称相同,但是本质并不相同。

7.MyBatis各种查询功能

由于用户使用过程中会有多种查询情况,查询结果的不同就导致返回结果的不同,大致有以下几种情况:

  • 查询结果为一条实体类数据或查询一条数据为map集合

  • 查询结果为一条单个数据

  • 查询结果为多条数据

以上情况三种情况,最大的不同之处在于返回值不同,除此之外,查询多条数据时有两种不同的方法:

1.每条数据查询为一个map集合,多条map集合放置在一个list集合中。

2..每条数据查询为一个map集合,多条map集合放置在一个map集合中,此时需要自己设置键,属性值为每条map数据。

若属性值为null,结果则不显示。

8.特殊sql语句的实现

8.1模糊查询

通过此代码

 <!--List<User> getUserByLike(@Param("mohu") String mohu);-->
    <select id="getUserByLike" 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>

主要了解到在少部分sql语句中,用#{}传递参数会报错,这时候主要采用${}传递参数

报错原因:#{}相当于占位符?,由于在单引号中,识别过程中不会被识别成占位符,而是?

8.2批量删除功能

 <!--    void deleteMoreUser(@Param("ids") String ids);-->
    <delete id="deleteMoreUser">
        delete from t_user where id in(${ids})
    </delete>

8.3动态设置表名

<!--List<User> getUserList(@Param("tableName") String tableName);-->
    <select id="getUserList" resultType="User">
        select * from ${tableName}
    </select>

只能使用${}传递参数

8.4获取自增的主键并添加用户信息

1.Test方法

public void testJDBC(){
        try {
            Class.forName("");
            Connection connection = DriverManager.getConnection("","","");
                /*String sql = "select * from t_user where username like '%?%'";
                PreparedStatement ps = connection.prepareStatement(sql);*/
                //ps.setString(1, "a");
            String sql = "insert into t_user values()";
		//预编译对象
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        //增删改
            ps.executeUpdate();
            ResultSet resultSet = ps.getGeneratedKeys();
		//将结果集指针指向当前数据
            resultSet.next();
		//当前自动递增的主键
            int id = resultSet.getInt(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.接口方法

/**
     * 添加用户信息并获取自增的主键
     * @param user
 */
    void insertUser(User user);

3.配置文件

<!--void insertUser(User user);--> <!-- useGeneratedKeys:表示当前添加功能使用自增的主键 keyProperty:将添加的数据的自增主键为实体类类型的参数的属性赋值 -->

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into t_user values(null,#{username},#{password},#{age},#{gender},#{email})
    </insert>

应用场景:实时获取自增的主键,并将其用于其它的sql语句的操作中

9.更高级的映射方式

当我们进行更加复杂的多表查询时,有一个问题是不可避免的,那就是字段名与属性名的匹配问题。

在实际开发过程中,表中的字段名使用下划线命名,而属性名在类中使用的是驼峰命名法,这两种情况势必无法匹配,为了解决这一问题,有以下两种方式

  • 此时可以在MyBatis的核心配置文件中设置一个mapUnderscoreToCamelCase全局配置,可以自动将下划线映射为驼峰,例如: emp_id:empId;emp_name : empName

  • 或者在mapper.xml文件中使用resultMap标签取别名来自定义映射:

    <resultMap id="empAndDeptResultMapOne" 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>
            <result column="dept_id" property="dept.deptId"></result>
            <result column="dept_name" property="dept.deptName"></result>
        </resultMap>

多表查询中,存在多对一或一对多的映射关系,此时查询出的一条数据中的某些字段,必然无法对应某返回类型的属性。因为一个类对应一个实体类对象,实体类对象中的属性对应一张表中的字段,而两张表查询出来的数据是拼接起来的,必然不对应一个完整的实体类对象,也就无法全部对应类中的属性。

<!-- 字段名和属性名不一致的情况,如何处理映射关系 1、为查询的字段设置别名,和属性名保持一致 2、当字段符合MySQL的要求使用_,而属性符合java的要求使用驼峰 此时可以在MyBatis的核心配置文件中设置一个全局配置,可以自动将下划线映射为驼峰 emp_id:empId,emp_name:empName 3、使用resultMap自定义映射处理 处理多对一的映射关系: 1、级联方式处理 2、association 3、分步查询

处理一对多的映射关系: ​ 1、collection ​ 2、分步查询 -->

<!-- resultMap:设置自定义的映射关系 id:唯一标识 type:处理映射关系的实体类的类型 常用的标签: id:处理主键和实体类中属性的映射关系 result:处理普通字段和实体类中属性的映射关系 association:处理多对一的映射关系(处理实体类类型的属性) collection:处理一对多的映射关系(处理集合类型的属性) column:设置映射关系中的字段名,必须是sql查询出的某个字段 property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名 -->

9.1为了解决上述问题中的多对一问题,有三种方法:

9.1.1级联方式处理映射
<resultMap id="empAndDeptResultMapOne" 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>
        <result column="dept_id" property="dept.deptId"></result>
        <result column="dept_name" property="dept.deptName"></result>
    </resultMap>

 

9.1.2association标签处理映射
<resultMap id="empAndDeptResultMap" 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>
        <!--
            association:处理多对一的映射关系(处理实体类类型的属性)
            property:设置需要处理映射关系的属性的属性名
            javaType:设置要处理的属性的类型
        -->
        <association property="dept" javaType="Dept">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"></result>
        </association>
    </resultMap>

 

9.1.3分步式处理映射(两张表)

第一步:查询员工信息

EmpMapper

Emp getEmpAndDeptByStepOne(@Param("empId") 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的条件
            fetchType:在开启了延迟加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载
            fetchType="eager(立即加载)|lazy(延迟加载)"
        -->
        <association property="dept" fetchType="eager"
                     select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                     column="dept_id"></association>
    </resultMap>

    <!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
    <select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
        select * from t_emp where emp_id = #{empId}
    </select>

第二步:根据员工所对应的部门id查询部门信息

DeptMapper

/**
     * 通过分步查询查询员工以及所对应的部门信息的第二步
     * @return
     */
    Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);

DeptMapper.xml

<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
    <select id="getEmpAndDeptByStepTwo" resultType="Dept">
        select * from t_dept where dept_id = #{deptId}
    </select>

9.2解决一对多问题的两种方法:

9.2.1collection标签:
<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"></result>
        </collection>
    </resultMap>
<!--    Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);-->
    <select 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>

与多对一的association标签十分类似,但是其中的JavaType属性要变成ofType

9.2.2分布式

与多对一的分布式方法类似,注意对应关系。

9.3延迟加载

在config.xml 中添加两个全局配置标签,针对分布查询时是否只运行一个语句

<!--开启延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <!--按需加载--> <setting name="aggressiveLazyLoading" value="false"/>

某一个分布查询的sql语句单独设置立即加载或延迟加载的情况:

association中添加fetchType标签

10.动态sql

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题。

动态拼装SQL指的是用户使用多个条件查询语句时,mybatis将这多个条件拼装到一条SQL语句达到查询或别的目的。这就导致在拼装过程中、条件的空与非空等方面出现问题,Mybatis框架的动态SQL技术就是为了解决这些问题。

<!-- 动态SQL: 1、if,通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中) 2、where a.若where标签中有条件成立,会自动生成where关键字 b.会自动将where标签中内容前多余的and去掉,但是其中内容后多余的and无法去掉 c.若where标签中没有任何一个条件成立,则where没有任何功能 3、trim prefix、suffix:在标签中内容前面或后面添加指定内容 prefixOverrides、suffixOverrides:在标签中内容前面或后面去掉指定内容 4、choose、when、otherwise 相当于java中的if...else if...else when至少设置一个,otherwise最多设置一个 5、foreach collection:设置要循环的数组或集合 item:用一个字符串表示数组或集合中的每一个数据 separator:设置每次循环的数据之间的分隔符 open:循环的所有内容以什么开始 close:循环的所有内容以什么结束 6、sql片段 可以记录一段sql,在需要用的地方使用include标签进行引用 <sql id="empColumns"> emp_id,emp_name,age,gender,dept_id </sql> <include refid="empColumns"></include> -->

示例代码:

trim标签prefix属性在内容之前添加where,suffixOverrides属性去掉末尾可能冗余的and

if判断空与非空,是否加入判断

<trim prefix="where" suffixOverrides="and">
            <if test="empName != null and empName != ''">
                emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
</trim>

10.1where标签解决

<where>
            <if test="empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age != ''">
                and age = #{age}
            </if>
            <if test="gender != null and gender != ''">
                and gender = #{gender}
            </if>
</where>

10.2where标签解决标签内容一开始有and

select * from t_emp where 1=1
        <if test="empName != null and empName != ''">
            and emp_name = #{empName}
        </if>
        <if test="age != null and age != ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender != ''">
            and gender = #{gender}
        </if>

10.3choose标签,只要有任一条件成立就可以查询

<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>

10.4foreach标签批量添加,注意括号,注意参数

<insert id="insertMoreEmp">
        insert into t_emp values
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>
    </insert>

10.5foreach标签批量删除,可以用open,close属性决定括号,或者separator属性用or来实现批量删除

<delete id="deleteMoreEmp">
        <!--delete from t_emp where emp_id in
        <foreach collection="empIds" item="empId" separator="," open="(" close=")">
            #{empId}
        </foreach>-->
        delete from t_emp where
        <foreach collection="empIds" item="empId" separator="or">
            emp_id = #{empId}
        </foreach>
    </delete>

10.6sql标签,在需要的位置插入提前设置好的sql片段

<sql id="empColumns">

eid,ename,age,sex,did

</sql>

select <include refid="empColumns"></include> from t_emp

11.MyBatisd的缓存

一级缓存

一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问

一级缓存在mybatis中是默认生效的
使一级缓存失效的四种情况:
  • 不同的SqlSession对应不同的一级缓存

  • 同一个SqlSession但是查询条件不同

  • 同一个SqlSession两次查询期间执行了任何一次增删改操作

  • 同一个SqlSession两次查询期间手动清空了缓存

二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被

缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

二级缓存开启的条件:
  • a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置

  • b>在映射文件中设置标签<cache/>

  • c>二级缓存必须在SqlSession关闭或提交之后有效

  • d>查询的数据所转换的实体类类型必须实现序列化的接口

使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

 

映射文件

<cache type="org.mybatis.caches.ehcache.EhcacheCache" />

测试

@Test
    public void testCache() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
        CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
        Emp emp1 = mapper1.getEmpById(1);
        System.out.println(emp1);
        sqlSession1.close();
        SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        Emp emp2 = mapper2.getEmpById(1);
        System.out.println(emp2);
        sqlSession2.close();
    }
MyBatis缓存查询的顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。

如果二级缓存没有命中,再查询一级缓存

如果一级缓存也没有命中,则查询数据库

SqlSession关闭之后,一级缓存中的数据会写入二级缓存

12.整合第三方缓存EHCache

13.MyBatis的逆向工程

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工程的。

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

  • Java实体类

  • Mapper接口

  • Mapper映射文件

创建逆向工程的步骤

1.添加依赖和插件
<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>
2.创建mybatis核心配置文件
3.创建逆向工程的配置文件

文件名必须是:generatorConfig.xml

</build>

<?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/mybatis?

serverTimezone=UTC"

userId="root"

password="123456">

</jdbcConnection>

<!-- javaBean的生成策略-->

<javaModelGenerator targetPackage="com.atguigu.mybatis.pojo"

targetProject=".\src\main\java">

<property name="enableSubPackages" value="true" />

<property name="trimStrings" value="true" />

</javaModelGenerator>

<!-- SQL映射文件的生成策略 -->

<sqlMapGenerator targetPackage="com.atguigu.mybatis.mapper"

targetProject=".\src\main\resources">

<property name="enableSubPackages" value="true" />

</sqlMapGenerator>

<!-- Mapper接口的生成策略 -->

<javaClientGenerator type="XMLMAPPER"

targetPackage="com.atguigu.mybatis.mapper" targetProject=".\src\main\java">

<property name="enableSubPackages" value="true" />

</javaClientGenerator>

<!-- 逆向分析的表 -->

<!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->

<!-- domainObjectName属性指定生成出来的实体类的类名 -->

<table tableName="t_emp" domainObjectName="Emp"/>

<table tableName="t_dept" domainObjectName="Dept"/>

</context>

</generatorConfiguration>
4.在maven插件中执行mybatis-generation插件

14.分页功能

由于分页功能实现过于繁琐,所以在mybatis中可以使用分页插件来简化操作,插件主要帮我们自动获取了大量数据,还提供了许多方法供开发者使用。

属性:

limit index,pageSize

pageSize:每页显示的条数

pageNum:当前页的页码

index:当前页的起始索引,index=(pageNum-1)*pageSize

count:总记录数

totalPage:总页数

totalPage = count / pageSize;

if(count % pageSize != 0){

totalPage += 1;

}

pageSize=4,pageNum=1,index=0 limit 0,4

pageSize=4,pageNum=3,index=8 limit 8,4

pageSize=4,pageNum=6,index=20 limit 8,

分页插件的使用步骤

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>
3.分页插件的使用

(1)在查询功能之前使用

PageHelper.startPage(int pageNum, int pageSize)

开启分页功能

pageNum:当前页的页码

pageSize:每页显示的条数

(2)在查询获取list集合之后,使用

PageInfo<T> pageInfo = new PageInfo<>(List<T> list, intnavigatePages)

获取分页相关数据

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]

 

 

 

 

 

 

 

 

 

 

posted on 2023-01-18 14:36  烛夺  阅读(60)  评论(0)    收藏  举报