Mybatis知识汇总

Posted 爱分享的程序袁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis知识汇总相关的知识,希望对你有一定的参考价值。

  1. 什么是mybatis

           mybatis是一个优秀的持久层框架,他对jdbc操作数据库的过程进行了封装,使开发者只用关注sql本身,不用去关注例如注册驱动,加载链接,得到statement,处理结果集等复杂的过程。
         mybatis通过xml或者注解的方式,将要执行的各种sql语句配置起来,并通过Java对象和statement中的sql语句映射生成最终的sql语句,最后由mybatis框架执行sql语句,并将结果映射成Java对象返回。

  2. 搭建一个mybatis

    导入jar包,导入myBatis核心jar包和 数据库驱动jar包

    在src下创建一个名为mybatis.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> 

     

     <environments default="development">

      <!-- 配置一个数据源 -->

        <environment id="development">

         <!-- 事务的方式 -->

         <transactionManager type="JDBC"/>

       <dataSource type="POOLED">

          <!--数据库连接的基本参数 -->

        <property name="driver" value="com.mysql.jdbc.Driver"/>

        <property name="url" value="jdbc:mysql://localhost:3306/home_work"/>

        <property name="username" value="root"/>

       <property name="password" value="root"/>

      </dataSource>

    </environment>

  </environments> 

</configuration>

3.namespace属性<mapper namespace="dao.PhoneDao"

     namespace 命名空间

     多个mapper文件的namespace不能重复

     命名:写的是 对应dao层接口的完全限定名(接口的包名+类名)

    将一个mapper文件当成一个普通的java类

    这里面的每一条sql语句 当成类中的方法

    调用mapper中的某一条SQL的时候

    namespace.SQL语句的id

4.id属性

    是该SQL语句的唯一标识

    在同一个mapper文件中 id不能重复

    调用该SQL语句的时候 需要用到id

    id可以想象成方法名字

    一般跟接口中的方法名一致

  resultType属性:

    返回值类型  需要将查询出的数据 映射(转换)为哪一个实体类

    无论是查询一条还是多条,写的都是实体类的完全限定名,不能写List<实体类>

    java接口中 多条数据 还是用List<实体类>来接收

  注意:

     查询后的列名 要和 实体类中的属性名 对应上

     对应不上的无法完成映射

新建了mapper文件后 需要到mybatis的配置文件中 进行配置,不然报错

    <!-- 项目中的所有mapper文件都要到这进行配置,不然mybatis找不到

      resource 写的是文件的路径  多个包之间用/分割-->

      <mappers>

        <mapper resource="dao/PhoneDao.xml"/>

      </mappers>

