在实际工作中可能会遇到需要在Dao的方法中传入不同参数的情况,根据各方面的资料的总结,大致可以归结于一下几种类型:
1、基本数据类型(比如常用的String、Integer类型等,mapper中传入的应为基本类型)
2、数组、List等单类型参数
3、自定义的对象类(含有基本数据类型、复杂类型共存类型,也是工作中较为常见的一种情况,建议认真思考掌握)
首先,先看一下mapper中标签的使用,基本的使用不必过多的赘述,这里主要记录一下<foreach>标签的的使用,务必熟练掌握<foreach>标签的使用。
<foreach>标签有五个基本的属性,都是在工作中常用的几个属性:item、index、open、separator、close
item表示在迭代的过程中的单个元素,
index表示在迭代的过程中每次迭代的位置,实际工作中常用于表示数据下标一类
open表示循环标签以什么开始,多数以"("开始
separator表示在每次迭代之间用什么符号进行分隔,多数为逗号“,”
close表示整个循环标签以什么结束,多数以 ")" 结束
(以上使用情况需根据实际使用灵活应对)
讨论第一种情况:
当DAO中的方法为基本数据类型时,如
public interface UserDao(){
public int countNum(final @Param("gender") String gender); //返回int类型
public List<User> queryManyPersons(final @Param("gender") String gender); //返回User集合
public User query(final @Param("name") String name); //返回User对象
}
//1、注意,Dao层里极少有返回Map类型的,因为在mapper文件中做映射较为复杂,返回list可实现需求
//2、如果基本数据类型是int,mapper文件里不能用#{..},而用${..}.
关于#{}和${}主要的区别在于前者可以防止SQL注入
其中,User对象为
public class User{
private String name; //姓名
private String gender; //性别
private int age; //年龄
//get和set方法不能少
public getName(){...}
public setName(String name){...}
public getGender(){...}
public setGender(String gender){...}
public getAge(){...}
public setAge(int age){...}
}
其对应的mapper文件为
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--UserDao的绝对路径-->
<mapper namespace="....UserDao">
<resultMap ...>
<select id="countNum" paramType="java.lang.String" resultType="java.lang.Integer">
SELECT COUNT(*) FROM ...
</select>
<select id="queryManyPersons" paramType="java.lang.String" resultMap="..."(User对象对应的表映射,虽然返回结果为List,但这里必须是指List单个元素的类型)
SELECT ...
</select>
第三个方法略,不用多余赘述
</mapper>
第二种情况:
当DAO中方法的参数为List时,这里以工作中实际遇到的情况举例
创建分组(创建商户记录),DAO的接口名省略,处理方法与上面一样,在<namespace>标签里声明
GroupMerchantDTO里面有String groupId,String merchantId属性
public void saveMerchantGroup(List<GroupMerchantDTO> groupMerchantDTOList);
mapper
<!--如果参数是数组,则把mapper里的俩处list分别换成java.util.ArrayList和array即可-->
<insert id="saveMerchantGroup" parameterType="java.util.List">
INSERT INTO
pss_store_group_merchant_relation (merchant_group_id,merchant_id)
VALUES
<foreach collection="list" index="index" item="item" separator=",">
(#{item.groupId},#{item.merchantId})
</foreach>
</insert>
第三种情况:
参数为Map时
public List<GroupPO> queryFilterGroup(Map<String,Object> map);
mapper:
参数map中有String productCode和List<String> groupIdss类型的参数
<select id="queryFilterGroup" parameterType="java.util.HashMap" resultMap="GroupPO">
SELECT
mgi.group_id,mgi.group_name
FROM
pss_store_merchant_group_info mgi
WHERE
mgi.group_id NOT IN ( SELECT
group_id
FROM
pss_store_product_group_relation pgr
WHERE
pgr.product_code= #{productCode}
)
<if test="groupIdss != null and groupIdss.size()>0">
AND mgi.group_id NOT IN ( <foreach collection="groupIdss" item="item" index="index" separator=",">
#{item}
</foreach>
)
</if>
</select>
PS:工作中遇到的几条myBatis小技巧
1、SQL脚本搜索出的字段数可以小于<resultMap>内部的映射对数,可多次复用<resultMap>,没有查到的内容的Bean为空
2、页码、分页一律采用int类型接收,有利于在SQL脚本里做分页计算 LIMIT #{pageSize} OFFSET ( #{pageNum}-1)*#{pageSize}
3、
cast():类型转换 cast(字段 as 转换的类型)
substring():截取查询的结果,第一位从1开始,包头不包尾
COALESCE(MAX(字段),"数字"):查询某个字段,如果这个字段有值,查询出这个结果;如果表中这个字段为空(null),就返回设置的数字,常用于输出默认值的情况
<!--查询组号最大的那条的记录-->
<select id="queryMaxGroupId" resultMap="groupMap">
SELECT
config_id,group_id,...
FROM
pss_store_merhant_group_info
WHERE
cast(substring(group_id,2,10) as int) = (SELECT
MAX(cast(substring(group_id,2,10)) as int)
FROM
pss_store_merchant_group_info
)
</select>
<!--展示产品的状态设置 表中有什么内容就展示什么内容,当表中的这个字段为空时返回默认值‘1’-->
<select id="displayStatus" parameterType="java.lang.String" resultType="java.lang.String">
SELECT
COALESCE(MAX(display_status),'1') AS display_status
FROM
pss_store_prdsvr_baseinfo
WHERE
product_code= #{productCode}
</select>
还是那句话,以上内容需在实际应用中灵活变通,切不可教条制造BUG