Mybatis

查询接收是int类型的时候用包装类(null)

更新和删除修改用int

删除多余,号

<trim suffixOverrides=",">

模糊查询

"%"#{}"%"
concat('%',#{},'%')

在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用来解决。

数据库查出来字段名real_time对应JavaBean的变量realTime

数据库查询出来字段名realTime,那JavaBean就要加@TableField来映射

if

判断字符串是否等于

判断字符串是否包含contains

        SELECT count(1) FROM [dbo].[ttaskmainls]
        <where>
            <if test="construction != null and construction != '' and construction=='plans'.toString()">
                and  rwflag=1
            </if>
            <if test="construction != null and construction != '' and construction=='temporary'.toString()">
                and  rwflag=0
            </if>
        </where>
select isnull(count(rwgdh), 0) as count
        from ttaskmainls
        where jzflag != 3 and jzflag != 10 and jzflag != 11 and jzflag != 88
        <if test="rwmbdmList != null and rwmbdmList.size() > 0">   
            and
            <foreach collection="rwmbdmList" item="rwmbdm" open="(" close=")" separator="or"><![CDATA[
                rwmbdm = #{rwmbdm}
            ]]></foreach>
        </if>
        <if test="rwmbdm != null and rwmbdm != ''"> and rwmbdm = #{rwmbdm} </if>
        <if test="rwmbdm == '31221'"> and jzStep > 1 </if>
        <if test="secondType.contains('new')"> and YEAR(cjsj) = YEAR(getdate())  </if>
        <if test="secondType.contains('wks')"> and jzflag = 0 </if>
        <if test="secondType.contains('ing')"> and 99 > jzflag </if>
        <if test="secondType.contains('ed')"> and jzflag = 99 </if>
        <if test="secondType.contains('today')"> and CONVERT(VARCHAR(10), cjsj, 120) = CONVERT(VARCHAR(10), getdate(), 120) </if>
        <if test="secondType.contains('thisMonth')"> and CONVERT(VARCHAR(7), cjsj, 120) = CONVERT(VARCHAR(7), getdate(), 120) </if>
        <if test="secondType.contains('thisQuarter')"> and CONVERT(VARCHAR(4), cjsj, 120) = CONVERT(VARCHAR(4), getdate(), 120) and DATENAME(QUARTER,cjsj) = DATENAME(QUARTER,GETDATE()) </if>
        <if test="secondType.contains('thisYear')"> and CONVERT(VARCHAR(4), cjsj, 120) = CONVERT(VARCHAR(4), getdate(), 120) </if>
        <if test="secondType == 'day'"> and CONVERT(VARCHAR(10), cjsj, 120) = #{day} </if>
        <if test="taskBmdm != null and taskBmdm != ''"> and task_bmdm = #{taskBmdm} </if>
        <if test="wcflag == '1'.toString()"> and jzflag = 99 </if>
        <if test="wcflag == '0'.toString()"> and 99 > jzflag </if>
    </select>

if else

<select id="selectUserByState" resultType="com.bz.model.entity.User">
    SELECT
      *
    FROM
      user
    WHERE
      1=1
    <choose>
      <when test="state == 1">   --if
        AND name = #{name1}
      </when>
     <when test="state == 2">
        AND name = #{name2}
      </when>
      <otherwise>               -- else
        AND name = #{name3}
      </otherwise>
    </choose>
  </select>

可以嵌套使用

        select * from t_contract_complaint
        <where>
            <choose>
                <when test="complaintPeopleId != null and complaintPeopleId !='' and receiveComplaintPeopleId != null and receiveComplaintPeopleId != ''">
                    complaint_peopleId = #{complaintPeopleId} or receive_complaint_peopleId = #{receiveComplaintPeopleId}
                </when>
                <otherwise>
                    <if test="complaintPeopleId != null and complaintPeopleId !=''">
                        and complaint_peopleId = #{complaintPeopleId}
                    </if>
                    <if test="receiveComplaintPeopleId != null and receiveComplaintPeopleId !=''">
                        and receive_complaint_peopleId = #{receiveComplaintPeopleId}
                    </if>
                </otherwise>
            </choose>
        </where>

where

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

set

这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

foreach

循环插入数据的时候列不要大于20 条数不要大于50 要不然 性能问题 很慢

可以二维数组

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

collection #数组名
item #临时遍历数组
separator  #遍历元素的连接对象
<foreach collection="items" item="item" separator=",">
select position_all_name as jtzh,longitude,latitude from t_assets_position where position_all_name in
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>

插入数据

   <insert id="insertList" parameterType="java.util.List">
        insert into active_send_push_value_config (send_push_id, value)
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (
              #{item.sendPushId,jdbcType=INTEGER},
              #{item.value,jdbcType=VARCHAR}
            )
        </foreach>
    </insert>

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

resultmap

<resultMap id="BaseResultMap" type="com.eagle.system.entity.Building">
  <id column="id" jdbcType="DECIMAL" property="id" />
  <result column="name" jdbcType="VARCHAR" property="name" />
  <result column="system_id" jdbcType="VARCHAR" property="systemId" />
  数据库列字段     字段类型    实体类属性
  </resultMap>
<resultMap id="tjhxjtasklsLz" type="com.eagle.business.ablock_lz.entity.TjhxjtasklsLz">
        <id column="rwgdh" property="rwgdh"/>
        <result column="zrczy" property="zrczy"/>
        <result column="zrczyxm" property="zrczyxm"/>
        <collection property="tczytasklsList" ofType="com.eagle.business.ablock_common.entity.Tczytaskls">
            <result column="zxczy" property="zxczy"/>
            <result column="zxczyxm" property="zxczyxm"/>
            <result column="jlsj" property="jlsj"/>
        </collection>

    </resultMap>
查数据   查出10条 查出来的数据 只有collection里边的字段内容不一样时 会合并一条 显

如果是list(string)

<resultMap type="User" id="user_map">
    <id property="id" column=""/>
    <result property="username" column="username"/>
    <collection property="age" ofType="int">
        <constructor>
            <arg column="age"/> <!-- 对号入座数据库column名称即可 -->
        </constructor>
    </collection>
    <collection property="authorities" ofType="java.lang.String">
        <constructor>
            <arg column="permission"/>  <!-- 对号入座数据库column名称即可 -->
        </constructor>
     </collection>
</resultMap>
parameterType="com.eagle.business.ablock_task.dto.SelectFaultrepairStatistics"

参数判断问题

<where>
    <if test="time != null and time != ''">
        CONVERT(varchar(8),a.time,112)  = #{time}
    </if>
    <if test="fieid != null and fieid !='' ">
        AND a.field = #{fieid}
    </if>
    <if test="state != null">
        AND a.state = #{state}
    </if>
</where>

integer 只判断不为null

时间要做处理

前端不要传参数 '' 不是null 'null' 不一样

结果映射map

一条记录就算一个map集合 字段名就算 key 值就算 value

mapper 接收 List<Map<String,Integer>>

resultType="java.util.Map"

两种结果形式list(map) | map(map)

一种是一行一个map 的形式 map的key 就是字段名 这种是多行要用list(map)接收

list<map>

一种是 返回结果是一个map类型 @MapKey("czyxm")

map里边套map 每一行要自定一个key

Map<String,ob>

双层list

image-20220107095722076

    insert into tbl_road_driving_offline (distance, status, polyline, light_speed, row_num, insert_time, drive_id)
    values
    <foreach collection="temporaryMaps" item="items" separator=",">
      <foreach collection="items" item="item" separator=",">
        (#{item.distance}, #{item.status}, #{item.polyline}, #{item.lightSpeed}, #{item.rowNum}, #{item.insertTime}, #{item.driveId})
      </foreach>
    </foreach>

Mybatis传入参数问题

parameterType 写实体类 可以直接写属性名

mybatis传参的几种方式

目录
第一种情形,传入单个参数 userId
第二种情况,传入多个参数 userId,sex 使用索引对应值
第三种情形,传入多个参数 userId,sex 使用注解@Param
第四种情形,传入多个参数 使用User实体类传入
第五种情形,传入多个参数, 使用Map类传入
第六种情形,传入多个参,使用 map封装实体类传入
第七种情形,即需要传入实体类,又需要传入多个单独参,使用注解@Param
List传参
数组传参
${}

首先大家都清楚,Mybatis里面传参方式分别有使用 #{} 和 ${}。

对于使用$符存在安全问题的,该篇不做分析和介绍(其实就是如果传参的话,使用$需要手动拼接‘ ' ,这就存在注入的风险)

接下来,进入正题,通过简单举例介绍,

{}

第一种情形,传入单个参数 userId
service层:
@Override
public User getUserInfo(Integer userId) {
User user = userMapper.getUserInfo(userId);
//省略 业务代码...
return user;
}

mapper层:
User getUserInfo(Integer userId);
mapper.xml:

第二种情况,传入多个参数 userId,sex 使用索引对应值

按照顺序传参
注意mapper层和xml层!
service层:
@Override
public User getUserInfo(Integer userId,String sex) {
User user = userMapper.getUserInfo(userId,sex);
//省略 业务代码...
return user;
}
mapper层:
User getUserInfo(Integer userId,String sex);
mapper.xml:

第三种情形,传入多个参数 userId,sex 使用注解@Param service层: @Override public User getUserInfo(Integer userId,String sex) { User user = userMapper.getUserInfo(userId,sex); //省略 业务代码... return user; } mapper层: User getUserInfo(@Param("userId")Integer userId,@Param("sex")String sex); mapper.xml:

第四种情形,传入多个参数 使用User实体类传入
service层:
@Override
public User getUserInfo(User user) {
User userInfo = userMapper.getUserInfo(user);
//省略 业务代码...
return userInfo;
}
mapper层:
User getUserInfo(User user);
mapper.xml:

第五种情形,传入多个参数, 使用Map类传入
service层:
@Override
public User getUserInfo(Map map) {
User user = userMapper.getUserInfo(map);
//省略 业务代码...
return user;
}
mapper层:
User getUserInfo(Map map);
mapper.xml层:

第六种情形,传入多个参,使用 map封装实体类传入
这种情况其实使用场景比较少,因为上面的各种姿势其实已经够用了
service层:
@Override
public User getUserInfo1(Integer userId,String sex) {
User userInfo = new User(userId,sex);
Map<String,Object> map=new HashMap<String,Object>();
map.put("user",userInfo);
User userResult= userMapper.getUserInfo(map);
//省略 业务代码...
return userResult;
}
mapper层:
User getUserInfo(Map map);
mapper.xml:

第七种情形,即需要传入实体类,又需要传入多个单独参,使用注解@Param
service层:
@Override
public User getUserInfo(User user,Integer age) {
User userResult = userMapper.getUserInfo(user,age);
//省略 业务代码...
return userResult;
}
mapper层:
User getUserInfo(@Param("userInfo") User user,@Param("age") Integer age);
mapper.xml:

List传参
service层:
Listlist= new ArrayList>();
list. add(44);
list. add(45);
list. add(46);
List sysUser= sysUserMapper. selectList(list);

mapper层:
List selectList(List ids);
mapper.xml:
<select id="selectList"resultMap"BaseResultMap">
select

from sys_user
where id in
<foreach item="item" index="index" collection="list"open="("separator","close=")"> #{item}

数组传参
service层:
List sysuser= sysUserMapper. selectlist(new Integer[]{44,45,46});
mapper层:
List selectList(Integer[]ids);

mapper.xml:
<select id="selectList"resultMap"BaseResultMap">
select

from sys user
where id in
<foreach item="item" index="index collection="array"open="("separator="," close=")"> #{item}


${}

使用这个的时候,只需要注意,如果是传递字段名或者表名,是直接做参数传入即可,
但是如果作为sql'语句里面使用的值, 记得需要手动拼接 ' ' 号。

例如, 传入单个参数 sex:
service层:
@Override
public User getUserInfo(String sex) {
sex="'"+sex+"'";
User user = userMapper.getUserInfo(sex);
//省略 业务代码...
return user;
}
mapper层:
User getUserInfo(String sex);
mapper.xml:

多个参数,那也就是使用注解@Param取名字解决即可。
posted @ 2021-10-29 14:11  李广龙  阅读(46)  评论(0)    收藏  举报