mybatis动态查询得相关点

1、

<resultMap id="BaseResultMap" type="com.ccssoft.entity.physical.Metype">
        <id column="ID" jdbcType="BIGINT" property="id" />
        <result column="VERSION" jdbcType="INTEGER" property="version" />
        <result column="NAME" jdbcType="VARCHAR" property="name" />
        <result column="MODEL" jdbcType="VARCHAR" property="model" />
        <result column="CATEGORY" jdbcType="BIGINT" property="category" />
     </resultMap>

    <sql id="Base_Column_List">
    ME.ID, ME.VERSION, ME.NAME, ME.MODEL, ME.CATEGORY
  </sql>
    <select id="pageFindAllMetypeSelective" resultMap="BaseResultMap" >
        SELECT DISTINCT
        <include refid="Base_Column_List"/>
        FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID=MDL.METYPEID
        WHERE 1=1
        <if test="name!=null and name!=''">
--             AND ME.NAME LIKE concat'%'||#{name}||'%'
            AND ME.NAME LIKE CONCAT('%',CONCAT(#{name},'%'))
        </if>
        <if test="ip!=null and ip!=''">
            AND MDL.IPADDRESS LIKE CONCAT('%',CONCAT(#{ip},'%'))
        </if>
        <if test="emsId!=null and emsId.size()>0">
            AND MDL.EMSID IN
            <foreach collection="emsId" item="item" open="(" close=")" separator=",">
            #{item}
            </foreach>
        </if>

        <if test="deviceType!=null and deviceType.size()>0">
            AND  MDL.DEVICETYPE IN
            <foreach collection="deviceType" item="devicetp" separator="," close=")" open="(">
                #{devicetp,jdbcType=BIGINT}
            </foreach>
        </if>
        ORDER BY ME.ID DESC

    </select>

这是一个写动态mybatis得一个例子,就这个例子我做一下总结:

  1. resultMap中是一个类所有的属性,只是因为返回得是集合类型,所以这样更方便一点,也可以将数据库中得字段和实体类中得属性对应起来,手动结合。

  resultMap比较强大,这里借鉴别人得(https://www.cnblogs.com/kenhome/p/7764398.html)。resultMap可以将多个表中得数据映射到一个结果集当中。

    这里又出来一个问题:映射得结果怎么接:百度和问了别人这里又俩种方法接:

      1、一种是新建一个对象去接,和返回得属性一一对应得。

      2、返回list这种得,但是这种得不利于后期得维护,很可能找不到返回得是什么。不直观。

    

<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
  <id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
  <result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
    <id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/>
    <result  column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
  </association>
  <!-- 集合中的property须为oftype定义的pojo对象的属性-->
  <collection property="pojo的集合属性" ofType="集合中的pojo对象">
    <id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
    <result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />  
  </collection>
</resultMap>

       其中如果:

<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
    <id column="ID" jdbcType="BIGINT" property="id" />
    <result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
    <result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
    <collection property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" > 
        <id column="AttributeID" jdbcType="BIGINT" property="id" />
        <result column="attribute_NAME" jdbcType="VARCHAR" property="attributeName" />
    </collection>
</resultMap>
复制代码

这里俩个表的实体类里面属性都是id命名的,但是表里面的不是同一个字段,如果在表里是同一个字段的话会报错。

这里的

<association>是所一对一的关系,也就是在这个实体类里面定义了其一对一的类:private User user;
 <collection>是一对多的关系,也就是这个实体类里定义返回一个类的集合:private List<User> users;
这个和连接是不一样的,这个叫关联映射,那个叫连接。这样写可以得到一个全新的映射对象。

如果collection标签是使用嵌套查询,格式如下:

 <collection column="传递给嵌套查询语句的字段参数" property="pojo对象中集合属性" ofType="集合属性中的pojo对象" select="嵌套的查询语句" > 
 </collection>

注意:<collection>标签中的column:要传递给select查询语句的参数,如果传递多个参数,格式为column= ” {参数名1=表字段1,参数名2=表字段2} ;     

  1. 当有外部表连接时
      SELECT DISTINCT
            <include refid="Base_Column_List"/>
            FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID=MDL.METYPEID

    可以指定表,给表一个别名。并且要把俩个表通过什么连接要写。

  2. java中的long对应数据库中的bigint,但是要大写,这里如果是在<resultMap>标签里的话jdbcType=“BIGINT”,但是如果不在标签里可以这样写
    #{devicetp,jdbcType=BIGINT}  //这里不用写双引号,

    因为在这里是俩张表查,在前面只指定了前一张表的jdbc类型,没有指定另外一张的,所以要指定,否则会报错。

  3. <sql>里面的代码时共用的代码。
  4. 如果这里写动态的数据库代码就是会生成日志的时候写出一个
     SELECT count(0) FROM (SELECT DISTINCT ME.ID, ME.VERSION, ME.NAME, ME.MODEL, ME.CATEGORY FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID = MDL.METYPEID WHERE 1 = 1 AND ME.NAME LIKE CONCAT('%', CONCAT(?, '%')) AND MDL.DEVICETYPE IN (?, ?, ?, ?, ?, ?, ?, ?)) table_count 

    这里的前面的东西是自动的。

  5.  <if test="ip!=null and ip!=''">
                AND MDL.IPADDRESS LIKE CONCAT('%',CONCAT(#{ip},'%'))
            </if>

    这里的ip是传过来的值,然而如果我们查的是另外一个表的东西的话,可以写上

    MDL.IPADDRESS    这样的东西,只要和传过来的东西比较就行。这里要判断不为null也不为没有数据
  6. 动态查询连接的话用这样写
    CONCAT('%',CONCAT(#{ip},'%'))  

  7. <if test="emsId!=null and emsId.size()>0">
                AND MDL.EMSID IN
                <foreach collection="emsId" item="item" open="(" close=")" separator=",">
                #{item}
                </foreach>
            </if>

    这里要先判断是不是null再判断size(),否则可能里卖弄都是几个空,也有大小,但是已经满足了条件,就进去了。
    collection属性是写传过来的List集合的对象名 item可以自己取名。

  8. where 1=1在动态数据库查询中的作用?(https://blog.csdn.net/u012195214/article/details/73522489
    参考了别人的。可以预防动态后面都不成立的时候sql语句不对,一般里面有and,动态的不成立还行,成立的话and会拼接。
    这里可以消除and就是用<WHERE>标签,这下我也懂了where和其标签的不同之处了
posted @ 2020-09-09 21:41  一个想飞的菜鸟  阅读(192)  评论(0编辑  收藏  举报