一、单个参数:
单个参数:并且没有注解,mybatis不会做特殊处理,
#{参数名/任意名}:取出参数值。
二、多个参数
多个参数:mybatis会做特殊处理。
多个参数会被封装成 一个map,
key:param1...paramN,或者参数的索引(arg0,arg1.....)也可以
value:传入的参数值
#{}就是从map中获取指定的key的值;
三、命令参数
明确指定封装参数时map的key;@Param("id")
多个参数会被封装成 一个map,
key:使用@Param注解指定的值
value:参数值
#{指定的key}取出对应的参数值
*POJO:
如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo;
#{属性名}:取出传入的pojo的属性值
*Map:
如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map
#{key}:取出map中对应的值
*TO:
如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象
Page{
int index;
int size;
}
*Collection,List,Array
##特别注意:如果是Collection(List、Set)类型或者是数组,
也会特殊处理。也是把传入的list或者数组封装在map中。
key:Collection(collection),如果是List还可以使用这个key(list)
数组(array)
*******************************************************************************************************************************************
===========================参数值的获取======================================
四、获取参数的值
#{}:可以获取map中的值或者pojo对象属性的值;
${}:可以获取map中的值或者pojo对象属性的值;
区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;
大多情况下,我们去参数的值都应该去使用#{};
原生jdbc不支持占位符的地方我们就可以使用${}进行取值:比如表名,字段名,desc等
比如分表、排序。。。;按照年份分表拆分:
select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} ${order}
#{}:更丰富的用法:
规定参数的一些规则:
javaType、 jdbcType、 mode(存储过程)、 numericScale、
resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能);
例如:jdbcType
jdbcType通常需要在某种特定的条件下被设置:
在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错);
JdbcType OTHER:无效的类型;因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;
由于全局配置中:jdbcTypeForNull=OTHER;oracle不支持;两种办法
1、#{email,jdbcType=OTHER};
2、jdbcTypeForNull=NULL
<setting name="jdbcTypeForNull" value="NULL"/>
四、参数封装
package com.mybatis.dao;
import com.mybatis.entity.Employee;
import com.mybatis.entity.OraclePage;
import org.apache.ibatis.annotations.MapKey;
import java.util.List;
import java.util.Map;
/**
* Created by admin on 2019/4/22 15:02
*
* @Author: created by admin
* @Date: created in 15:02 2019/4/22
* @param: bindingResult
* @param: result
* @return:
* @throws:
* @Description:
* @version:
*/
public interface EmployeeMapper {
Employee getEmployeeById(Integer id);
Employee getEmp(Integer id);
//mybatis中增删改可以有返回值:int long boolean 以及相应的包装类
public void addEmployee(Employee e);
public void updateEmployee(Employee e);
public void deleteEmployee(Integer id);
//多个参数的处理
public Employee getEmpByIdAndLastName(Integer id, String lastName);
public Employee getEmpByMap(Map<String, Object> conditions);
//返回List
public List<Employee> getempByLastNameLike(String lastName);
//返回一条记录,key是列明,值就是对应的值
public Map<String, Object> getEmpByIdReturnMap(Integer id);
//多条记录map:key是指定某个列,值就是javaeBean对象
//@Mapkey告诉mabatis中用哪个javabean的属性作为封装的key
@MapKey("id")
public Map<Integer, Employee> getEmpListByLastNameLikeReturnMap(String lastName);
//查询所有的员工数据
public List<Employee> getEmps();
//调用存储过程查询分页
public void getPageByProcedure(OraclePage page);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.EmployeeMapper">
<!--
namespace:名称空间;指定为接口的全类名
id:唯一标识
resultType:返回值类型
#{id}:从传递过来的参数中取出id值
public Employee getEmpById(Integer id);
-->
<!-- <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> -->
<!--
eviction:缓存的回收策略:
• LRU – 最近最少使用的:移除最长时间不被使用的对象。
• FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
• SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
• WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
• 默认的是 LRU。
flushInterval:缓存刷新间隔
缓存多长时间清空一次,默认不清空,设置一个毫秒值
readOnly:是否只读:
true:只读;mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。
mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
false:非只读:mybatis觉得获取的数据可能会被修改。
mybatis会利用序列化&反序列的技术克隆一份新的数据给你。安全,速度慢
size:缓存存放多少元素;
type="":指定自定义缓存的全类名;
实现Cache接口即可;
-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
<!--databaseId 表名是在mysql环境中的数据库产厂商-->
<select id="getEmployeeById" resultType="com.mybatis.entity.Employee" databaseId="mysql">
select id,last_name lastName,gender,email from tb_employee where id = #{id}
</select>
<select id="getEmployeeById" resultType="com.mybatis.entity.Employee" databaseId="oracle">
select id,last_name lastName,gender,email from tb_employee where id = #{id}
</select>
<select id="getEmp" resultType="com.mybatis.entity.Employee">
select * from tb_employee where id = #{id}
</select>
<!--parameterType 可以省略不写
public void addEmployee(Employee e);
public void updateEmployee(Employee e);
public void deleteEmployee(Integer id);
-->
<!--
获取自增主键的值:
mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();
useGeneratedKeys="true";使用自增主键获取主键值策略
keyProperty;指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性
-->
<insert id="addEmployee" parameterType="com.mybatis.entity.Employee" useGeneratedKeys="true" keyProperty="id"
databaseId="mysql">
insert into tb_employee(last_name,email,gender,emp_status)
values
(#{lastName},#{email},#{gender},#{empStatus})
</insert>
<!--
keyProperty:查出的主键值封装给javaBean的哪个属性
order="BEFORE":当前sql在插入sql之前运行
AFTER:当前sql在插入sql之后运行
resultType:查出的数据的返回值类型
BEFORE运行顺序:
先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
在运行插入的sql;就可以取出id属性对应的值
AFTER运行顺序:
如果并发运行的话可能会造成只能获取到最后一次的的序列,导致数据不正确,所以一般都是用before
先运行插入的sql(从序列中取出新值作为id);
再运行selectKey查询id的sql;
-->
<insert id="addEmployee" parameterType="com.mybatis.entity.Employee" databaseId="oracle">
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
select seq_employee.nextval from dual
<!-- AFTER:
select seq_employee.currval from dual -->
</selectKey>
insert into tb_employee(id,last_name,email,gender,emp_status)
values
(#{id},#{lastName},#{email,jdbcType=NULL},#{gender,jdbcType=NULL},#{empStatus,typeHandler=com.mybatis.typeHandler.MyEmpStatusTypeHandler})
<!-- AFTER:
insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)
values(seq_employee.nextval,#{lastName},#{email}) -->
</insert>
<!--
public void updateEmployee(Employee e);
-->
<update id="updateEmployee">
update tb_employee set last_name = #{lastName},email=#{email},gender=#{gender} where id=#{id}
</update>
<!--
public void deleteEmployee(Integer id);
-->
<delete id="deleteEmployee">
delete from tb_employee where id = #{id}
</delete>
<!--public Employee getEmpByIdAndLastName(Integer id,String lastName);
/**
Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
*/
/*select * from tb_employee where id=#{arg0} and last_name = #{arg1}*/
-->
<select id="getEmpByIdAndLastName" resultType="com.mybatis.entity.Employee" databaseId="oracle">
<!--select * from tb_employee where id=#{arg0} and last_name like #{arg1}-->
<!--select * from tb_employee where id=#{param1} and last_name like #{param2}-->
select * from tb_employee where id=#{arg0} and last_name like #{arg1}
</select>
<select id="getEmpByIdAndLastName" resultType="com.mybatis.entity.Employee" databaseId="mysql">
<!--select * from tb_employee where id=#{arg0} and last_name like #{arg1}-->
select * from tb_employee where id=#{param1} and last_name like #{param2}
</select>
<!--public Employee getEmpByMap(Map<String,Object> conditions);-->
<select id="getEmpByMap" resultType="com.mybatis.entity.Employee">
select * from ${tableName} where id = #{id} and last_name=#{lastName} order by ${id} ${order}
</select>
<!--public List<Employee> getempByLastNameLike(String lastName);-->
<select id="getempByLastNameLike" resultType="com.mybatis.entity.Employee">
select * from tb_employee where last_name like #{lastName}
</select>
<!-- public Map<String,Object> getEmpByIdReturnMap(Integer id);
mybatis为我们常用的取了别名http://www.mybatis.org/mybatis-3/zh/configuration.html#typeAliases
-->
<select id="getEmpByIdReturnMap" resultType="hashMap">
select * from tb_employee where id = #{id}
</select>
<!-- public Map<Integer ,Employee> getEmpListByLastNameLikeReturnMap(String lastName);-->
<select id="getEmpListByLastNameLikeReturnMap" resultType="com.mybatis.entity.Employee">
select * from tb_employee where last_name like #{lastName}
</select>
<!-- public List<Employee> getEmps ();-->
<select id="getEmps" resultType="com.mybatis.entity.Employee">
select * from tb_employee
</select>
<!--public void getPageByProcedure(OraclePage page);
-->
<!-- public void getPageByProcedure();
1、使用select标签定义调用存储过程
2、statementType="CALLABLE":表示要调用存储过程
3、{call procedure_name(params)} :固定写法
jdbcType:需要参考枚举类JdbcType
-->
<select id="getPageByProcedure" statementType="CALLABLE" databaseId="oracle" useCache="false">
{call hello_test(
#{start,mode=IN,jdbcType=INTEGER},
#{end,mode=IN,jdbcType=INTEGER},
#{count,mode=OUT,jdbcType=INTEGER},
#{emps,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=oraclePage}
)}
</select>
<resultMap id="oraclePage" type="com.mybatis.entity.Employee">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<result column="last_name" property="lastName"/>
</resultMap>
</mapper>