在MyBatis的select、insert、update、delete这些元素中都提到了parameterType这个属性。MyBatis现在可以使用的parameterType传入以下类型的参数,拼接sql语句。
通过#{参数名}: 获取参数中的值
dao中的方法:
public User selectUserByOrgId(long userId);
mapper.xml:
<sql id="Base_Column_List" >
userId,name,age,gender,phone
sql>
<select id="selectUserByOrgId" parameterType="java.lang.Long"
resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where org_id = #{userId}
select>
通过#{0}、#{1}……索引方式,传入多个参数
dao中的方法:
public User selectUser(String username,String password);
mapper.xml:
<select id="selectUser" resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where username= #{0} and password= #{1}
select>
#{参数名},传入多个参数,并且参数用@param注解 (推荐)
dao中的方法:
public User selectUser(@Param("username") String username,
@Param("password") String password);
mapper.xml:
<select id="selectUser" resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user where username= #{username} and password= #{password}
select>
在sql动态语句中经常会有根据数据库某个字段状态进行判断的,但在Mybatis中如果用了if判断那么传进来的参数时,不能直接单独传入,要封装到Map或对象中。例如下边代码会出错:
<select id="selectUserById" parameterType="int"
resultType="Base_Column_List">
select
<include refid="Base_Column_List" />
from user
<if test="userId!=0">
where userId= #{userId}
if>
select>
因为java的int类型默认值为0,导致0与null的判定无法识别
Mybatis默认采用ONGL解析参数,所以会自动采用对象树的形式取Integer.userId。Integer对象没有userId属性。如果不用if标签判断,直接传入不会报错。
解决办法1:参数名全部改为_parameter
<select id="sel_campusinfo" parameterType="int" resultType="Campusinfo">
select
<include refid="Base_Column_List" />
from user
<if test="_parameter!=0">
where userId= #{userId}
if>
select>
解决办法2:
dao中的方法设置为:
User seleteUserById(@Param("id") int id);
mapper.xml:
<select id="seleteUserById" parameterType="int" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from user
<if test="id!=0">
where id = #{id}
if>
select>
//goodsIdArray = {1,2,3,4,5}
List<Goods> queryGoodsArray(long[] goodsIdArray);
mapper.xml:
<sql id="Base_Column_List">
id, userId, userName, goodsId, goodsName, goodsPic, goodsStyle, goodsPrice, goodsNum,
storeId, storeName, addTime
sql>
<select id="queryGoodsArray" resultMap="Base_goods_List">
select * from t_goods
where goodsId in
<foreach collection="array" open="(" separator="," close=")" item="goodsId">
#{goodsId}
foreach>
select>
注意:
- 用到foreach循环遍历数组,foreach标签中的属性有,collection,open,separator,close,item
- collection:单独传入list时,当传入的类型是List集合时,它的值为list;单独传入数组时,当传入的类型为数组时,它的值为array。
- open:是以某字符开头,separator:字符串之间分隔符,close:是以某字符结束
- item:遍历的当前对象
- 以上完成的sql语句为:
select * from t_goods where goodsId in (1,2,3,4,5)
int addUsers(List<User> users);
mapper.xml:
<sql id="addUser">
username, password, name, age, sex, phone
sql>
<insert id="addUsers" parameterType="java.util.List">
insert into user
( <include refid="addUser" /> )
values
<foreach collection="list" item="user" separator=",">
(
#{user.username},
#{user.password},
#{user.name},
#{user.age},
#{user.sex},
#{user.phone}
)
foreach>
insert>
注意:
- parameterType的类型为java.util.List,但是不写也不会错误
- collection属性为list
- item为当前对象
- separator:必须有,不写会出现错误
- 以上完成的sql语句为:
insert into user ( username, password, name, age, sex, phone ) values (?,?,?,?,?,?) , (?,?,?,?,?,?) , (?,?,?,?,?,?)
(?,?,?,?,?,?) 为插入的数据条数
Map<String,Object> map=new HasMap<String,Object>();
map.put("name","张三");
map.put("age",23);
通过 #{map中的键} 取值。
dao中的方法:
User queryUser(Map map);
<select id="queryUser" parameterType="java.util.Map" resultType="BaseResultMap">
select * from user where name = #{name} and age = #{age}
select>
(2) 如果Map中有list或array时,foreach中的collection必须是具体list或array的变量名。比如这里Map含有一个名为intList的list,所以Map中用intList取值,这点和单独传list或array时不太一样。例如:
Map<String, Object> map= new HashMap<String, Object>();
List<Integer> intList= new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
map.put("userId", 123);
map.put("intList", intList);
dao中的方法:
List<User> queryUsers(Map map);
mapper.xml:
<select id="queryUsers" resultMap="BaseResultMap" parameterType="java.util.Map">
select * from user
where 1=1 and intListin
<foreach item="item" index="index" collection="intList"
open="(" separator="," close=")">
#{item}
foreach>
select>
(3)如果Map中封装的是实体类,则通过#{key.attributeName}取值,例如:
User user= new User("张三",18);
Map<String,Object> map=new HasMap<String,Object>();
map.put("user",user);
dao中的方法:
User queryUsers(Map map);
mapper.xml:
<select id="selectUserByNameAndAge" parameterType="Map"
resultType="BaseResultMap">
select * from user
where name = #{user.name} and age = #{user.age}
select>
直接传入实体参数,通过#{属性名}取值,但Java对象中有list或array时,foreach中的collection必须是具体list或array的变量名。
mapper.xml:
<update id="updateByPrimaryKeySelective" parameterType="com.boot.demo.model.User">
update user
<set>
<if test="username != null">
username = #{username,jdbcType=VARCHAR},
if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
if>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
if>
<if test="age != null">
age = #{age,jdbcType=INTEGER},
if>
<if test="sex != null">
sex = #{sex,jdbcType=VARCHAR},
if>
<if test="phone != null">
phone = #{phone,jdbcType=VARCHAR},
if>
set>
where id = #{id,jdbcType=INTEGER}
update>
property:属性名,即代码传入的变量名。
javaType:该字段在JAVA中的类型,比如int。
jdbcType:该字段在JDBC中的类型,比如NUMERIC。
column:数据库中字段名
resultMap:结果,可以自行指定
resultType:结果,现成的对象类
namespace:对数据库操作的方法->mapper文件所在的包名
简单概括就是:
statementType属性:
STATEMENT(非预编译):使用Statement查询sql语句,
PREPARED(预编译):使用PreparedStatement 查询sql语句,可防止sql注入
举例:根据用户选择对查询的数据排序
List<User> selectUsers(@Param("str") String str);
<select id="selectUsers" parameterType="String" resultMap="BaseResultMap" statementType="STATEMENT">
select
<include refid="Base_Column_List" />
from user
order by ${str} desc
select>
这样完成的sql语句为:
当str="age"时select id, username, password, name, age, sex, phone from user order by age desc
当str="name"时
select id, username, password, name, age, sex, phone from user order by name desc
使用like查询可以通过#{},${}和CONCAT()函数连接参数形式三种查询方式,但是#{}和 ${}都有明显的弊端,所以推荐使用CONCAT()函数查询。
dao中方法:
List<User> selectUsers(@Param("name") String name);
mapper.xml:
<select id="selectUsers" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where name like CONCAT('%',#{name},'%')
select>
以上完成的sql语句为:
select * from user where name like CONCAT('%',?,'%')