IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> mybatis -> 正文阅读

[大数据]mybatis

MyBatis:底层封装了JDBC的持久层框架

1.为什么使用MyBatis

1.1. 传统的ORM框架介绍?

  1. 传统的访问数据库的方式?JDBC
    1. 加载驱动 Class.forName()
    2. 获得连接 Connection con…
    3. 创建执行SQL的Statement对象 PreparedStatement…
    4. 执行SQL返回结果 execute executeUpdate executeQuery()
    5. 处理结果 while rs.next()…
    6. 关闭资源 close
    问题:面向对象开发和面向关系存储之间不匹配问题【不完全对应。】开发人员手动处理由对象到关系型数据库之间的对应。【手动处理】
  2. ORM思想的出现:
    1. ORM:Object Relational Mapping 对象关系映射,这种思想目标是把面向对象开发中的对象映射到基于SQL的关系型数据库中。

    2. addStu(Student stu) orm: addStu(Student stu)

      jdbc:手动造车 手动执行 ORM框架.save(stu)–>XML 映射文件

      手动处理结果 手动写SQL 映射文件: 类=表 类中属性-表中字段

      ? }

  3. ORM是一种思想,其中最著名的实现: Hibernate.

  4. Hibernate是一款“全自动”的ORM映射框架:实现了Pojo到数据库表的全套映射机制,开发人员只需要定义好映射文件。Hibernate会自动的根据映射文件逻辑生成SQL语句、自动的执行SQL语句、自动的返回结果。

  5. Hibernate save()–>insert语句 翻译过程 效率非常低、SQL语句不灵活

2.MyBatis简介?

  1. MyBatis也是一款ORM思想的实现框架,底层也是封装的JDBC。

  2. MyBatis是一款"半自动的"ORM框架. MyBatis也会执行SQL,返回结果。具体的SQL语句需要开发人员自己写。 灵活 效率高。

  3. MyBatis在2010年之前叫IBatis,属于ASF(apache software foundation),后来退出ASF,改名为MyBatis。

  4. 文档地址:

    https://mybatis.org/mybatis-3/zh/configuration.html

  5. MyBatis中有两类配置文件:

    1. 属性文件mybatis-config.xml:连接数据库的信息+属性 配置
    2. 映射文件StudentMapper.xml: 我们写的SQL语句

3.MyBatis提供的用户接口?

  1. org.apache.ibatis.session.SqlSessionFactoryBuilder:
    1. build(IO流)
    2. build(Configuration 配置对象)
  2. org.apache.ibatis.session.SqlSessionFactory:
    1. openSession()
  3. org.apache.ibatis.session.SqlSession:[核心]
    1. insert
    2. update
    3. delete
    4. selectOne selectList…

4. MyBatis的helloworld[对学生表的CRUD]?

  1. mybatis-config.xml

    <?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 resource="db.properties"></properties>
        <settings><!--logImpl:LOG4J 采用log4j做日志-->
            <setting name="logImpl" value="LOG4J"></setting>
        </settings>
      <typeAliases>
            <!--注册别名 所有需要完成包名+类名的地方都可以通过 别名来替换-->
            <!--<typeAlias type="com.etoak.student.entity.Student" alias="stu"></typeAlias>
            <typeAlias type="com.etoak.student.entity.School" alias="sch"></typeAlias>-->
            <!--给指定的包及其子包起别名 别名默认是:类名字首字母小写 ,可以通过@Alias注解修改默认规则-->
          <package name="com.etoak.student.entity"/>
        </typeAliases>
        <environments default="m">
            <environment id="m">
                <!--事务管理器:JDBC:代表使用JDBC的方式管理事务
                    Connection.setAutoCommit();
                    Connection.commit();/rollback()
                -->
                <transactionManager type="JDBC"></transactionManager>
                <!--POOLED:代表采用MyBatis使用了连接池方式实现的数据源-->
                <dataSource type="POOLED">
                    <property name="driver" value="${m.driver}"></property>
                    <property name="url" value="${m.url}"></property>
                    <property name="username" value="${m.user}"></property>
                    <property name="password" value="${m.pwd}"></property>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="StudentMapper.xml" />
        </mappers>
    </configuration>
    

