Mybatis

Mybatis

  • ORM ,持久层框架
  • 支持定制化 SQL、存储过程和高级映射
  • 在 Spring 中使用 MyBatis
    • mybatis-spring-boot-starter
    • MyBatis Spring Adapter

可以使Mybatis更好用的工具

  • Mybatis Generator
    • MyBatis 官方提供的代码生成器
    • 根据数据库表生成相关代码
      • POJO
      • Mapper 接口
      • SQL Map XML
    • 一些内嵌子工具
  • Mybatis PageHelper
    • 帮助更好的处理分页的
    • 支持多种数据库
    • 支持多种分页形式
    • pagehelper-spring-boot-starter

注意:如果既要使用组件自动生成的部分,又需要对它做一个手动的微调

把手动处理的部分和自动生成的部分放在不同的位置

有两套model,mapper,xml,这样下次自动生成时就会仅覆盖自动成的部分,不会干扰手动处理的部分

尽管Mybatis Genertor有合并的逻辑,但是并不是很靠谱。

Mapper 的定义与扫描

  • @MapperScan 配置扫描位置
    • 使用 Java Config 时使用此注解注册 MyBatis mapper interfaces。
  • @Mapper 定义接口
  • DAO 层的定义方法,有两种
    • mapper interface + SQL XML,扫描xml 文件
    • 带有SQL注解 的 mapper interface

insert, update, delete 语句返回的结果与 数据库执行时一样,是受影响条数。

20210901

整体学习前的杂记

  1. insert 语句中 插入的字段名使用表中的字段名,values 对应的名字使用 java Model 中的字段名,
  2. selectKey 的作用是什么?
  3. selectByExample 中的 example 是什么意思?
  4. insert 与 insertSelective 有什么区别?

Mybatis Generator

到官网查看详细内容

主要功能:

  • 用来生成简单的 CRUD (Create, Retrieve, Update, Delete) 代码,
  • 不过仍然需要为连接查询或存储过程编写 SQL 和对象代码。

目标:

  • 掌握如何开箱配置,运行,如何与代码整合一起使用,可以正常打包即可;
  • 更高级用法,等有需要时再去查官方文档即可;

配置 MyBatis Generator

  1. 配置文件要命名为 generatorConfig.xml

  2. 在 IDEA 中配置时,只要提供了 XML 文件的 DOCTYPE 头信息,涉及的标签就会有自动提示和补全,很方便(可以先抄一个官方文档的例子,然后修改)。

  3. xml 配置文件提供哪些信息?

    • 如何连接到数据库
    • 要生成什么对象,以及如何生成它们
    • 应该使用哪些表来生成对象
    • java model class
    • SQL map XML files (可选)
  4. 注意,配置内容是有顺序的,

    1. 配置plugin
    2. 配置 jdbcConnection
    3. 配置 javaModelGenerator
    4. 。。。。
  5. 需要注意的两个重要参数:

    • targetProject ,必须是一个已存在的目录,如果不存在则报错,
    • targetPackage ,是 targetProject 属性的子目录,如果不存在 MBG 会自动创建
      • targetProject + targetPackage = 生成的代码最终存放的位置
  6. xml 配置文件中,有两种属性,

    • attribute ,这是<> 标签内部的属性,例如: ,这些都写在标签内部。多个attribute 之间用 空格 分割;

    • property ,这个属性类似于标签的子元素,例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <javaModelGenerator targetPackage="test.model" targetProject="\MyProject\src">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
      </javaModelGenerator>

      上面的例子中,分别表现了两种不同的属性的写法。
      1. targetPackage,targetProject 都属于 attribute;
      2. property 子元素有两个,而 name ,value 都属于 property 的 attribute
      3. <> 标签 ,当子元素时,是成对出现的 <a></a> ; 当没有子元素时,是可以单独使用的 <property/>