5.SQL语句中的ParamterType属性Mybatis知识汇总

        parameterType属性 ---- 参数类型

         如果在执行增删改查的时候 需要传递参数 那么就需要些parameterType属性

         与接口中参数类型保持一致

         获取参数的方式:

         1.#{参数名}  -----》 推荐   如果只传递了一个int,string类型的参数

         那么大括号中参数名  可以随意

         2.${参数名}     

    #{}和${}的区别是什么?

    答:${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态 

    文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql的参数占位

    符,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数

    设置方法,按序给sql的?号占位符设置参数值,比如ps.setInt(0, parameterValue),#

   {item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值,相当于

    param.getItem().getName()。

         注意:

         如果传递的是一个实体类,那么大括号中写的是实体类中的属性名

         如果获取的是实体类中的本身属性,那么大括号中直接写属性名字

         如果获取的是级联属性,那么先获取级联的对象,在获取里面的属性

6.解决数据库中列名和实体类中的属性名不一致问题

    1.在查询时将与属性名不一样的列名起 别名

    2.在MyBatis配置文件中 配置启用驼峰映射方式

  <settings>

  <!-- 使用驼峰命名进行自动映射 -->

  <setting name="mapUnderscoreToCamelCase" value="true"/>

  </settings>

    使用驼峰方式映射 要求:

    1.列名 多个单词之间用下划线连接 stu_name

    2.实体类中 使用驼峰方式,将下划线去掉,第二个单词的首字符大写 如:stuName

7.实体类配置别名

   在mybatis配置文件中,setting标签下写,位置不能换

  <typeAliases>

    <!--

    package 为一个包下的所有类 配置别名

    name属性   包的路径

    Mapper文件中只要用到了实体类,那么直接写类名即可

     -->

  <package name="model"/>

  </typeAliases>

8.控制台打印sql语句的配置

9.面向接口编程的注意事项  

    1.Mapper文件的文件名字 和 接口的名字 对应,Mapper文件的namespace属性的值 要

   和 接口的完全限定名一致

    2.Mapper文件中的sql语句的id 要和 接口中的方法名字 一致

    3.sql语句的返回值(resultType),要和接口中方法的返回值一致

    4.接口中方法的参数 必须包含(但不限于) sql语句中 所需要的参(parameterType

10.where标签和if标签

    用法:     

      <select id="select" resultType="PhoneModel"

            parameterType="PhoneModel">

            select * from phone

            <where>

                <if test="phoneName != null  and phoneName != ''">

                and phone_name

                like concat('%',#{phoneName},'%')

                </if>

                <if test="brandId != null">

                and brand_id = #{brandId}

                </if>

            </where>

        </select>

    where标签作用:

    where标签会自动生成一个where关键字

    会自动去掉where条件后的第一个and关键字

    每个条件都要加上and关键字

    如果说一个where条件都没有,那么将不会生成where关键字

    if标签作用:

     与java中的if逻辑一致,没有else结构体

     if标签可用在任意位置,不是只能用在where标签里面

     test属性 写的是判断条件

     如果要使用if标签对属性进行判断,那么要么传递

     实体类,要么传递一个map集合

     判断是获取的是 实体类中的属性名字,不需要#{}

     多个判断条件之间用 and 单词来连接

     注意:

     如果使用if标签判断级联属性,那么首先要

     判断该级联的对象是否非空,然后在判断级联对象

     下的某些属性

11.set标签

    <update id="update" parameterType="PhoneModel">

    update phone

    <set>

        <if test="phoneName != null and phoneName != ''">

            phone_name = #{phoneName},

        </if>

        <if test="phonePrice != null">

            phone_price = #{phonePrice},

        </if>

        <if test="brandId != null">

            brand_id = #{brandId},

        </if>

    </set>

        where id = #{id}

    </update>

    作用:只能用于update操作

              会生成一个set关键字

              会将最后一个更新字段的逗号 去掉

              更新每个字段后面都要加逗号

              where关键字要写在set标签的外面

12.trim标签

      prefix 前缀 是在trim标签之前拼接字符

     prefixOverrides 去掉trim标签语句中第一个出现的关键字

     suffix 后缀 是在trim标签之后拼接字符

     suffixOverrides 去掉trim标签语句中最后一个出现的关键字

 用法:

   1.查询     

            <select id="selectTrim"  parameterType="PhoneModel"

                resultType="PhoneModel">

                select * from phone

                <trim prefix="where" prefixOverrides="and">

                <if test="phoneName != null  and phoneName != ''">

                    and phone_name

                    like concat('%',#{phoneName},'%')

                </if>

                <if test="brandId != null">

                    and brand_id = #{brandId}

                </if>

                </trim>

           </select>

    2.修改

            <update id="updateTrim" parameterType="PhoneModel">

                update phone

                <trim prefix="set" suffixOverrides="," suffix="where">

                <if test="phoneName != null and phoneName != ''">

                    phone_name = #{phoneName},

                </if>

                <if test="phonePrice != null">

                    phone_price = #{phonePrice},

                </if>

                </trim>

                id = #{id}

            </update>

    3.新增

        <insert id="insertTrim" parameterType="PhoneModel">

            insert into phone

            <trim prefix="(" suffix=")" suffixOverrides=",">

                <if test="phoneName != null and phoneName != ''">

                    phone_name,

                </if>

                <if test="brandId != null">

                    brand_id,

                </if>

                </trim>

            values

            <trim prefix="(" suffix=")" suffixOverrides=",">

            <if test="phoneName != null and phoneName != ''">

                    #{phoneName},

                </if>

                <if test="brandId != null">

                    #{brandId},

                </if>

            </trim>

        </insert>

13.choose标签

  用法:

        <select id="selectChoose" resultType="PhoneModel"

                parameterType="PhoneModel">

            select * from phone

            <where>

                <choose>

                    <when test="brandId != null">

                        and brand_id = #{brandId}

                    </when>

                    <when test="id != null">

                        and id = #{id}

               </when>

                <otherwise>

                    and 1=1

             </otherwise>

                </choose>

            </where>

       </select>

作用:跟java的if-else if-else逻辑是一样的

         第一个when标签代表了if

         其他的when标签代表了 else if

         otherwise 代表了else

14.foreach标签

    用法:

     1.实现批量插入

            <insert id="insertBatch" parameterType="list">

                insert into phone

                (phone_name,phone_price,brand_id)

                values

                <foreach collection="list" item="i"  separator=",">

                (#{i.phoneName},#{i.phonePrice},#{i.brandId})

                </foreach>

            </insert>

     2.拼接or语句

            <select id="selectPhoneName"   resultType="PhoneModel" 

                parameterType="PhoneModel">

                select * from phone

                where phone_price > #{phonePrice}

                <foreach collection="nameList"item="i" open=" and ("                  close=")" separator="or">

                phone_name like concat("%",#{i},"%")

                </foreach>

            </select>

15.resultMap标签

      用法:

        <resultMap type="PhoneModel" id="phoneMap" autoMapping="true">

             <id column="id" property="id"/>

             <result column="phone_name" property="phoneName"/>

             <result column="phone_price" property="phonePrice"/>

             <result column="brand_id" property="brandId"/>

             <association property="brandModel" javaType="BrandModel">

             <id column="b_id" property="id"/>

             <result column="brand_name" property="brandName"/>

             </association>

         </resultMap>

         <select id="selectByMap" resultMap="phoneMap">

                 select

                 p.id,p.phone_name,p.phone_price,p.brand_id,

                 b.id b_id,b.brand_name

                 from phone p

                 left join brand b

                 on p.brand_id = b.id

         </select>

注意:

        1.只能用于查询

        2.resultMap 和 resultType 二者只能出现一个

        3.如果需要对结果集进行 一对一 或者 一对多的映射,

        那么就要使用resultMap

作用:

        1.解决列名与属性名不一致的问题

        2.对结果进行一对一,一对多映射

用法:

        select标签中resultMap属性写的是 一个resultMap标签的id

        id属性 是resultMap标签的一个标识,不能重复

        type属性 返回的类型,一般来讲,将主表对应的实体类当做返回类型

        autoMapping属性:如果有一部分的查询出的列名和属性名 是一致的话

        那么开启autoMapping将不需要为列名和属性名一致的

子标签:

        1.id标签,用来映射主表的主键字段,只能出现一次

            column 代表了列名,一定要根据查询后的列名来进行映射

            property 代表了实体类中的属性名

            javaType 代表了property所指定的属性在实体类中是什么类型

            jdbcType 代表了column所指定的列在表中是什么类型

         2.result标签 除主键以外字段 全部使用result标签进行映射

         3.association标签  用于一对一映射

             property 代表了实体类中的属性名字

             javaType 代表了该属性是哪一个类型

16.嵌套查询

场景:查询所有手机并且 实体类中要 关联出 手机的品牌

        <resultMap type="PhoneModel" id="queryMap">

            <id column="id" property="id"/>

            <!-- 其他字段使用驼峰自动映射 -->

            <association property="brandModel" fetchType="lazy"

            javaType="BrandModel" select="selectBrand" column="brand_id">

            </association>

        </resultMap>

        <select id="selectPhone" resultMap="queryMap">

            select * from phone

        </select>

        <!-- 一对一映射时自动被执行 -->

        <select id="selectBrand"   resultType="BrandModel" parameterType="int">

           select * from brand where id = #{brandId}

        </select>

用法:

        select属性:在一对一映射的时候,自动调用 另外一条查询语句,将查询语句的返回

                            值,映射到 property所指定的属性上

        column属性:指定的是查询后的一个列名可传递一个参数,也可传递多个 传递一个

                            直接写需要传递的列名即可传递多个参数:

                        {phoneName=phone_name,brandId=brand_id}

                            等号左面是 参数名,在第二条语句中获取的名字

                            等号右面是  需要传递的列名

        fetchType属性:延迟加载 将fetchType指定为lazy则为延迟加载 只有嵌套查询的方

                            式 延迟加载才能生效

17.一对多关系查询

   (只展示resultMap部分,select部分和上面一样)

        <resultMap type="BrandModel" id="brandMap">

            <id column="b_id" property="id"/>

            <result column="brand_name" property="brandName"/>

            <collection property="phoneList" autoMapping="true" ofType="PhoneModel">

            <id column="id" property="id"/>

            <!-- 其他属性交给驼峰进行自动映射 -->

            </collection>

        </resultMap>

        collection标签作用:一对多的映射

        property属性:list集合在实体类中的属性名

        ofType属性:list集合中实体类的类型(尖括号中的类型)

18.嵌套的一对多查询

        <!-- 嵌套的一对多映射 -->

        <resultMap type="BrandModel" id="queryMap">

            <id column="id" property="id"/>

            <result column="brand_name" property="brandName"/>

            <collection property="phoneList" ofType="PhoneModel" 

                select="selectPhoneByBrandId" column="id">

            </collection>

        </resultMap>

        <select id="selectPhone" resultMap="queryMap">

        select * from brand

        </select>

        <select id="selectPhoneByBrandId" 

            resultType="PhoneModel" parameterType="int">

        select * from phone where brand_id = #{brandId}

        </select>

19.Constructor标签

  作用:实例化有带参的构造方法的对象

  用法:

        <resultMap type="BrandModel" id="conMap">

        <constructor>

            <idArg column="id" javaType="int"/>

            <arg column="brand_name" javaType="string"/>

        </constructor>

        </resultMap>

 注意:实体类中必须有带参数的构造

            如果在<idArg><arg >标签中没有指定name属性,映射的顺序要和 有参构造中参

            数顺序一致





 



        

            


    





以上是关于Mybatis知识汇总的主要内容,如果未能解决你的问题,请参考以下文章

计算机网络知识点汇总

JDBC核心知识点汇总

什么是ZK-Rollup(零知识汇总)?

css3知识汇总:切角

EWM常规开发知识汇总

java 零散知识汇总(初级)