目录
一、获取参数
MyBatis获取参数值的两种方式:${} 和 #{}
${}的本质就是字符串拼接,#{}的本质就是占位符赋值
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
${}
是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc. Driver
。#{}
是 sql 的参数占位符,MyBatis 会将 sql 中的#{}
替换为? 号,在 sql 执行前会使用 PreparedStatement 的参数设置方法,按序给 sql 的? 号占位符设置参数值,比如 ps.setInt(0, parameterValue),#{item.name}
的取值方式为使用反射从参数对象中获取 item 对象的 name 属性值,相当于param.getItem().getName()
。
方便起见,还是推荐用#{}的形式。
但有时必须用${},如表名、字段名,这些参数不应该加引号,而#{}会自动加引号。
获取参数的方式有好几种,为了规范化和容易记忆,我们统一为两种方式:
1.实体类型的参数
如User、Employee,参数格式:#{属性名}
void insertUser(User user);
<insert id="insertUser">
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
2.其他类型(单个/多个参数)
采用注解的方式:在定义mapper接口时形参前加@Param注解。
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;若没有指明,则以 param1,param2...为键,以参数为值;
User getUserByIdAndName(@Param("uid") Integer id, @Param("uname") String username);
<select id="getUserByIdAndName" resultType="User">
select * from t_user where id=#{uid} and username=#{uname}
</select>
二、普通查询
2.1 返回List集合
List<User> getAllUsers();
<select id="getAllUsers" resultType="User">
select * from t_user
</select>
2.2 查询单个数据(Integer/String)
Integer getUserCount();
<select id="getUserCount" resultType="Integer">
select count(*) from t_user
</select>
2.3 以Map的形式返回单条数据
Map<String,Object> getUserMapById(@Param("id") Integer id);
<select id="getUserMapById" resultType="Map">
select * from t_user where id=#{id}
</select>
虽然查询的是单条数据,但是所有字段以键值对的形式保存在一个Map中返回的,例如 {username=lisa , age=18 , id=1 , password=110}
2.4 以Map的形式返回多条数据
方式一:多条数据产生多个map集合,将这些map放在一个list集合中获取。
List<Map<String, Object>> getAllUserToMap();
<select id="getAllUserToMap" resultType="map">
select * from t_user
</select>
方式二:多个map集合最终以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对应的 map集合
@MapKey("id")
Map<String, Object> getAllUserToMap();//以每条记录的id为key,每条记录为value
<select id="getAllUserToMap" resultType="map">
select * from t_user
</select>
结果:
{1={password=123456, sex=男, id=1, age=23, username=王五},
2={password=123456, sex=男, id=2, age=23, username=张三},
3={password=123456, sex=男, id=3, age=23, username=李四}}
2.5 Map作为参数查询
这种方式是手动封装Map集合,将每个条件以key和value的形式存放到集合中。然后在使用的时候通过#{map集合的key}来取值
/**
* 根据name和age查询
* @param paramMap
* @return
*/
List<Student> selectByParamMap(Map<String,Object> paramMap);
@Test
public void testSelectByParamMap(){
// 准备Map
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("nameKey", "张三");
paramMap.put("ageKey", 20);
List<Student> students = mapper.selectByParamMap(paramMap);
}
//<select id="selectByParamMap" resultType="student">
// select * from t_student where name = #{nameKey} and age = #{ageKey}
//</select>
三、模糊查询
List<User> getUserLike(@Param("String") String str);
<select id="getUserLike" resultType="User">
select * from t_user where username like "%"#{String}"%"
</select>
注意不能写成"%#{String}%",这样会把参数识别为字符串。
四、批量删除
单独提及这个操作的原因是这个操作只能用 ${ } 而不能用 #{ } ,因为#{}会自动加引号,识别为字符串。
void deleteUsers(@Param("ids") String ids);
<delete id="deleteUsers" >
delete from t_user where id in(${ids})
</delete>
五、动态设置表名
假如我们要把表名作为参数传入SQl语句时,必须使用 ${ },因为 #{ } 会自动加引号,而表名是不允许加引号的。
List<User> getUsersByTableName(@Param("table") String tableName);
<select id="getUsersByTableName" resultType="User">
select * from ${table}
</select>
六、Insert 时得到自增主键
有时候我们向有自增主键的表插入一条记录时,希望这条记录的自增主键值能够在插入的同时保存到java实体类的对象中,而不是进行二次查询,那就应该使用如下格式:
void insertUser(User user);
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
这样一来,插入记录的同时,我们插入的user对象的id值也就被赋上了。