一些常用元素

  • ,是 generatorConfiguration.xml 配置文件的 root element 即根元素。

    • 可用的子元素如下:

    • [](# [<properties> ](# 一些常用元素)) (0 or 1)

    • (0..N)

    • [](# [<context>](# 一些常用元素)) (1..N)

      • [](# [<property>](# 一些常用元素)) (0..N)
      • [](# [](# 一些常用元素)) (0..N)
      • [](# [](# 一些常用元素)) (0 or 1)
      • [](# [](# 一些常用元素)) (either connectionFactory or jdbcConnection is Required)
      • [](# [](# 一些常用元素)) (either connectionFactory or jdbcConnection is Required)
      • [](# [](# 一些常用元素)) (0 or 1)
      • [](# [](# 一些常用元素)) (1 Required)
      • [](# [<sqlMapGenerator>](# 一些常用元素)) (0 or 1)
      • [](# [](# 一些常用元素)) (0 or 1)
      • [](# [](# 一些常用元素)) (1..N)

        下面是一些元素的解释和样例:

        [<properties> ](# 一些常用元素)

        用于指定外部properties 文件,该文件中的 property 可以用在 xml配置文件中,通过 ${property},属性占位符

        1
        2
        3
        4
        5
        6
        使用时,两个 attribute 二选一,
        1. resource, 在类路径中搜索指定的文件;
        2. url ,在文件系统中搜索指定的文件,给定 file:///C:/myfolder/generatorConfig.properties

        例如:
        <properties resource="generator.properties"/>

        [<context>](# 一些常用元素)

        的子元素,生成代码的核心配置都在里面,例如连接什么数据库,生成什么对象,怎么生成,需要用到什么表等。如果需要连接多个不同的数据库,可以添加多个 元素对。

        • id ,是必须的 attribute,用作唯一标识符

        • 一些可选属性 attribute

        • defaultModelType,模型类型,用于定义如何将表结构生成 domain 类

          • conditional ,默认值,与分成模型有类似的地方,当某张表仅有一个字段的时候,不会生成单独的class,而是放到基类中;
          • flat ,每张表生成独立的 domain class;
          • hierarchical ,分层模型,如果表有一个主键,这个模型将生成一个主键类,另一个类保存表中的任何 BLOB 列,另一个类保存剩余的字段。类之间存在适当的继承关系。
        • targetRuntime ,用于指定运行时目标,是会影响其他子元素的配置,(Kotlin的内容暂时不记录)

          • MyBatis3DynamicSql , 这是默认值,生成的代码会支持 Java8 和一些其他特性,有几个特点,
            1. 直接使用FLAT模式,无论 defaultModelType配置什么值;
            2. 无论 <javaClientGenerator>子元素的type配置什么值,mapper 都会生成带注解的mapper;
            3. 无视<sqlMapGenerator> 子元素的配置,不生成 XML 文件;
            4. 支持在查询时配置 table 别名,而不是固定不变的别名;
          • MyBatis3 ,特点:by example 方法支持各种动态的 where 子句 (dynamic where clauses)。
          • MyBatis3Simple ,特点:是 MyBatis3 的简化版,只生成点单的 CRUD 操作和很少的动态 SQL,不生成 by example 方法;

        [<property>](# 一些常用元素)

        支持的各种属性 ,详细查看官方文档

        • 常用的三个如下,
        • beginningDelimiter , SQL 表字段的分隔符的开始字符,其他同下;
        • endingDelimiter , SQL 表字段的分隔符的结束字符,默认 " 双引号 ,有时可能需要为 “`” 反引号,例如 hive 里使用反引号就可以规避保留字
        • javaFileEncoding ,指定Java文件的编码方式,参考 java.nio.charset.Charset

        [<plugin>](# 一些常用元素)

        生成代码时提供的插件,插件将按照配置中列出的顺序调用。支持的插件 ,具体查看官方文档。

        • 下面列举几个可能常用的插件

        • org.mybatis.generator.plugins.ToStringPlugin

        • org.mybatis.generator.plugins.SerializablePlugin

        • org.mybatis.generator.plugins.RowBoundsPlugin (对 targetRuntime=MyBatis3DynamicSql 时无效)

        • org.mybatis.generator.plugins.FluentBuilderMethodsPlugin (生成builder 方法,方便进行链式赋值)

        • org.mybatis.generator.plugins.EqualsHashCodePlugin

        1
        2
          例如:
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

        [<commentGenerator>](# 一些常用元素)

        官方文档部分 , 用于控制生成的java 代码中field,method ,等内容的注释。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        1. type 为可选 attribute,可以指定用户自定义的 CommentGenerator,具体参考官方文档
        2. 常用的 property 属性都列在了下面

        // 这里type指定的为用户自定义的 CommentGenerator 类,为了与 Swagger 文档结合
        <commentGenerator type="com.macro.mall.tiny.mbg.CommentGenerator">
        <!-- 是否去除自动生成的注释 true:是 : false:否 -->
        <property name="suppressAllComments" value="true"/>
        <property name="suppressDate" value="true"/>
        <!--这里的remark是指利用table的中文名生成代码注释-->
        <property name="addRemarkComments" value="true"/>
        </commentGenerator>

        [<connectionFactory>](# 一些常用元素)

        (either connectionFactory or jdbcConnection is Required)

        • 用于获取自省表所需的数据库连接。每个 元素都需要一个, 二选一。

        [<jdbcConnection>](# 一些常用元素)

        (either connectionFactory or jdbcConnection is Required)

        • driverClass ,JDBC driver 的全限定类名,必须的属性

        • connectionURL ,连接数据库用的 JDBC 连接 url,必须的属性

        • userId ,数据库用户名,可选

        • password , 数据库密码,可选

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
            <!--connectionFactory 与 jdbcConnection 作用一样,连接数据库用,且使用的参数也一样-->
          <!--区别,写法不一样,详见样例-->

          <connectionFactory>
          <property name="driverClass" value="org.hsqldb.jdbcDriver"/>
          <property name="connectionURL" value="jdbc:hsqldb:mem:aname"/>
          <property name="userId" value="sa"/>
          </connectionFactory>

          <!--与上面的作用一样,根据需要不同,userId,与 password 是可选的-->
          <jdbcConnection driverClass="COM.ibm.db2.jdbc.app.DB2Driver"
          connectionURL="jdbc:db2:MBGTEST"
          userId="db2admin"
          password="db2admin">
          </jdbcConnection>

        [<javaTypeResolver>](# 一些常用元素)

        [<javaModelGenerator>](# 一些常用元素)

        1
        2
        3
        4
        5
        6
        7
        8
        用于作JavaModel代码生成的配置

        1. targetPackage 是 targetProject 的子目录,两者合起来是生成代码存放的具体位置。
        2. 常用的两个property列在了下面,也可以都不用。
        <javaModelGenerator targetPackage="test.model" targetProject="\MyProject\src">
        <property name="enableSubPackages" value="true" />
        <property name="trimStrings" value="true" />
        </javaModelGenerator>

        [<sqlMapGenerator>](# 一些常用元素)

        1
        2
        3
        4
          每个内省的表构建一个 MyBatis 格式的 SQL 映射 XML 文件。
        <sqlMapGenerator targetPackage="test.model" targetProject="\MyProject\src">
        <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        仅当您选择的 需要 XML 时,此元素才是 元素的必需子元素。

        [<javaClientGenerator>](# 一些常用元素)

        1
        2
        3
        4
        5
        6
        7
        8
        9
        用于指定生成 Java 客户端接口和类,如果不配置,则不生成。
        1. type 属性,如果 <context> targetRuntime 是 MyBatis3DynamicSql,则是可选的,因为它会生成带注解的接口,不会生成 SQL mapper XML 文件;

        2. 如果 <context> targetRuntime 是 MyBatis3,则需要通过指定type为 ANNOTATEDMAPPER,MIXEDMAPPER,XMLMAPPER 来判断如何生成

        3. 其中 MIXEDMAPPER,简单的SQL会生成注解,复杂的动态SQL会生成 XML 文件。其他两个就简单了。
        <javaClientGenerator targetPackage="test.model" targetProject="\MyProject\src" type="XMLMAPPER">
        <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        [<table>](# 一些常用元素)

        • 很多内容
          • ,是 的子元素 ,用于映射 元素时生成合适的 元素

            运行 MyBatis Generator

            • 命令行运行

            1
            2
            3
            java -jar mybatis-generator-core-x.x.x.jar -configfile \temp\generatorConfig.xml -overwrite

            # -overwrite 覆盖已存在的Java 同名文件
          • Maven Plugin (mybatis-generator-maven-plugin)

            • 官方maven使用样例
            • mvn mybatis-generator:generate
              • 默认需要手动执行该命令才能生存,或者也可以配置 maven goal 和 execution 在 mvn 时自动生成
            • ${basedir}/src/main/resources/generatorConfig.xml 默认 XML 配置文件位置
          • Eclipse Plugin

          • Java 编程方式触发 generator 的生成

            • 支持通过解析 generatorConfig.xml 配置文件的形式生成代码;(XML 配置文件方式更常用)

              1
              2
              3
              4
              5
              6
              7
              8
              List<String> warnings = new ArrayList<String>();
              boolean overwrite = true;
              File configFile = new File("generatorConfig.xml");
              ConfigurationParser cp = new ConfigurationParser(warnings);
              Configuration config = cp.parseConfiguration(configFile);
              DefaultShellCallback callback = new DefaultShellCallback(overwrite);
              MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
              myBatisGenerator.generate(null);

              注意:如果在配置文件中指定了一个属性并且未解析,则转义的属性字符串将“按原样”传递到生成的代码中。

            • 支持基于java代码配置(在java代码中构建Configuration对象) 的形式生成代码;(样例,略,查看官方文档)

          • ant task

          运行 MyBatis Generator 后的任务

          更新 MyBatis 3.x 中的 MapperConfig.xml 文件

          • 必须列出 MBG 生成的 XML mapper 文件

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
              
            <configuration>
            ...
            <mappers>
            <!-- XML mapper files should be listed here -->
            <mapper resource="test/xml/MyTable_SqlMap.xml" />
            <!-- 如果有多个都列在这里 -->
            </mappers>

            </configuration>

          参考文件

          MBG 官方文档

          MBG 代码主要涉及步骤

          MBG 运行遇到的问题

          1. 配置完 generatorConfig.xml 文件之后,通过 java 代码运行没有生成预期的 model ,mapper interface,和 mapper XML文件,而且什么报错也没有。

            解决:1. 与配置文件中的 targetProjecttargetPackage 两个属性有关系,

            1
            2
            3
                <javaModelGenerator targetPackage="spoonli.data.mybatis.mbg.model"
            targetProject="./src/main/java">
            1. targetProject 这个目录一样要存在,且配置正确,可以配置全路径,也可以配置相对路径(建议,这样就不用频繁修改了)
          2. 配置的generatorConfig.xml 文件,在 Spring Boot 中使用内嵌 h2 数据库自动创建表,然后通过 MyBatisGenerator 生成代码的过程中,发现 h2 数据库没有自动创建写好的 resources/schema.xml 文件中的表。

            解决:暂时没有解决,换了 MySQL 数据库配置后自动生成没有问题,同时通过debug generate 方法发现,程序在数据库自省的过程中没有在内嵌的 h2 数据库中找到指定的表,在源码这行List<IntrospectedTable> tables = databaseIntrospector.introspectTables(tc); tables变量为 null,说明配置的 Spring Boot 内嵌 h2 数据库没有自动执行创建语句。


          Mapper文件

          MyBatis 中 Mapper 接口引用 XML 配置

          mapper interfaces that reference an XML configuration for MyBatis.

          编写Mapping文件时,需要注意

          • 默认情况下,Mapper文件名于Map接口名一样,一般以*Mapper.xml结尾

          • Mapper文件中,

            1
            <mapper namespace="xxx">  //要检查xxx是否与xml文件坐在package包名一样
          • Mapper文件中的SQL语句中,

            1. id要与Mapper接口文件中的方法名一样

            2. parameterType是参数的类型,一个参数时可以如果要指定,需要与方法中参数的数据类型一直,可以省略不写

            3. SQL语法中传入的参数要与方法中参数名一样,如:

              1
              2
              3
              4
              // applyId是方法参数中的参数名称,这里要一致
              <select id="getTaskID" parameterType="String">
              select business_id from apply where id=#{applyId}
              </select>
            4. 一般如果需要对传入的参数做判断,String !=null and String !=’’, Number !=null 即可

              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              //这是一个update操作
              <!--update apply set apply_status=? where id=?-->
              <update id="updateApplyStatus">
              update apply
              <set>
              <if test="applyStatus!=null"> //判断传入的数字参数applyStatus是否为null
              apply_status=#{applyStatus,jdbcType=DECIMAL}
              </if>
              </set>
              <where>
              <if test="applyId !=null and applyId!=''"> //String类型的,判断!=null,!=""
              id=#{applyId,jdbcType=VARCHAR}
              </if>
              </where>
              </update>

          Mybatis运行报错

          1
          org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.yo....

          运行时遇到上面的错误,找到了下面的内容,一般也就按照下面的提示内容检查

          1
          2
          3
          4
          5
          6
          7
          8
          首先,给定的异常提示信息并不精准,有多个错误原因都会抛出该异常。mybatis出现这个问题,通常是由Mapper interface和对应的xml文件的定义对应不上引起的,这时就需要仔细检查对比包名、xml中的namespace、接口中的方法名称等是否对应。我之前就因为称忘记在xml标签的id属性中添加方法名或写错方法名而出现这个错误。
          出现这个错误时,按以下步骤检查一般就会解决问题:
          1:检查xml文件所在package名称是否和Mapper interface所在的包名一一对应;
          2:检查xml的namespace是否和xml文件的package名称一一对应;
          3:检查方法名称是否对应;
          4:去除xml文件中的中文注释;
          5:随意在xml文件中加一个空格或者空行然后保存。

          参考内容

          学习的过程中参考了下面的博客内容,

          附上地址链接:

          http://blog.csdn.net/yzllz001/article/details/54312929
          http://www.cnblogs.com/softidea/p/5884772.html
          http://www.jianshu.com/p/800fe918cc7a

          20210421添加

          问题:

          1. mybatis-config.xml中mapper对应的文件可以是classpath中的相对路径吗?如何是,需要如何配置?
          2. mapper.xml文件中,SQL语句返回的resultType如果是自定义的,是否需要在哪里注册?
          3. mapper.xml中,多张表配置多个xml文件

          在Mybatis的config.xml配置文件中
          properties的优先级如下:
          Thus, the highest priority properties are those passed in as a method parameter, followed by resource/url attributes and finally the properties specified in the body of the properties element.

          如果配置多个environment,每个SqlSessionFactory实例只能使用一个
          (While you can configure multiple environments, you can only choose ONE per SqlSessionFactory instance. )
          所以,如果需要连接两个数据库,那么就需要两个SqlSessionFactory实例
          - One SqlSessionFactory instance per database

          数据库连接池
          org.apache.commons.dbcp:
          ali的Druid:
          上面两个好像都可以生成DataSource,有什么不同吗?

          Druid的两种DataSourceFactory在与Mybatis一同使用时有什么不同吗?
          为什么抄来的代码中要

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          // 如下,要通过Druid的pool的DataSource来创建ibatis的DataSource然后再用到mybatis-config.xml的datasource中,
          // 而不是直接使用Druid的support.ibatis的DataSource?是应为这个无法使用pool连接池吗?
          // Druid中这两个datasource的区别是什么?
          import com.alibaba.druid.pool.DruidDataSourceFactory;
          import org.apache.ibatis.datasource.DataSourceFactory;

          public class CustomerDruidDSFactory implements DataSourceFactory {
          @Override
          public void setProperties(Properties properties) {
          this.dataSource = DruidDataSourceFactory.createDataSource(properties);
          ......
          }
          ......
          }

          Mybatis的mapper文件中,如何对sql传递多个参数?

          不明白,migrate程序中为什么开始show database时,和后面insertdata时的connection 要用两种连接方式?为什么不能全都使用连接池?
          - 一种通过jdbc的方式直接创建
          - 一种通过common.dbcp连接池创建?

          利用Mybatis如何连接华为平台,使用kerbose认证的情况?
          配置文件让配置kerbose的url?也是可能的,但是没有migrate程序中将重要属性分开设置,程序拼接url友好

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信