请添加图片描述

  1. XXMapper.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="com.et">
        <!--
        insert: 执行 insert语句 executeUpdate
        -->
        <insert id="addStu" parameterType="com.etoak.student.pojo.Student">
            insert into student( name, age, birth, email, schid)
            values(#{name},#{age},#{birth},#{email},#{schid})
        </insert>
        <!--
        select:执行查询
        -->
        <select id="queryStuById" parameterType="int"
                resultType="com.etoak.student.pojo.Student">
            select * from student where id=#{id}
        </select>
        <!--
        UPDATE executeUpdate
        -->
        <update id="updateStu" >
            update student set name=#{name},age=#{age},birth=#{birth},
                               email=#{email} where id=#{id}
        </update>
        <!--
        delete executeUpdate
        -->
        <delete id="deleteStu" >
            delete from student where id=#{id}
        </delete>
        <select id="queryAll" resultType="com.etoak.student.pojo.Student">
            select * from student
        </select>
    
    </mapper>
    
  2. 基础操作

 session.insert(SQL语句id,参数)
 session.update(SQL语句id,参数)
 session.delete(SQL语句id,参数)
 session.selectOne(SQL语句id,参数)
 session.selectList(SQL语句id,参数)

5. Mapper方式实现MyBatis?

  • Mapper.xml中namespace的名字和Mapper接口的名字一致
  • Mapper.xml中的SQL语句的id和Mapper接口中方法名字一致

6. 类中属性和表中字段不完全一致?

  1. 添加

    #{类中的属性不是表中的字段}

  2. 查询
    1. 起别名

       <select id="queryById" parameterType="int"
          resultType="stu">
              select
              s_id as id,
              s_name name,
              s_age age,
              s_birth birth,
              s_email as email,
              s_schid as schid
              from tb_stu where s_id=#{id}
          </select>
      
    2. 使用resultMap

      <resultMap id="rMap_stu" type="stu">
              <id property="id" column="s_id"></id>
              <result property="name" column="s_name"></result>
              <result property="age" column="s_age"></result>
              <result property="birth" column="s_birth"></result>
              <result property="email" column="s_email"></result>
              <result property="schid" column="s_schid"></result>
          </resultMap>
          <select id="queryById" parameterType="int"  resultMap="rMap_stu">
              select * from tb_stu where s_id=#{id}
          </select>
      

7. 传递多个参数?

  1. Map

  2. @Param

  3. 对象

 List<Student> querySome1(@Param("start")int startadadfa,
                            @Param("pageSize") int pageSizeasdfadf);

    List<Student> querySome(Map<String,Object> map);

8. resultType和resultMap的区别?

  • resultType:表示执行SQL查询之后的结果集的每一条记录返回的类型,如:自定义的对象Student/User/Teacher、int、map
  • resultMap:一定对应的一个元素的id

9. MyBatis如何获得添加到数据库中的主键?

  1. JDBC如何获得?

    1. 自动增长的数字
      1. 开关 Statement.RETURN_GENERATED_KEYS
      2. 同一个连接前提下查询:select last_insert_id()
    2. 字符串
      1. select replace(uuid(),‘-’,‘’)
      2. UUID.randomUUID()
      3. KeyGenerator.getId()
  2. MyBatis和JDBC原理一样。

    1. 使用useGeneratedKeys +keyProperty属性

      <insert id="addStudent" parameterType="stu" useGeneratedKeys="true"
          keyProperty="id" keyColumn="s_id" >
              insert into tb_stu( s_name, s_age, s_birth, s_email, s_schid)
              values(#{name},#{age},#{birth},#{email},#{schid})
          </insert>
      
    2. selectKey

       <insert id="addStudent" parameterType="stu" >
              <selectKey keyProperty="id" keyColumn="s_id" resultType="int"
              order="AFTER">
                  select last_insert_id()
                 <!-- select replace(uuid(),'-','')-->
              </selectKey>
              insert into tb_stu( s_name, s_age, s_birth, s_email, s_schid)
              values(#{name},#{age},#{birth},#{email},#{schid})
          </insert>
      
      

10. 批量添加?

  1. 使用就是动态标签 foreach

     <insert id="addStus1" parameterType="list">
            insert into tb_stu(s_name, s_age, s_birth, s_email, s_schid)
            values
            <foreach collection="list" item="s" separator=",">
                (#{s.name},#{s.age},#{s.birth},#{s.email},#{s.schid})
            </foreach>
    
        </insert>
    
        <insert id="addStus" parameterType="list">
            insert into tb_stu(s_name, s_age, s_birth, s_email, s_schid)
    
            <foreach collection="list" item="s" separator=" union ">
                (select  #{s.name},#{s.age},#{s.birth},#{s.email},#{s.schid} )
            </foreach>
    
        </insert>
    

11. 模糊查询:#和$的区别?

1.#底层使用的是预编译的Statement,即:PreparedStatement,支持?占位符的。$:底层使用的是普通的Statement,不支持?占位符的,参数只能拼接。

2.有些情况不能使用?占位:

? 参考JDBC :PrearedStatement和Statement的区别。

12. MyBatis中的动态SQL标签?

  • where

  • if

      <select id="queryByConditions1" resultMap="rMap_stu">
            select * from tb_stu
            <where>
                <if test="name!=null and name!='' ">
                    and s_name like '%${name}%'
                </if >
                <if test="email!=null and email!='' ">
                    and s_email=#{email}
                </if>
            </where>
        </select>
    
  • foreach

     <insert id="addStus1" parameterType="list">
            insert into tb_stu(s_name, s_age, s_birth, s_email, s_schid)
            values
            <foreach collection="list" item="s" separator=",">
                (#{s.name},#{s.age},#{s.birth},#{s.email},#{s.schid})
            </foreach>
    
        </insert>
        <insert id="addStus" parameterType="list">
            insert into tb_stu(s_name, s_age, s_birth, s_email, s_schid)
    
            <foreach collection="list" item="s" separator=" union ">
                (select  #{s.name},#{s.age},#{s.birth},#{s.email},#{s.schid} )
            </foreach>
    
        </insert>
    
  • trim

     <select id="queryByConditions" resultMap="rMap_stu">
            select * from tb_stu
            <!--prefix:前缀  prefixOverrides:前边遇到什么内容干掉-->
                <trim prefix="where" prefixOverrides="and">
                    <if test="name!=null and name!='' ">
                        and s_name like '%${name}%'
                    </if >
                    <if test="email!=null and email!='' ">
                        and s_email=#{email}
                    </if>
                </trim>
    
        </select>
    
  • chose…when.otherwise

     <select id="queryByConditions" resultMap="rMap_stu">
            select * from tb_stu
            <!--prefix:前缀  prefixOverrides:前边遇到什么内容干掉-->
            <trim prefix="where" prefixOverrides="and">
               <choose>
                   <when test="name!=null and name!='' ">
                       and s_name like '%${name}%'
                   </when>
                    <otherwise>
                        and s_email=#{email}  
                    </otherwise>
               </choose>
            </trim>
    
        </select>
    
    

13. 一对一和一对多的关联查询?

  • association

     <resultMap id="rMap_stu_sch" type="stu">
            <id property="id" column="s_id"></id>
            <result property="name" column="s_name"></result>
            <result property="age" column="s_age"></result>
            <result property="birth" column="s_birth"></result>
            <result property="email" column="s_email"></result>
            <result property="schid" column="s_schid"></result>
            <!--association:一对一关联
                property:类中的属性 javaType:属性的类型-->
            <association property="sch" javaType="com.etoak.student.entity.School">
                <id property="id" column="id"></id>
                <result property="name" column="name"></result>
                <result property="phone" column="phone"></result>
                <result property="info" column="info"></result>
            </association>
        </resultMap>
        <select id="queryByIdWithSch" resultMap="rMap_stu_sch">
            select
            s_id, s_name, s_age, s_birth, s_email, s_schid,
            sch.id, sch.name, sch.phone,sch.info
            from tb_stu s left join school sch
                on s.s_schid = sch.id where s.s_id=#{id}
        </select>
    
  • collection:一对多

      <resultMap id="rMap_sch" type="com.etoak.student.entity.School">
            <id property="id" column="id"></id>
            <result property="name" column="name"></result>
            <result property="phone" column="phone"></result>
            <result property="info" column="info"></result>
            <!--
            collection:表示集合 List /set都可以
                property:类中的属性
                ofType:集合中每一个元素的类型
            -->
            <collection property="stus" ofType="stu">
                <id property="id" column="s_id"></id>
                <result property="name" column="s_name"></result>
                <result property="age" column="s_age"></result>
                <result property="birth" column="s_birth"></result>
                <result property="email" column="s_email"></result>
                <result property="schid" column="s_schid"></result>
            </collection>
        </resultMap>
        <select id="querySchWithStus" resultMap="rMap_sch">
            select sch.id, sch.name, sch.phone,sch.info,
                   s_id, s_name, s_age, s_birth, s_email, s_schid
            from school sch   left join tb_stu s on s.s_schid = sch.id
            where sch.id=#{id}
        </select>
    

14. MyBatis的核心接口【面向内部的】?

  1. org.apache.ibatis.session.Configuration:

    1. 代表MyBatis中的配置文件
    2. 其中的属性:Environment:代表环境标签
    3. 其中的属性:MappedStatement:代表SQL映射文件中的等标签
  2. org.apache.ibatis.mapping.Environment:

    1. 代表环境元素.
    2. 其中的属性:id+transactionFactory+dataSource
  3. org.apache.ibatis.mapping.MappedStatement:

    1. 代表SQL映射文件中的标签

    2. 其中的属性:

      1. StatementType:执行器的类型 枚举

        STATEMENT:普通的执行器
        PREPARED:预编译的执行器
        CALLABLE:执行触发器的执行器
        
      2. ResultSetType:结果集的类型 枚举

        	DEFAULT(-1):默认的结果集
           FORWARD_ONLY(1003):不可滚动的结果集
           SCROLL_INSENSITIVE(1004):可滚动结果集
           SCROLL_SENSITIVE(1005):可滚动的结果集
        
      3. SqlCommandType:SQL语句的类型 枚举

        INSERT/UPDATE/DELETE/SELECT/UNKNOWN
        
      4. SqlSource:解析SQL语句的方法+获得SQL的方法

        其中有一个方法getBoundSql:BoundSql真正代表SQL语句
        
  4. org.apache.ibatis.type.TypeAliasRegistry:类型别名注册器 存放别名

    1. TypeAliasRegistry构造时默认注册一些别名: int string list

    2. new Configuration():中 自动添加别名 如:JDBC POOLED LOG4J

    3. 我们写的别名

        1.  <typeAlias type="" alias="">
      
       
        2.  <typeAliasPackage value="">
      

请添加图片描述

  1. org.apache.ibatis.builder.BaseBuilder:基本的解析器

    1. 代表解析器。解析XML的。

    2. 其中主要属性和构造方法

      public abstract class BaseBuilder{    
          protected final Configuration configuration;
          protected final TypeAliasRegistry typeAliasRegistry;
          protected final TypeHandlerRegistry typeHandlerRegistry;
      
          public BaseBuilder(Configuration configuration) {
              this.configuration = configuration;
              this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
              this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
          }
    
    1. BaseBuilder有很多子类:

      1. XMLConfigBuilder:解析 mybatis-config.xml
      2. XMLMapperBuilder:解析 *Mapper.xml
      3. XMLStatementBuilder:解析insert update delete标签的
      4. XMLScriptBuilder:SQL语句
  2. org.apache.ibatis.io.Resources:资源

    1. 该类是MyBatis封装的工具类。专门加载配置文件
    2. 底层委托 classLoaderWrapper实现具体加载的。原理就是使用ClassLoader.getResourceAsStream实现的。

15. 解析配置以及SqlSessionFactory构造的过程?

  1. SF工厂

请添加图片描述

  1. build(reader)

请添加图片描述

  1. 分步骤解析:1.XMLConfigBuilder parser = new XMLConfigBuilder(reader)

请添加图片描述

XMLPathParser:接收mybatis-config.xml流+resolver,本身提供把流转换成Document对象【JDK中提供DOM解析器】的方法和一堆使用JDK中提供的XPath方式计算XML中每一个部分的的方法。

请添加图片描述

  1. 分析步骤2: parser.parse():挨个解析mybatis-config和mapper.xml中的每一个元素 最终都装configuration对象

    请添加图片描述

  2. 步骤分析3:new DefaultSqlSessioFacotry(config)

16. parseConfiguration中的几个部分分析?

  1. 解析元素

    请添加图片描述

  2. 解析元素

请添加图片描述

  1. 解析元素

请添加图片描述

  1. XMLConfigBuilder:解析mybatis-config.xml

    1.XMLConfigBuilder中 调用 XMLMapperBuilder解析 Mapper.xml,

    2.然后再XMLMapperBuilder 调用XMLStatementBuilder专门解析元素中的每一个属性和内容

    2.然后再XMLStatementBuilder中调用XMLScriptBuilder 构造SQL语句 BoundSql===》SqlSource

17. 常见错误?

  • Mapped Statements collection does not contain value for xxx

? 原因: SQL语句映射文件中没有DAO层调用的语句。

  • A query was run and no Result Maps were found for the Mapped Statement ‘com.et2203.queryById’. It’s likely that neither a Result Type nor a Result Map was specified.

    原因:执行的是查询语句,没有resultType或者resultMap。

  • Caused by: org.apache.ibatis.binding.BindingException: Parameter ‘start’ not found. Available parameters are [arg1, arg0, param1, param2]

    原因:传递多个参数MyBatis默认不会按照形参去命名,而是自动命名为:arg0,arg1…或者param1 param2…

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:34:26  更:2022-07-05 23:35:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:22:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码