<selectid="listArticleFuzzy"parameterType="string"resultType="Article"> select * from article where title like concat('%',#{string},'%') or author like concat('%',#{string},'%') </select>
//模糊查询 List<Article> as = session.selectList("listArticleFuzzy","东野"); for(Article a:as){ System.out.println(a.toString()); }
打印输出 1-白夜行-东野圭吾
多条件查询 如果我们又要限定查询的id,又要模糊查询,就需要传两个参数
Mapper
<selectid="listArticleByIdAndStr"parameterType="map"resultType="Article"> select * from article where id > #{id} and title like concat('%',#{string},'%') </select>
这里我们传入的参数类型事map
测试
Map<String,Object>params = new HashMap<>(); params.put("id",0); params.put("string","白夜"); List<Article> as = session.selectList("listArticleByIdAndStr",params); for(Article a:as){ System.out.println(a.toString()); }
<selectid="listAuthorWorks"resultMap="authorBean"> select au.*,ar.*,au.id 'auid',ar.id 'arid'from author au left join article ar on ar.author_id = au.id </select> </mapper>
<!-- 根据id查询Product, 关联将Orders查询出来 --> <selectid="listArticleAndAuthor"resultMap="articleBean"> select ar.*,au.*,ar.id 'arid',au.id 'auid' from article ar left join author au on ar.author_id = au.id </select>
<selectid="listFavorites"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id </select>
动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。比如说就在上面多对多的sql语句中,我写了两个查询收藏夹的SQL,显得臃肿,重合的代码太多了。
现在改写
<selectid="listFavorites"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id <iftest="id!=null"> where f.id = #{id} </if> </select>
测试
Map<String,Object> params = new HashMap<>(); params.put("id",1); List<Favorites> favorites = session.selectList("listFavorites",params);
for(Favorites fa :favorites) { System.out.println(fa.getFname()); List<FavoritesItems> favoritesItems = fa.getFavoritesItems(); for (FavoritesItems fai : favoritesItems){ System.out.format("\t%d\t%s\t%d%n",fai.getArticle().getId(),fai.getArticle().getTitle(),fai.getArticle().getAuthor_id()); } }
如果直接写成这样session.selectList("listFavorites",1); 会报错There is no getter for property named 'id' in 'class java.lang.Integer'意思就是没有发现id属性的getter方法。
但是如果我们就是要用这种直接传参呢,也是可以的,不过要修改SQL语句
使用_parameter
<selectid="listFavorites"parameterType="int"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id <iftest="_parameter!=null"> where f.id = #{id} </if> </select>
将if 判断中的参数换为_parameter
使用mybatis默认的对象名:value <if test="value!=null">也就行了
输出结果
我的最爱 1 白夜行 1 2 龙族 2 4 嫌疑人X的献身 1
trim, where, set
上面用if时我们只是单条件查询,如果我们改成多条件查询,比如编号大于某数和根据收藏夹名字模糊查询
<selectid="listFavoritesBy"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id <iftest="id!=null"> where f.id > #{id} </if> <iftest="name!=null"> and f.name like concat('%',#{name},'%') </if> </select>
当两个参数都有或者只有第一个参数的时候是没有问题的,但是如果只传入第二个参数,那么拼接成错误的sql语句。 select * from table and这种错误sql等等。
现在改写一下,很简单用标签包裹一下标签**就ok了
<selectid="listFavoritesByWhere"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id <where> <iftest="id!=null"> f.id > #{id} </if> <iftest="name!=null"> and f.name like concat('%',#{name},'%') </if> </where> </select>
这样就可以避免参数顺序拼接出错了。 where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where_ 元素也会将它们去除。
<selectid="listFavoritesByChoose"resultMap="favoritesBean"> select ar.*,f.id 'fid',f.name 'fname',fi.id 'fiid',ar.id 'arid' from favorites f left join favorites_items fi on f.id = fi.fid left join article ar on fi.arid = ar.id where <choose> <whentest="id!=null"> f.id = #{id} </when> <whentest="name!=null"> f.name like concat('%',#{name},'%') </when> <otherwise> f.id > 0 </otherwise> </choose> </select>
choose只用一个限定条件,这里的意思就是传参是 id 就更具 id 查询,如果传的是名称就根据名称模糊查询,没有给条件就默认查询所有收藏夹。
foreach
用于对一个集合进行遍历,通常是在构建 IN 条件语句的时候。
比如我们查询article表,根据指定的 id 集合查询
<selectid="listArticleByList"resultType="Article"> select * from article where id in <foreachitem="item"index="index"collection="list" open="("separator=","close=")"> #{item} </foreach> </select>
这里我们查询 1 2 4
List<Integer> articleList = new ArrayList<>(); articleList.add(1); articleList.add(2); articleList.add(4);
List<Article> as = session.selectList("listArticleByList",articleList); for(Article a:as){ System.out.println(a.toString()); }
<selectid="listArticleFuzzy"resultType="Article"> select * from article where title like concat('%',#{string},'%') </select>
这是Mysql数据库的语句,若是换成Oracle数据库 那么语句应该是 select * from article where title like'%'``||#{``string``}||``'%'
但是用元素可以解决这种问题 改写成
<selectid="listArticleFuzzy"resultType="Article"> <bindname="liketitle"value="'%' + name + '%'" /> select * from product_ where name like #{liketile} </select>