mybatis加强
使用Mapper接口
相当于DAO,在接口汇总定义CRUD等方法 Mapper组件=Mapper接口+Mapper XMl文件
规范:
- 接口的命名为XxxMapper(Xxx为实体类名),一般与对应的XML文件放在一起(编译后的字节码文件和XML放在一起就行)
- XML命名空间nameSpace对应接口的全限定类名
定义Mapper接口: UserMapper
public interface UserMapper {void save(User user);}
定义XMl: UserMapper.xml
<insert id="save" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
INSERT INTO user(username, password) VALUES(#{username}, #{password})
</insert>
- useGeneratedKeys=“true” :获取数据生成主键值(获取由数据库自动生成的主键)
- keyProperty=“id” :设置到被保存的User对象哪个属性上id属性上(指定把获取到的主键注入到实体类的id属性上)
测试使用Mapper接口:
@Test
public void save() {
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("yyy");
user.setPassword("123");
mapper.save(user);
session.commit();
session.close();
}
这里使用了getMapper ,getMapper返回的是什么? 为什么需要向getMapper方法传递参数?
- getMapper返回的是上述UserMapper的实现类对象 ,这个实现类对象是由JDK动态代理创建的(以后补充动态代理)
- 项目中会有多个Mapper接口,传递接口的字节码就可以找到对应的接口实现类对象.
@Param注解
当传递一个 List 对象或数组对象参数给 MyBatis 时,MyBatis 会自动把它包装到一个 Map 中
List 对象会以 list 作为 key,数组对象会以 array 作为 key。我们也可以使用 @Param
(给参数命名)设置key名
使用场景:
Mapper接口方法定义的参数
1.一个参数 :
1.简单类型: 分为 # , $
1.# 不贴注解
2.$或者标签取值 贴注解
2.Map JavaBean :不贴注解 ,因为已经进行了封装,sql可以直接引用javabean中的属性
3.List数组:一般都会贴注解,在Mapper XMl 取值见名知意
2.多个参数:需要贴上注解,不然会报错
原理,以登录接口为例:
User login(@Param("username") String username, @Param("password") String password);
<select id="login" resultType="cn.k.domain.User">
select id,username,password from user where username=#{username} and password=#{password}
</select>
如果login接口不使用注解的方式,由于命名空间方式只支持一个参数,那么传递的两个参数会被封装成一个Map集合;
map集合会帮我们装进去,但是是有两种方式,例如:
map.put("param1","xx")
map.put("param2","1")
map.put("arg0","xx")
map.put("arg1","1")
那么Mapperxml文件中就需要写成
<select id="login" resultType="User">
select id,username,password from user where username=#{param1} and password=#{param2}
//或者
//select id,username,password from user where username=#{arg0} and password=#{arg1}
</select>
上述这种不贴注解,需要按照param1,2…这样顺序写下去,sql不直观,不小心就会报错,不写也会报错,所以我们需要采用贴注解方式来解决
#与$的区别
在sql 中有分 #和 $ , 使用#传递的参数会先转换,无论传递什么类型都会带一个单引号(’’),使用$传递的参数,直接把值作为SQL语句的一部分.
# | $ |
---|---|
简单类型(八大基本数据类型及其包装类、String、BigDecimal 等等)参数作为 值 | 使用 $ 不支持把简单类型参数作为值 |
使用#,没有SQL注入的问题,相对比较安全 | 相对不安全,可能会有sql注入问题 |
$:会优先取db.properties中的参数
#和$的选取
$ 取列名或者表名的时候使用,一般出现在FROM子句,GROUP BY ,ORDER BY ,SELECT子句
其他使用 # 解决
动态SQL
if where
<select id="queryByMinSalaryAndMaxSalary" resultType="Employee">
select id, name, sn, salary, deptId
from employee
<where>
<if test="minSalary != null">
and salary >= #{minSalary}
</if>
<if test="maxSalary != null">
and salary <= #{maxSalary}
</if>
</where>
</select>
set
<update id="update">
update employee
<set>
<if test="name != null and name != ''">
name=#{name},
</if>
<if test="salary != null">
salary=#{salary},
</if>
<if test="sn != null">
sn=#{sn},
</if>
<if test="deptId != null">
deptId=#{deptId},
</if>
</set>
where id = #{id}
</update>
froeach
通常在构建 IN 条件语句时使用
- Collection 要遍历list 对象 或者数组对象
open 要遍历之前拼接字符串
item 遍历时指定变量存到每次遍历元素
index 遍历的索引
separator 每遍历一个元素之后拼接字符串,除了最后一次
close 遍历结束拼接字符串
批量删除
//批量删除
void multipleDelete(@Param("ids") Long[] ids);
<delete id="multipleDelete">
delete
from employee where id IN
<foreach collection="ids" open="(" item="id" separator="," close=")">
#{id}
</foreach>
</delete>