1. 程式人生 > >Mybaits中if、choose、foreach標籤的使用

Mybaits中if、choose、foreach標籤的使用

在使用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下載