• 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>
    
  • 相关阅读:
    合理配置SQL Server的最大内存
    理解内存----优化SQL Server内存配置
    Systems Performance: Enterprise and the Cloud 读书笔记系列
    google perftools分析程序性能
    源代码分析-构建调用图
    Intel VTune性能分析器基础
    代微机原理与接口技术(第3版)课程配套实验包和电子课件
    【MySQL性能优化】MySQL常见SQL错误用法
    Linux 内核分析 -- Linux内核学习总结
    《Linux就该这么学》 软件库
  • 原文地址:https://www.cnblogs.com/xiaoaiying/p/14052910.html
Copyright © 2020-2023  润新知