MyBatis

作者: Roct | 来源:发表于2019-08-13 23:11 被阅读0次

    MyBatis概述

    • ORM(Object Relational Mapping)持久层框架的佼佼者
    • 真正实现了SQL语句与Java代码的分离
    • 优秀的功能 动态SQL, 缓存, 插件-pageHelper等

    Mybatis入参处理

    • 单参数Mybatis不做特殊处理, 直接取出参数赋值给xml文件, 如:#{id}, 当传递的为单参数的时候#{xxx}, Mybatis不会关心名称.
    • 多参数
      • 默认传递为多参数的时候, Mybatis会将参数起名为: arg0, arg1, param1, param2
      • JavaBean传递参数
        • 如果多个参数是业务逻辑的数据模型, 那么可以直接传入pojo
        • Xml文件中直接通过#{属性名}取出对应的值
      • Map接口
        • 如果参数个数比较少, 而且没有对应的Javabea n, 可以封装成Map
        • Xml文件中: #{key}取出map中对应的值
      • 注解@param
        public Person getPersonInfo(@Param("username") String username, @Param("id") Integer id);
        
        如果多个参数只使用了一个@Param, 那么Mybatis会自动启用默认的规则, 即第二个参数为Param1
    • 集合类型参数处理
      • 当参数为Collection接口, 转换为Map, Mapkeycollection
      public Person getPersonByCollection(Collection list);
      
      <select id="getPersonByCollection" resultType="person">
          select * from person where id=#{list[0]}
      </select>
      
      • 如果参数类型为List接口, 除了collection以外, list也可以作为key
      public Person getPersonByCollection(List list);
      
      <select id="getPersonByCollection" resultType="person">
          select * from person where id=#{list[0]}
      </select>
      
      • 如果参数为数组, 也会转换为Map, Mapkeyarray
      public Person getPersonByArray(int[] ids);
      
      <select id="getPersonByArray" resultType="person">
          select * from person where id=#{array[0]}
      </select>
      
      • 以上均可以使用param来处理
      public Person getPersonByArray(@Param("idsc") int[] ids);
      
      <select id="getPersonByArray" resultType="person">
          select * from person where id=#{idsc[0]}
      </select>
      
    • Mybatis动态SQLforeach
      • 特点
        循环遍历集合, 支持数组和List, Set接口, 对其提供遍历功能
      • 常用配置
        • collection: 需要遍历的集合
        • item: 当前集合的对象
        • index: 当前遍历的对象的索引
        • openclose: 当前打开和关闭的字符串
        • separator: 每个元素的分割符
      • 代码示例
      // 根据传入的id的数组, 查询id在数组里的用户, 返回一个List列表
      <select id="getPersonListByIds" resultType="person">
          select * from person where id in
          <foreach collection="array" item="item" index="i" open="(" close=")"  separator=",">
              #{item}
          </foreach>
      </select>
      

    Mybatis批量插入数据

    • 借助foreach标签使用insert into table values()
     // 根据传入的id的数组, 查询id在数组里的用户, 返回一个List列表
     <insert id="addPersons">
         insert into person(username, email, gender) values
         <foreach collection="persons" item="item" index="i"   separator=",">
             (#{item.username}, #{item.email}, #{item.gender})
         </foreach>
     </insert >
    
    • 借助ExecutorBatch批量添加, 可与Spring框架整合

    Mybatis拦截器与分页

    • Mybatis四大对象
      • ParamterHandler: 处理SQL的参数对象
      • ResultSetHandler: 处理SQL的返回结果集
      • StatementHandler: 数据库的处理对象, 用于执行SQL
      • Executor: Mybatis的执行器, 用于执行增删改查
    • Mybatis插件原理
      • Mybatis的插件借助于责任链的模式进行对拦截的处理
      • 使用动态代理对目标对象进行包装, 达到拦截的目的
      • 作用于Mybatis的作用于对象之上
    • Interceptor
    // 拦截目标对象的目标方法
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("拦截的目标对象" + invocation.getTarget());
        Object object = invocation.proceed();
        return object;
    }
    // 包装目标对象, 为目标对象创建代理对象的
    public Object plugin(Object o) {
        System.out.println("将要包装的目标对象" + o);
        return Plugin.wrap(o, this);
    }
    // 设置属性, 在配置文件中声明拦截器, 初始化的属性
    public void setProperties(Properties properties) {
          System.out.println("插件配置的初始化参数" + properties);
    }
    
    • 分页
      • 分页的分类: 内存分页和物理分页
      • Mysql自带的Limit关键字
    • PageHelper
    // 获取第一页 数量为10个
    Page<Object> page = PageHelper.startPage(1, 10);
    // 从数据库进行查询
    List<Person> persons = personMapper.getAllPersons();
    // 获取导航页面, 经常用于页面底部显示导航123....10页
    PageInfo pageInfo = new PageInfo(persons, navigatePages: 9)
    
    page.getPageNum(); // 获取当前的页面
    page.getTotal(); // 获取总共多少页
    page.getPageSize; // 获取一页有多少数量
    
    pageInfo.isIsFirstPage(); // 是否是第一页
    pageInfo.getPages(); // 总共多少页
    // PageInfo pageInfo = new PageInfo(persons, navigatePages: 9) 输出nums为1, 2, 3,4,5,6,7,8,9
    int [] nums = pageInfo.getNavigatepageNums(); // 获取页面
    
    
    • Mybatis分页应用
    public ServerResponse getProductList(int pageNum, int pageSize) {
            // mybatis pageHelper的使用
            // 1. startPage->start
            PageHelper.startPage(pageNum, pageSize);
            // 2. 填充sql查询逻辑
            List<Product> productList = productMapper.selectProductList();
            List<ProductListVo> productListVos = new ArrayList<ProductListVo>();
            for (Product product : productList) {
                ProductListVo productListVo = assembleProduct(product);
                productListVos.add(productListVo);
            }
            // 3. pageHelper->收尾
            PageInfo pageResult = new PageInfo(productList);
            pageResult.setList(productListVos);
            return ServerResponse.createBySuccess(pageResult);
        }
    

    Mybaitis自动生成Mapper映射文件和dao层实体类

    1. 在pom.xml文件里新增Mybatis的generator

      <build>
        <finalName>项目名</finalName>
        <plugins>
          <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.2</version>
            <configuration>
              <verbose>true</verbose>
              <overwrite>true</overwrite>
            </configuration>
          </plugin>
        </build>
    

    2.在resources包下面添加generator.properties和generatorConfig.xml, 其中generator.properties是数据库配置文件

    generator.properties
    db.initialSize = 20
    db.maxActive = 50
    db.maxIdle = 20
    db.minIdle = 10
    db.maxWait = 10
    db.defaultAutoCommit = true
    db.minEvictableIdleTimeMillis = 3600000
    
    db.driverLocation=/Volumes/ruirui/mysql-connector/mysql-connector-java-5.0
     .8-bin.jar // 不能有中文路径
    db.driverClassName=com.mysql.jdbc.Driver
    db.url=jdbc:mysql://localhost:3306/bos?characterEncoding=utf-8
    db.username=root
    db.password=root
    
    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>
        <!--导入属性配置-->
        <properties resource="generator.properties"/>
    
        <!--指定特定数据库的jdbc驱动jar包的位置-->
        <classPathEntry location="${db.driverLocation}"/>
    
        <context id="default" targetRuntime="MyBatis3">
    
            <!-- optional,旨在创建class时,对注释进行控制 -->
            <commentGenerator>
                <property name="suppressDate" value="true"/>
                <property name="suppressAllComments" value="true"/>
            </commentGenerator>
    
            <!--jdbc的数据库连接 -->
            <jdbcConnection
                    driverClass="${db.driverClassName}"
                    connectionURL="${db.url}"
                    userId="${db.username}"
                    password="${db.password}">
            </jdbcConnection>
    
    
            <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
    
            <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
                targetPackage     指定生成的model生成所在的包名
                targetProject     指定在该项目下所在的路径
            -->
            <!--<javaModelGenerator targetPackage="com.mmall.pojo" targetProject=".\src\main\java">-->
            <javaModelGenerator targetPackage="com.mmall.pojo" targetProject="./src/main/java">
                <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
                <property name="enableSubPackages" value="false"/>
                <!-- 是否对model添加 构造函数 -->
                <property name="constructorBased" value="true"/>
                <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
                <property name="trimStrings" value="true"/>
                <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
                <property name="immutable" value="false"/>
            </javaModelGenerator>
    
            <!--mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
            <!--<sqlMapGenerator targetPackage="mappers" targetProject=".\src\main\resources">-->
            <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
                <property name="enableSubPackages" value="false"/>
            </sqlMapGenerator>
    
            <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
                    type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
                    type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
                    type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
            -->
    
            <!-- targetPackage:mapper接口dao生成的位置 -->
            <!--<javaClientGenerator type="XMLMAPPER" targetPackage="com.mmall.dao" targetProject=".\src\main\java">-->
            <javaClientGenerator type="XMLMAPPER" targetPackage="com.mmall.dao" targetProject="./src/main/java">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
    
    
            <!-- tableName:数据库表名 -->
            <!-- domainObjectName:对应于数据库表的javaBean类名即pojo -->
            <!-- columnOverride :重新设置该属性, 在本案例中, 设置格式为VARCHAR; -->
            <table tableName="mmall_product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
                <columnOverride column="detail" jdbcType="VARCHAR" />
                <columnOverride column="sub_images" jdbcType="VARCHAR" />
            </table>
            <table tableName="mmall_user" domainObjectName="User"
                   enableCountByExample="false" enableUpdateByExample="false"
                   enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
        </context>
    </generatorConfiguration>
    

    3. 自动生成

    点击左边栏的Maven, 如果没有点击View=>Tool Window=> Maven


    Mybatis自动生成

    有一个哥们私聊我, 在项目进行到一半, 如何自动生成新的pojo和mapper, 只需要将其他的注释掉, 仅保留需要生成的部分代码即可.

    MyBatis工作原理与工作流程

    MyBatis工作原理与工作流程
    • sql语句和数据库配置信息保存在配置文件中
    • Mybatis运行的时候, 将配置信息存储在Configuration对象里
    • 在创建SqlSession对象提供属性
      • Configuration对象
      • dirty: true sql语句执行完毕以后 可以事务提交
        false sql语句执行发送错误 事务进行回滚
      • Executor执行器对象:
        • 创建Statement对象,在创建过程中依靠MapperStatement对象赋值内容与sql占位符进行绑定
    • SqlSession.commit(): 根据此时dirty属性决定提交和回滚
    • SqlSession.close()

    相关文章

      网友评论

          本文标题:MyBatis

          本文链接:https://www.haomeiwen.com/subject/yagijctx.html