• mybatis复习笔记----关于标签


    关于sql操作

    一 、定义SQL语句

    • 【select】
        属性介绍:
         id :唯一的标识符.
         parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User或user
         resultType :语句返回值类型或别名。注意,如果是集合,那么这里填写的
         是集合的泛型,而不是集合本身(resultType 与resultMap 不能并用)
       例子:
         sql:
          <select id="userList" parameterType="user" resultType="User">
            select * from user where name =#{name}
          </select>
    
    • 【insert】
        属性介绍:
          id :唯一的标识符
          parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User
    
    • 【delete】
        例子:
        <delete id="deleteUser" parameterType="int"> 
          delete from user 
          where id = #{id} 
        </delete>
    
    • 【update】
          类似于insert
    

    二、配置对象属性与查询结果集

    • 【resultMap】
      • 建立SQL查询结果字段与实体属性的映射关系信息
      • 查询的结果集转换为java对象,方便进一步操作
      • 将结果集中的列与java对象中的属性对应起来并将值填充进去
      • 注意:与java对象对应的列不是数据库中表的列名,而是查询后结果集的列名
    例:
    <resultMap id="getStudentRM" type="EStudnet">
        <id property="id" column="ID"/>
        <result property="studentName" column="Name"/>
        <result property="studentAge" column="Age"/>
    </resultMap>
    <select id="getStudent" resultMap="getStudentRM">
        SELECT ID, Name, Age
        FROM TStudent
    </select>
    
    resultMap标签属性:
        id:该resultMap的标志
        type:返回值的类名,此例中返回EStudnet类
    resultMap标签下的子标签:
        id:用于设置主键字段与领域模型属性的映射关系,此处主键为ID,对应id。
        result:用于设置普通字段与领域模型属性的映射关系
    

    【association】 一对一
    【collection】 一对多
    上面两个标签在resultmap中使用,可以通过嵌套结果集(即在标签里再通过result标签来对应属性),也可以通过另一接口方法查询后获得结果集。

    resultMap标签自定义结果集

    联合查询以及association通过嵌套结果集的使用

    collection通过调用其他接口方法使用
    相关属性:

    select:表示调用另一个接口的查询方法
    column:将哪一列的值传递过去作为另一接口方法的参数 , 可以传递一个map类型的参数,例如:column="key1=column1, key2=column2}"
    property:查询结果返回后封装到当前pojo哪一个属性。
    fetchType: 设置延迟加载 ="lzay"

    【discriminator】
    鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为封装Employee:
    如果查出的是女生:就把部门信息查询出来,否则不查询;如果是男生,把last_name这一列的值赋值给email;

    例如:
    <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpDis">
        <id column="id" property="id" / >
        <result column="last_name " property= "LastName"/>
        <result column="email" property="email"/ >
        <result column="gender" property="gender"/ >
        <discriminator javaType="string" column="gender">
            <!--女生resultType :指定封装的结果类型﹔不能缺少。resultMap-->
            <case value="0" resultType= "com.atguigu.mybatis.bean. Emp
                <association property="dept" select="com.atguigu.mybatis.dao.DepartmentMapper" column="d_id"></association>
            </case>
            <!--男生;如果是男生,把last_name这一列的值赋值给email; -->
            <case value="1" resultType="com.atguigu.mybatis.bean.Em . Empl
                 <id column="id" property="id"/>
                 <result column="Last_name" property="LastName" />
                 <result column= "last_name" pPoperty="emaiL" />
                 <result column= "gender" property="gender" />
            </case>
        </discriminator>
    </resultMap>
    

    三、动态拼接SQL标签

    • 【if】
      通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段,还可以在INSERT语句中用来判断是否插入某个字段的值
    例:
    <select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBL ST       
        WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
    </select> 
    

    但是此时如果studentName是null或空字符串,此语句很可能报错或查询结果为空。此时我们使用if动态sql语句先进行判断,如果值为null或等于空字符串,我们就不进行此条件的判断。

    修改为:
    <select id=" getStudentListLikeName " parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBL ST      
        <if test="studentName!=null and studentName!='' ">     
            WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
        </if>     
    </select>    
    
    • 【foreach】
      主要用于构建in条件,他可以在sql中对集合进行迭代。如下:
      <delete id="deleteBatch"> 
        delete from user where id in
        <foreach collection="array" item="id" index="index" open="(" close=")" separator=",">
          #{id}
        </foreach>
      </delete>
       假如说参数为----int[] ids = {1,2,3,4,5}----那么打印之后的SQL如下:
      delete form user where id in (1,2,3,4,5)
      foreach属性释义:
       collection :collection属性值有三个(分别是list、array、map),分别对应的参数类型为(List、数组、map集合);上面传的参数为数组,所以值为array,但是如果接口在传递参数时使用了@Param注解,则可以使用自己定义的名称
       item : 表示在迭代过程中每一个元素的别名
       index :表示在迭代过程中每次迭代到的位置(下标)
       open :前缀
       close :后缀
       separator :分隔符,表示迭代时每个元素之间以什么分隔
       我们通常可以将之用到批量删除、添加等操作中。
    
    • 【choose】
      从多个选项中选择一个。MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。
      当choose中所有when的条件都不满则时,则执行 otherwise中的sql。
      类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。if是与(and)的关系,而choose是或(or)的关系。
    例:
    <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBLST      
        <where>     
            <choose>     
                <when test="studentName!=null and studentName!='' ">     
                        ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
                </when>     
                <when test="studentSex!= null and studentSex!= '' ">     
                        ST.STUDENT_SEX = #{studentSex}      
                </when>     
                <when test="studentBirthday!=null">     
                       ST.STUDENT_BIRTHDAY = #{studentBirthday}      
                </when>     
                <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">     
                       ST.CLASS_ID = #{classEntity.classID}      
                </when>     
                <otherwise>     
                       1=1 
                </otherwise>     
            </choose>     
        </where>     
    </select>     
    

    四、格式化输出

    • 【where】
    <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBL ST      
            WHERE 
            <if test="studentName!=null and studentName!='' ">     
                AND ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
            </if>     
            <if test="studentSex!= null and studentSex!= '' ">     
                AND ST.STUDENT_SEX = #{studentSex}      
            </if>     
    </select>     
    

    如果上面例子,参数studentName为null或’’,则或导致此sql组合成“WHERE AND”之类的关键字多余的错误SQL。
    这时我们可以使用where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
    上面例子修改为:

    <!-- 查询学生list,like姓名,=性别 -->     
    <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBL ST      
        <where>     
            <if test="studentName!=null and studentName!='' ">     
                ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
            </if>     
            <if test="studentSex!= null and studentSex!= '' ">     
                AND ST.STUDENT_SEX = #{studentSex}      
            </if>     
        </where>     
    </select>     
    
    • 【set】
      当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。
      使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
      没有使用if标签时,如果有一个参数为null,都会导致错误,如下示例:
    <!-- 更新学生信息 -->     
    <update id="updateStudent" parameterType="StudentEntity">     
        UPDATE STUDENT_TBL      
           SET STUDENT_TBL.STUDENT_NAME = #{studentName},      
               STUDENT_TBL.STUDENT_SEX = #{studentSex},      
               STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
               STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
         WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
    </update>     
    

    使用set+if标签修改后,如果某项为null则不进行更新,而是保持数据库原值。如下示例:

    <!-- 更新学生信息 -->     
    <update id="updateStudent" parameterType="StudentEntity">     
        UPDATE STUDENT_TBL      
        <set>     
            <if test="studentName!=null and studentName!='' ">     
                STUDENT_TBL.STUDENT_NAME = #{studentName},      
            </if>     
            <if test="studentSex!=null and studentSex!='' ">     
                STUDENT_TBL.STUDENT_SEX = #{studentSex},      
            </if>     
            <if test="studentBirthday!=null ">     
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
            </if>     
            <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">     
                STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
            </if>     
        </set>     
        WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
    </update>     
    
    • 【trim】
      trim(拼接字符串)是更灵活的去处多余关键字的标签,他可以实践where和set的效果。
    trim标签相关属性说明:
        prefix=""             前缀----trim标签体中是整个字符串拼串后的结果。prefix给拼串后的整个字符串加一个前缀
        prefixOverrides=""    前缀覆盖----去掉整个字符串前面多余的什么字符
        suffix=""             后缀----suffix给拼串后的整个字符串加一个后辍
        suffixOverrides=" "   后缀覆盖----去掉整个字符串后面多余的什么字符
    

    where例子的等效trim语句:

    <!-- 查询学生list,like姓名,=性别 -->     
    <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">     
        SELECT * from STUDENT_TBL ST      
        <trim prefix="WHERE" prefixOverrides="AND|OR">     
            <if test="studentName!=null and studentName!='' ">     
                ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
            </if>     
            <if test="studentSex!= null and studentSex!= '' ">     
                AND ST.STUDENT_SEX = #{studentSex}      
            </if>     
        </trim>     
    </select>  
    

    set例子的等效trim语句:

    <!-- 更新学生信息 -->     
    <update id="updateStudent" parameterType="StudentEntity">     
        UPDATE STUDENT_TBL      
        <trim prefix="SET" suffixOverrides=",">     
            <if test="studentName!=null and studentName!="">     
                STUDENT_TBL.STUDENT_NAME = #{studentName},
            </if>     
            <if test="studentSex!=null and studentSex!=" ">     
                STUDENT_TBL.STUDENT_SEX = #{studentSex}, 
            </if>     
            <if test="studentBirthday!=null ">     
                STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
            </if>     
            <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">     
                STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
            </if>
        </trim>     
        WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
    </update>     
    

    五、配置关联关系

    • 【association】标签
      一对一
      association通常用来映射一对一的关系,例如,有个类user,对应的实体类如下:(getter,setter方法省略)
    private String id;//主键
    private String userName;//用户姓名
    

    有个类Article,对应的实体类如下:

    private String id;//主键
    private String articleTitle;//文章标题
    private String articleContent;//文章内容
    

    如果我想查询一个用户的时候,也查到他写的一篇文章,可以怎样写呢?在类user加入一个属性article

       private String id;//主键
       private String userName;//用户姓名
       private Article article;//新增的文章属性
    

    2、mapper.xml 我在user类的mapper.xml这样配置

    
    <resultMap id="userResultMap" type="test.mybatis.entity.User">
        <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
        <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
        //这里把user的id传过去
        <-- 属性:
            select:表示调用另一个接口的查询方法
            column:将那一列的值传递过去作为另一接口方法的参数
            property:查询结果返回后封装到当前pojo哪一个属性。
          -->
        <association property="article" column="id" select="test.mybatis.dao.articleMapper.selectArticleByUserId"/>//test.mybatis.dao.articleMapper为命名空间
    </resultMap>
    

    同时,我的article对应的xml这样写:

    <resultMap id="articleResultMap" type="test.mybatis.entity.Article">
        <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
        <result column="articleTitle" property="articleTitle" jdbcType="VARCHAR" javaType="java.lang.String"/>
        <result column="articleContent" property="articleContent" jdbcType="VARCHAR" javaType="java.lang.String"/>
    </resultMap>
      (当然,这里还有查询user表的语句,省略)
    

    同时,在article对应的xml有这样的select语句:

    <select id="selectArticleByUserId" parameterType="java.lang.String" resultMap="ArticleResultMap">
        select * 
        from tb_article where userId=#{userId} 
    </select>
    
    • 【collection】标签
      一对多
      实体类增加对应属性
    private String id;//主键
    private String userName;//用户姓名
    private List<Article> articleList;
    

    userMapper.xml这样配置

    <resultMap id="userResultMap" type="test.mybatis.entity.User">
        <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
        <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
        //这里把user的id传过去
        <collection property="articleList" column="id" select="test.mybatis.dao.articleMapper.selectArticleListByUserId" />
    </resultMap>
    以下省略,类同,Mybatis会把结果封装成List类型。
    

    如果我还想通过Article表另一张表,比如文章中有个fk_id,也可以像上面这样重复配置,把fk_id当做与另一张表关联的参数,那时就可以通过用户查到文章,查到文章关联的另一张表了。

    六、标签
    【bind】
    可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值

    属性:
    name:相当于变量名
    value:变量值,可以动态拼接,即可以写ognl表达式
    使用时,直接使用变量即可,
    

    【sql】
    更多用于写sql语句的一部分,就像写在配置文件中的sql常量

    【include】
    用于引用常量,也可以定义属性property,
    sql标签内部就能使用自定义的属性
    但取值的正确方式是${prop},不能使用#{prop}这种方式

    参考:https://blog.csdn.net/weixin_40950778/article/details/78655288

    全局配置文件中的一些标签

    • 【properties】标签
      引入外部properties配置文件的内容;
    属性:
    1---resource:引入类路径下的资源
    2---url:引入网络路径或者磁盘路径下的资源
    
    • 【settings】标签
      用于设置mybatis的运行时行为
      例如:缓存、懒加载、驼峰命名策略等等等。
    • 【typeAliases】标签
      对javabean进行重命名,重命名后在接口对应配置文件.xml中返回类型填写时可以不用填写全限定类名,不过推荐填写全限定类名
      注意:如果用package 进行重命名,若指定包下的子包包含和父包一样类名的类,会报错。
      1----对单个进行重命名
    例如:
    <typeAliases>
        <typeAlias alias="Author" type="domain.blog.Author" />
        <typeAlias alias="Blog" type="domain.blog.Blog" />
        <typeAlias alias="Comment" type="domain.blog.Comment"/>
        <typeAlias alias="Post" type="domain.blog.Post" />
        <typeAlias alias="Section" type="domain.blog.section"/>
        <typeAlias alias="Tag" type="domain.blog . Tag" />
    </typeAliases>
    

    2----对多个进行重命名
    多个重命名就是指定包名,默认命名为类名小写

    例如:
    <typeAliases>
        <package name="domain.blog" />
    </typeAliases>
    

    3----也可以在实体类上通过注解@alias实现类重命名

    • 【databaseIdProvider】标签
      mybatis根据不同的数据库厂商执行不同的执行sql
    例如:
    <databaseIdProvider type="DB_VENDOR">
        <! --为不同的数据库厂商起别名–->
        <property name="MysQL " value= "mysql" />
        <property name="Oracle" value="oracle" / >
    </databaseIdProvider>
    

    在slq标签里通过databaseId="databaseIdProvider标签下数据库取的名称"指定

    例如:
    <select id="getEmpById" resultType="com.xiaoai.empUser" databaseId="mysql">
        select *
        from tbl_employee 
        where id = #{id}
    </select>
    
    • 【mapper】标签
      引入接口对应slq映射文件.xml
    <configuration>
      <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
      <mappers>
          <mapper resource="com/xiaoai/dao/IUserDao.xml"/>
      </mappers>
    </configuration>
    
    属性:
    resource引用类路径下的sql映射文件
    url 引用网路路径或磁盘下的sql映射文件
    class 引用(注册)接口全限定类名: 1-如果用注解,就是引入接口类。2-如果是映射文件,映射文件必须和接口同名,并且放在接口同一目录下;
    
    • 【package】标签
      注意:mappers下的package和重命名标签中的package区别:一个指定实体类包,一个指定dao包
    <mappers>
        <!-- 用于指定Dao接口所在的包,当指定了之后就不需要再写mapper标签resource或者class属性了 -->
        <package name="com.xiaoai.dao"/>
    </mappers>
    
  • 相关阅读:
    最大子数组求和并进行条件组合覆盖测试
    Ubuntu 16.04 c++ Google框架单元测试
    The directory '/home/stone/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If execu
    Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/cache/app-info -a -e /usr/bin/appstreamcli; then appstreamcli refresh > /dev/null; fi'
    个人博客作业三:微软小娜APP的案例分析
    补交 作业一
    补交 作业二:个人博客作业内容:需求分析
    嵌入式软件设计第12次实验报告
    嵌入式软件设计第11次实验报告
    嵌入式软件设计第10次实验报告
  • 原文地址:https://www.cnblogs.com/xiaoaiying/p/14052910.html
Copyright © 2020-2023  润新知