目录
一.MyBatis映射文件
1.insert、update、delete元素
<mapper namespace="com.itheima.dao.EmployeeDao">
<!--插入 -->
<insert id="addEmp">
INSERT INTO tb1_employee(name,email,gender) VALUES (#{name},#{email},#{gender})
</insert>
<!--更新 -->
<update id="updateEmp">
UPDATE tb1_employee set name= #{name},email=#{email},gender=#{gender} WHERE id=#{id}
</update>
<!--删除 -->
<delete id="deleteEmp">
delete from tb1_employee where id=#{id}
</delete>
</mapper>
public interface EmployeeDao {
Employee getEmpById(Integer id);
void addEmp(Employee employee);
void deleteEmp(Integer id);
void updateEmp(Employee employee);
}
2.主键生成方式
-
若数据库支持自动生成主键的字段,则可以设置
useGeneratedKeys="true"
,然后把keyProperty
设置到目标属性上
<insert id="addEmp" parameterType="com.itheima.bean.Employee"
useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
insert into tbl_employee(last_name,email,gender)
values(#{lastName},#{email},#{gender})
</insert>
-
对于不支持自增性主键的数据库(例如Oracle),可以使用
selectKey
子元素,selectKey
元素将会首先运行,id会被设置,然后插入语句会被调用
<insert id="addEmp" databaseId="oracle">
<!--
keyProperty:查出的主键值封装给javaBean的哪个属性
order="BEFORE":当前sql在插入sql之前运行
AFTER:当前sql在插入sql之后运行
resultType:查出的数据的返回值类型
BEFORE运行顺序:
先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
在运行插入的sql;就可以取出id属性对应的值
AFTER运行顺序:
先运行插入的sql(从序列中取出新值作为id);
再运行selectKey查询id的sql;
-->
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
<!-- 编写查询主键的sql语句 -->
<!-- BEFORE-->
select EMPLOYEES_SEQ.nextval from dual
<!-- AFTER:
select EMPLOYEES_SEQ.currval from dual -->
</selectKey>
<!-- 插入时的主键是从序列中拿到的 -->
<!-- BEFORE:-->
insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)
values(#{id},#{lastName},#{email<!-- ,jdbcType=NULL -->})
<!-- AFTER:
insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)
values(employees_seq.nextval,#{lastName},#{email}) -->
</insert>
3.参数(Parameters)传递
(1)单个参数
可以接受基本类型,对象类型,集合类型的值
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{id}
</select>
一个非常简单的命名参数映射。参数类型被设置为 int
,这样这个参数就可以被设置成任何内容。原生的类型或简单数据类型(比如整型和字符串)因为没有相关属性,它会完全用参数值来替代。
(2)多个参数
任意多个参数,都会被MyBatis重新包装成一个Map传入,Map的key是param1,param2...
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{param1}
and username = #{param2}
</select>
(3)命名参数
为参数使用@Param起一个名字,MyBatis会将这些参数封装到map中,key就是@Param的value值
User selectUsers(@Param("id") Integer id, @Param("name") String name);
<select id="selectUsers" resultType="User">
select id, username, password
from users
where id = #{id}
and username = #{name}
</select>
(4)POJO
当这些参数属于我们的业务POJO时,直接传递POJO
void addEmp(Employee employee);
<insert id="addEmp">
INSERT INTO
tb1_employee(name,email,gender)
VALUES
(#{name},#{email},#{gender})
</insert>
(5)Map
也可以封装多个参数为map,直接传递,#{map中的key}取出map中对应的值
(6)注意
如果是Collection(List、Set)类型或者是数组,也会特殊处理。也是把传入的list或者数组封装在map中。
Collection(collection)
List(list)
数组(array)
public Employee getEmpById(List<Integer> ids);
<!--取值:取出第一个id的值 -->
#{list[0]}
4.参数(Parameters)处理
(1)#{}和${}的区别
-
#{}:是以预编译的形式,将参数设置到sql语句中,可以防止sql注入
-
${}:取出的值直接拼接在sql语句中,会有安全问题
select * from tbl_employee where id=${id} and last_name=#{lastName}
Preparing: select * from tbl_employee where id=2 and last_name=?
-
大多情况下,我们取参数的值都应该去使用#{}
-
在原生jdbc不支持占位符的地方我们可以使用${}进行取值
比如分表、排序等
<!-- 按照年份分表查询-->
select * from ${year}_salary where xxx;
<!--按照姓名进行排序 -->
select * from tbl_employee order by ${f_name}
(2)null值的处理
-
参数位置支持的属性:
javaType、jdbcType、mode、numericScale、
resultMap、typeHandler、jdbcTypeName、expression
-
jdbcType通常需要被设置
在我们数据为null的时候,有些数据库(Oracle)可能不能识别mybatis对null的默认处理,会报错。
JdbcType OTHER:无效的类型 。因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理。
-
解决方法
①参数后面直接指定
#{email,jdbcType=OTHER}
②全局配置中Setting配置
<setting>
<setting name="jdbcTypeForNull" value="NULL"/>
</setting>