Mybaits中if、choose、foreach标签的使用

本文详细介绍了Mybatis中的if、choose和foreach标签的使用方法。通过示例展示了如何根据条件动态改变SQL语句,实现灵活的数据查询。if标签用于条件判断,choose类似Java的switch语句,foreach则用于处理集合参数,构建IN语句。通过对不同ID的测试,验证了这些标签在实际操作中的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用mybatis的时候,经常会使用到一些特殊的标签,这些标签,可以动态改变sql语句的查询条件,查询的字段等,通过使用这些特殊的标签,在mybatis的数据库sql语句时,就像在写普通的java程序一样,可以对输入进行一些判断,选择操作等。
下面就一次说一下这些标签的使用!
首先看一下if标签:

    <select id="selectWithIf" parameterType="map" resultMap="BaseResultMap">
        SELECT * FROM city <if test="id!=0">WHERE city.id=#{id}</if> <if test="id==0" >limit 2</if>
    </select>

根据这个语句可以看出,当id为0的时候会查出两条记录,当指定id的时候最多只能查询一条记录。首先需要明白if语句中的id代表的是什么?

在参数类型上指定了类型为map,其实也可以是其他的,但是传入的参数对象中必须有一个属性名称叫做id或者有一个以id为key的值,否则在解析if标签的时候会报错。
在此次测试中使用的是map,传入的map如下:
在service中,对传入的id进行封装,封装成一个map对象,保证if语句可以正常解析

    public List<City> selectWithIf(int id){
        Map<String,Integer> param = new HashMap<String, Integer>();
        param.put("id",id);
        return cityMapper.selectWithIf(param);
    }

当传入id位0时返回结果如下:

{
  "status": "200",
  "timestamp": "1525609407834",
  "data": [
    {
      "id": 1,
      "name": "Kabul",
      "countrycode": "AFG",
      "district": "Kabol",
      "population": 1780000
    },
    {
      "id": 2,
      "name": "Qandahar",
      "countrycode": "AFG",
      "district": "Qandahar",
      "population": 237500
    }
  ]
}

当传入id为1时,返回如下:

{
  "status": "200",
  "timestamp": "1525610317259",
  "data": [
    {
      "id": 1,
      "name": "Kabul",
      "countrycode": "AFG",
      "district": "Kabol",
      "population": 1780000
    }
  ]
}

可以看到,通过改变判断的条件,可以达到动态改变sql语句的目的!

choose的作用与if相似,类似于java代码中的switch关键字,具体使用语句如下:

    <select id="selectWithChoose" parameterType="map" resultMap="BaseResultMap">
        SELECT * FROM city
        <choose >
            <when test="id==1">
                limit 1
            </when>
            <when test="id==2">
                limit 2
            </when>
            <otherwise>
                city.id=#{id}
            </otherwise>
        </choose>
    </select>

根据语句可以看到,当id为1或者2的时候,指定select语句返回一条或者两条记录,在id为其他的情况下,select语句会根据City的id字段进行条件查询,对应的service和controller代码如下:

    //serivce:
    public List<City> selectWithChoose(int id){
        Map<String,Integer> param = new HashMap<String, Integer>();
        param.put("id",id);
        return cityMapper.selectWithChoose(param);
    }
    //controller:
    @RequestMapping(value = "/select_with_choose",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "selectWithIf")
    public ResponseDto selectWithChoose(@RequestParam(value = "id") @ApiParam(value = "id") int id){
        List<City> cities =  cityService.selectWithChoose(id);
        ResponseDto dto = new ResponseDto();
        dto.setData(cities);
        dto.setStatus("200");
        dto.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return dto;
    }

通过启动应用,使用swagger自定的测试界面,测试编写的接口是否正常工作,解释结果如下:
id==1时:

{
  "status": "200",
  "timestamp": "1525610964460",
  "data": [
    {
      "id": 1,
      "name": "Kabul",
      "countrycode": "AFG",
      "district": "Kabol",
      "population": 1780000
    }
  ]
}

id==2时:

{
  "status": "200",
  "timestamp": "1525610988549",
  "data": [
    {
      "id": 1,
      "name": "Kabul",
      "countrycode": "AFG",
      "district": "Kabol",
      "population": 1780000
    },
    {
      "id": 2,
      "name": "Qandahar",
      "countrycode": "AFG",
      "district": "Qandahar",
      "population": 237500
    }
  ]
}

id==9时:

{
  "status": "200",
  "timestamp": "1525611058989",
  "data": [
    {
      "id": 9,
      "name": "Eindhoven",
      "countrycode": "NLD",
      "district": "Noord-Brabant",
      "population": 201843
    }
  ]
}

可以通过结果,看到实际的返回的查询结果集是按照预想的那么进行的!

foreach标签的使用:

    <select id="selectWithForeach" parameterType="map" resultMap="BaseResultMap">
        SELECT * FROM city
            WHERE city.id in
        <foreach collection="ids" item="tmp" open="(" close=")" separator="," index="">
            #{tmp.id}
        </foreach>
    </select>

使用foreach标签将传入的参数拼接成一个数组,用来代表in的参数!
对应的service和controller代码如下:

    //service:
    public List<City> selectWithForeach(int id1,int id2,int id3){
        Map<String,Integer> param1 = new HashMap<String, Integer>();
        param1.put("id",id1);
        Map<String,Integer> param2 = new HashMap<String, Integer>();
        param2.put("id",id2);
        Map<String,Integer> param3 = new HashMap<String, Integer>();
        param3.put("id",id3);
        List<Map<String,Integer>> list = new ArrayList<Map<String, Integer>>();
        list.add(param1);
        list.add(param2);
        list.add(param3);
        Map<String,List<Map<String,Integer>>> param = new HashMap<String, List<Map<String, Integer>>>();
        param.put("ids",list);
        return cityMapper.selectWithForeach(param);
    }
    //controller:
    @RequestMapping(value = "/select_with_foreach",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "selectWithIf")
    public ResponseDto selectWithForeach(@RequestParam(value = "id1") @ApiParam(value = "id1") int id1,
                                         @RequestParam(value = "id2") @ApiParam(value = "id2") int id2,
                                         @RequestParam(value = "id3") @ApiParam(value = "id3") int id3){
        List<City> cities =  cityService.selectWithForeach(id1,id2,id3);
        ResponseDto dto = new ResponseDto();
        dto.setData(cities);
        dto.setStatus("200");
        dto.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return dto;
    }

在输入参数一次为1,5,8的情况下,实际测试返回结果如下:

{
  "status": "200",
  "timestamp": "1525612224374",
  "data": [
    {
      "id": 1,
      "name": "Kabul",
      "countrycode": "AFG",
      "district": "Kabol",
      "population": 1780000
    },
    {
      "id": 5,
      "name": "Amsterdam",
      "countrycode": "NLD",
      "district": "Noord-Holland",
      "population": 731200
    },
    {
      "id": 8,
      "name": "Utrecht",
      "countrycode": "NLD",
      "district": "Utrecht",
      "population": 234323
    }
  ]
}

到这里也基本上说完了这三个标签的用法,关于测试中使用的数据库可以通过点击world.sql下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值