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得一个例子,就这个例子我做一下总结:
- 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} ;
- 当有外部表连接时
SELECT DISTINCT <include refid="Base_Column_List"/> FROM METYPE ME LEFT JOIN MANAGEDELEMENT MDL ON ME.ID=MDL.METYPEID
可以指定表,给表一个别名。并且要把俩个表通过什么连接要写。
- java中的long对应数据库中的bigint,但是要大写,这里如果是在<resultMap>标签里的话jdbcType=“BIGINT”,但是如果不在标签里可以这样写
#{devicetp,jdbcType=BIGINT} //这里不用写双引号,
因为在这里是俩张表查,在前面只指定了前一张表的jdbc类型,没有指定另外一张的,所以要指定,否则会报错。
- <sql>里面的代码时共用的代码。
- 如果这里写动态的数据库代码就是会生成日志的时候写出一个
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
这里的前面的东西是自动的。
-
<if test="ip!=null and ip!=''"> AND MDL.IPADDRESS LIKE CONCAT('%',CONCAT(#{ip},'%')) </if>
这里的ip是传过来的值,然而如果我们查的是另外一个表的东西的话,可以写上
MDL.IPADDRESS 这样的东西,只要和传过来的东西比较就行。这里要判断不为null也不为没有数据
- 动态查询连接的话用这样写
CONCAT('%',CONCAT(#{ip},'%'))
-
<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可以自己取名。 - where 1=1在动态数据库查询中的作用?(https://blog.csdn.net/u012195214/article/details/73522489)
参考了别人的。可以预防动态后面都不成立的时候sql语句不对,一般里面有and,动态的不成立还行,成立的话and会拼接。
这里可以消除and就是用<WHERE>标签,这下我也懂了where和其标签的不同之处了
along