1、insert_获取自增主键的值
<!-- 增加 mybatis 也是利用 statement.getGeneratedKeys()来获取自增主键值 useGeneratedKeys ="true" 使用自增主键获取主键值策略 keyProperty : mybatis获取到主键值后,将其封装到java bean的哪个属性 --> <insert id="addEmp" parameterType="com.atguigu.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id"> insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender}) </insert>
2、insert_获取非自增主键的值_selectKey
<insert id="addEmp" databaseId="oracle"> /* keyProperty: 查出的主键值封装到javaBean的哪个属性 order = "BEFORE" 当前sql在插入sql之前运行 "AFTER" 当前sql在插入sql之后运行 resultType : 查出的数据的返回值类型 */ <selectKey keyProperty="id"> /*编写查询主键的sql语句*/ select employees_seq.nextval from dual; </selectKey> /*插入的主键是从序列中拿到的*/ insert into employees(id,last_name,email,gender) values(#{lastName},#{email},#{gender}) </insert>
3、mybatis参数处理
单个参数:
mybatis不会做特殊处理,#{参数名} 取出参数
多个参数:
mybatis会做特殊处理
多个参数会被封装成一个map
key:param1...paramN
value: 对应的按照顺序传入的参数
#{key} 就是从map中获取指定的值
命名参数:
明确指定封装参数时map的key ==》接口定义时 使用@param
多个参数会被封装成一个map
key:使用@param注解指定的值
value:参数值
#{key} 就是从map中获取指定的值
接口中的方法:
public Employee getEmpByIdAndLastName(@Param("id") int id, @Param("lastName") String lastName);
mapper.xml中
<select id="getEmpByIdAndLastName" resultType="employee"> select id,last_name,email,gender from tbl_employee where id = #{id} and last_name =#{lastName} </select>
POJO:
如果多个参数正好是我们业务逻辑的数据原型,可以之间传入pojo
#{属性名} 取出对应的值
Map:
如果多个参数不是业务模型中的数据,没有对应的pojo,为了方便,我们也可以传入map
#{key} 取出对应的值
应用示例
参数值的获取
#{} :以预编译的形式,将参数设置到sql语句中,类似于jdbc的参数占位符,防止sql注入
${} : 取出的值直接拼装在sql语句中,会有安全问题
#{} 更丰富的用法
规定参数的一些规则:
javaType、 jdbcType、 mode(存储过程)、 numericScale、
resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能);
jdbcType通常需要在某种特定的条件下被设置:
在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错);
JdbcType OTHER:无效的类型;因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;
由于全局配置中:jdbcTypeForNull=OTHER;oracle不支持;两种办法
1、#{email,jdbcType=NULL };
2、jdbcTypeForNull=NULL
<setting name="jdbcTypeForNull" value="NULL"/>
4、select 返回list和map
如果select返回list ,resultType 取得是 list 中的泛型
如果select返回map,resultType = "map"
5、select_resultMap
1)自定义结果映射规则:
<resultMap id="myemp" type="com.atguigu.mybatis.bean.Employee"> <!--指定主键列的封装规则 id 定义主键,底层会有优化 column :指定哪一列 property: 指定对应的javaBean属性 --> <id column="id" property="id"></id> <result column="last_name" property="lastName"></result> </resultMap> <select id="getEmpById" resultMap="myemp"> select * from tbl_employee where id = #{id} </select>
2)级联属性封装结果:
<resultMap id="myEmpDept" type="com.atguigu.mybatis.bean.Employee"> <id column="id" property="id"></id> <result column="last_name" property="lastName"></result> <result column="gender" property="gender"></result> <result column="email" property="email"></result> <result column="did" property="dept.id"></result> <result column="dept_name" property="dept.deptName"></result> </resultMap> <select id="getEmpAndDept" resultMap="myEmpDept"> select e.id id, e.last_name last_name, e.gender gender, e.email email, d.id did, d.dept_name dept_name from tbl_employee e left join tbl_dept d on e.dept_id = d.id where e.dept_Id = 2 </select>
【注意】Employee中有一个Department对象
结果:
2)association定义关联对象封装规则:
<!-- 使用 association ,封装关联的单个对象 --> <resultMap id="myEmpDept1" type="com.atguigu.mybatis.bean.Employee"> <id column="id" property="id"></id> <result column="last_name" property="lastName"></result> <result column="gender" property="gender"></result> <result column="email" property="email"></result> <!-- association 可以指定联合的javaBean对象 property : 指定哪个属性是联合的对象 javaType : 指定这个属性对象的类型 --> <association property="dept" javaType="com.atguigu.mybatis.bean.Department"> <result column="did" property="id"></result> <result column="dept_name" property="deptName"></result> </association> </resultMap> <select id="getEmpAndDept" resultMap="myEmpDept1"> select e.id id, e.last_name last_name, e.gender gender, e.email email, d.id did, d.dept_name dept_name from tbl_employee e left join tbl_dept d on e.dept_id = d.id where e.dept_Id = #{id} </select>
也是一样的结果
association分步查询
先准备好department对象的mapper和 xml文件
DepartmentMapper.xml
<select id="getDeptById" resultType="com.atguigu.mybatis.bean.Department"> select id,dept_name deptName from tbl_dept where id =#{id} </select>
EmployeeMapperPlus.xml
<!-- association 分步查询--> <resultMap id="myEmpDept2" type="com.atguigu.mybatis.bean.Employee"> <id column="id" property="id"></id> <result column="last_name" property="lastName"></result> <result column="gender" property="gender"></result> <result column="email" property="email"></result> <!-- association 可以指定联合的javaBean对象 property : 指定哪个属性是联合的对象 select: 调用目标的方法查询当前属性的值 column: 将sql中的哪一列传入上述调用的方法 --> <association property="dept" select="com.atguigu.mybatis.mapper.DepartmentMapper.getDeptById" column="dept_id"> </association> </resultMap>
结果:
分步查询&延迟加载
只有在真正用到关联对象时,才会进行第二次的分布查询
<settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
3)collection定义关联集合封装规则
<resultMap id="myDept" type="com.atguigu.mybatis.bean.Department"> <id column="did" property="id"></id> <result column="dept_name" property="deptName"></result> <!-- collection 定义集合类型属性的封装规则 ofType: 集合中元素的类型 --> <collection property="emps" ofType="com.atguigu.mybatis.bean.Employee"> <!--定义集合中元素的封装规则--> <id column="eid" property="id"></id> <result column="last_name" property="lastName"></result> <result column="email" property="email"></result> <result column="gender" property="gender"></result> </collection> </resultMap> <select id="getgetDeptByIdPlus" resultMap="myDept"> select d.id did,d.dept_name dept_name, e.id eid,e.last_name last_name,e.email email,e.gender gender from tbl_dept d left join tbl_employee e on d.id =e.dept_id where d.id =#{id} </select>
collection分步查询和延迟加载
<!--collection 分步查询--> <resultMap id="myDeptStep" type="com.atguigu.mybatis.bean.Department"> <id column="id" property="id"></id> <result column="dept_name" property="deptName"></result> <collection property="emps" select="com.atguigu.mybatis.mapper.EmployeeMapper.getEmpsByDeptId" column="id"> </collection> </resultMap> <select id="getgetDeptByIdStep" resultMap="myDeptStep"> select id,dept_name from tbl_dept where id =#{id} </select>
扩展:分步查询select中方法,如果要传多列的值:
将多列的值封装成map传递
column = "{k1= column1}"
fetchType ="lazy":表示延迟加载
-lazy :延迟加载
-eager: 立即查询
<collection property="emps" select="com.atguigu.mybatis.mapper.EmployeeMapper.getEmpsByDeptId" column="id" fetchType="lazy"> </collection>