zoukankan      html  css  js  c++  java
  • [MyBatis] MyBatis理论入门

    • 什么是MyBatis
    • iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
    • 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
    • MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

    • MyBatis特点
    • 简单易学,
    • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
    • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
    • 提供映射标签,支持对象与数据库的orm字段关系映射
    • 提供对象关系映射标签,支持对象关系组建维护
    • 提供xml标签,支持编写动态sql。

    • MyBatis执行流程
    • 加载配置(xml或注解)
      MyBatis将SQL的配置信息加载为一个个的MappedStatement对象(包括sqlId,sql语句,入参信息,返回值信息等),并将其存储在内存中

    • SQL解析
      当API接口层收到调用请求以后,会接收到传入的SQLId以及传入的入参对象(可以是任何类型),MyBatis根据SQL的Id找到对应的MappedStatement对象,然后根据传入参数对象对MappedStatement对象进行解析(将实际传入的参数来替换占位符参数,得到一条能够执行的sql语句)

    • SQL执行
      将解析得到的sql语句发送到数据库进行执行,得到数据库操作以后的结果

    • 结果集映射
      将数据库操作后得到的结果根据出参的配置进行自动转换,可以转换成任意类型,最后,将结果返回给调用方

    • MyBatis中的配置文件
      sqlMapConfig.xml(仅有一个),放在src目录下
    • <configuration></configuration>:包含配置信息
    • <environments default="environment"></environments>:默认的数据库连接环境,该节点中可包含多个<environments>标签
      • default:默认使用哪一个<environments>节点,值为<environments>中的id属性
    • <environments></environments>:数据库连接环境,可有多个
      <configuration>
          <!-- 数据库连接环境,default属性表示当前默认使用哪一个环境,值就是下面 environment子节点的id-->
          <environments default="environment">
              <!--environment节点可以有多个,表示不同的环境  -->
              <environment id="environment">
                  <!-- transactionManager 必须写在最上面 -->
                  <transactionManager type="JDBC" />
                  <dataSource type="POOLED">
                      <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
                      <property name="url" value="jdbc:oracle:thin:@192.168.3.5:1521:XE" />
                      <property name="username" value="SYSTEM" />
                      <property name="password" value="system" />
                  </dataSource>
              </environment>
          </environments>
          <!-- 包含了映射文件的信息 -->
          <mappers>
              <mapper resource="com/niit/entity/Dept.xml"/>
              <mapper resource="com/niit/entity/Emp.xml"/>
          </mappers>
          
      </configuration>
    • MyBatis放置SQL语句的XML文件(映射文件)
    • <mapper></mapper>:定义需要执行的一些SQL语句的信息 
      • namespace属性:命名空间,可以用来指定sqlId所在的xml文件,每一个xml文件都有一个唯一的namespace

    • <insert></insert>:新增。  <update></update>:更新  <select></select>:搜索  <delete></delete>:删除
      • id:当前SQL语句的一个唯一标识,在同一个映射文件中id不能重复
      • paramType:入参的类名
      • #{ }:占位符参数
      • ${ }:占位符。在添加到SQL语句中的值不会自动添加 单引号( ‘ ’)

    • 动态SQL

      在一些组合查询页面,需要根据用户输入的查询条件不同生成不同的查询SQL语句,这个操作在JDBC或其他框架中都需要通过SQL的拼接来完成
      动态SQL是MyBatis中的重要特性,用来解决这一问题

      • 判断元素:if(简单的条件判断逻辑,当满足指定条件时追加if元素内的SQL语句)  / choose
      •                 <select>
                            固定SQL语句
                            <if test="条件表达式">
                                动态SQL语句
                            </if>
                            <if ...>
                                ...
                            </if>
                        </select>
      • choose
                        <select>
                            固定SQL语句
                            <choose>
                                <when test="条件表达式">
                                    动态SQL语句
                                </when?>
                                <when ...>
                                    ...
                                </when>
                                <otherwise>
                                    动态语句N(当前都不满足时追加的SQL)
                                </otherwise>
                            </choose>
                        </select>
    • 关键字元素
      • where:主要用于简化查询语句中where部分的条件判断,where元素可以在其出现的位置上输出一个where关键字,而且还可以将后面条件多余的and或or去掉
                        <select>
                            固定SQL语句
                            <where>
                                根据不同条件动态追加的SQL语句
                            </where>
                        </select>
      • set:用在更新操作时,主要功能和where元素类似,set元素所在的位置输出一个set关键字,而且还可以去掉内容结尾中无关的逗号。
                        <update>
                            update 表名
                            <set>
                                根据条件动态追加要更新的列
                                //可嵌套if
                            </set>
                        </update>
      • trim:在trim包含的内容之前加上某些前缀,也可以在其后面添加后缀
          prefix="":前缀
          suffix="":后缀
        可以把trim包含的内容前面的某些内容过滤,也可以把尾部的某些内容过滤
          prefixOverrides="":过滤前面内容
          suffixOverrides="":过滤后面内容
        <!-- trim元素的使用   模拟where元素的实现 -->
               <select id="getDeptsByNameAndLoc4"  resultType="com.niit.entity.Dept">
                        select * from dept 
                       <trim prefix="where" prefixOverrides="AND|OR">
                           <if test="dname!=null and dname!=''">
                            and dname=#{dname}
                        </if>
                        <if test="loc!=null and loc!=''">
                            and  loc=#{loc}
                        </if>
                       </trim>
               </select>
    • 循环元素
      • foreach

        collection="":要迭代的集合
        item="":迭代变量
        open="":打印集合元素时,以什么元素开始
        close="":打印集合元素时,以什么符号结尾
        separator="":每个集合元素打印时,其中的分隔符

        <!-- foreach -->
               <select id="getDeptByDeptNos" resultType="com.niit.entity.Dept">
                       select * from dept where deptno in 
                       <!-- 
                           collection:要迭代的集合
                           item:迭代变量
                           open:打印集合元素时,以什么符号开头
                           close:打印集合元素时,以什么符号结尾
                           separator:每个集合元素打印时中间的分隔符
                        -->
                       <foreach collection="deptnos" item="deptno" open="(" close=")" separator=",">
                           #{deptno}
                       </foreach>
               </select>
    • 如果语句中有小于号(<)会被解析为XML中的节点,使用CDATA语句块

      <![CDATA[  and age<19  ]]>
    • 主键映射
      • 使用MyBatis做插入操作时,可以由MyBatis负责主键的生成,主键字段的映射分为两种情况
        数据库支持自动递增:(MySQL、SqlServer)
        数据库不支持自动增长:(Oracle)

                    <insert>
                        <selectKey keyProperty="" resultType="" order="">
                            
                        </selectKey>
                    </insert>

        selectKey指定了入参对象中用来表示主键的属性名,在完成selectKey中语句的执行以后, 会自动将值set到入参对象中由keyProperty指定的属性中去
        keyProperty:入参中用来表示主键字段的属性名
        order:如果取值为BEFOR,表示先获取主键,再执行插入;对于之处自增长主键的数据库必须设置为AFTER才有效
        resultType:生成的主键对应的结果类型

    • 关联映射
      • (1)嵌套查询:通过执行另外一条SQL语句来返回关联数据的结果(至少要查两次)
      • (2)嵌套结果:执行一个表关联查询的SQL语句,然后将查询结果映射成关联的对象(只查一次)

        <!-- 关联映射  嵌套查询 -->
            <select id="getEmpByEmpNo" parameterType="int" resultMap="empMap1">
                select * from emp where empno=#{empno}
            </select>
            <select id="getDeptByDeptno" parameterType="int" resultType="com.niit.entity.Dept">
                select * from dept where deptno=#{deptno}    
            </select>
            <resultMap id="empMap1" type="com.niit.entity.Emp">
                <!-- association元素:用来配置JavaBean类型的关联对象
                     property:关联对象在当前类中的属性名
                     column:关联列的列名
                     javaType:关联对象的java类型
                     select:指定通过哪一条语句来查询关联对象
                 -->
                <association property="dept" column="deptno" javaType="com.niit.entity.Dept" select="getDeptByDeptno">
                    
                </association>
            </resultMap>
            
            <!-- 嵌套结果 -->
            <select id="getEmpByEmpNo2" parameterType="int" resultMap="empMap2">
                select e.*,d.*
                from emp e,dept d 
                where e.deptno=d.deptno and e.empno=#{empno}
            </select>
            <resultMap  id="empMap2" type="com.niit.entity.Emp">
                <result column="empno" property="empno"/>
                <!-- 
                    Emp中其它字段映射关系的配置……    
                 -->
                <association property="dept" column="deptno" javaType="com.niit.entity.Dept">
                    <id column="deptno" property="deptno"/>
                    <result column="dname" property="dname"/>
                    <result column="loc" property="loc"/>
                </association>
            </resultMap>
    • 集合映射 
      • 嵌套查询:(查询两次)
        <!-- 嵌套查询 -->
               <select id="getDeptInfoByDeptNo" parameterType="int" resultMap="deptMap1">
                       select * from dept where deptno=#{deptno}
               </select>
               <select id="findEmpsByDeptNo" parameterType="int" resultType="com.niit.entity.Emp">
                       select * from emp where deptno=#{deptno}
               </select>
               <resultMap id="deptMap1" type="com.niit.entity.Dept" >
                       <result property="deptno" column="deptno"/>
                       <!-- 返回Dept中关联的Emp列表 -->
                       <!-- 
                           collection:关联的集合对象
                           property:当前类中的集合对象对应的属性
                           column:当前表中的关联列,通过这个列的值再去查询另外一张表
                           javaType:返回的集合类型
                           ofType:返回的集合中元素的泛型
                           select:指定通过哪条SQL语句来查询关联的集合对象
                        -->
                       <collection property="emps" 
                       column="deptno" 
                       javaType="java.util.ArrayList" 
                       ofType="com.niit.entity.Emp" 
                       select="findEmpsByDeptNo"></collection>
                       
               </resultMap>
      • 嵌套结果:(查询一次)
        <!-- 嵌套结果 -->
               <select id="getDeptInfoByDeptNo2" parameterType="int" resultMap="deptMap2">
                       select e.*,d.*
                    from emp e,dept d
                    where e.deptno=d.deptno and d.deptno=#{deptno}
               </select>
               <resultMap  id="deptMap2" type="com.niit.entity.Dept">
                       <id column="deptno" property="deptno"/>
                       <result column="dname" property="dname"/>
                       <result column="loc" property="loc"/>
               
                       <collection property="emps" column="deptno" ofType="com.niit.entity.Emp" javaType="java.util.ArrayList">
                           <id column="empno" property="empno"/>
                           <result column="ename" property="ename"/>
                           <!-- Emp中的其它字段和属性的映射关系 -->
                       </collection>
               </resultMap>

        使用<collection>进行dept对象中的List<Emp> emps;的注入。只执行了一次SQL语句,返回一个 Dept 对象。该标签中的列名当前表中的关联列,通过这个列的值再去查询另外一张表
        <id />和<result />基本一致


        Dept.java

        private int                    deptno;
            private String                dname;
            private String                loc;
            private List<Emp>            emps;


        Emp.java

        private int                    empno;
            private String                ename;
            private String                job;
            private int                    mgr;
            private Date                hiredate;
            private double                sal;
            private double                comm;
            private int                    deptno;
            /** dept就是员工对应的部门对象 **/
            private Dept                dept;
  • 相关阅读:
    Java程序,猜大小游戏
    Java程序,取随机数的两种实现方法
    用Java程序判断是否是闰年
    Python学习-基础篇17 Django-进阶
    Python学习-基础篇16 Django-Ajax、Cookie
    Python学习-基础篇15 Django-MTV
    Python学习-基础篇14 Web框架本质及第一个Django实例
    Python学习-基础篇13 前端知识之Bootstrap框架
    Python学习-基础篇12 前端知识之Javascript知识
    Python学习-基础篇11 前端知识之HTML内容
  • 原文地址:https://www.cnblogs.com/x-you/p/8525278.html
Copyright © 2011-2022 走看看