当参数传入Map时,可以使用#{Key}来获取参数的Value。
当一个方法中集合了以上所有情况,即多个参数的情况
getByIdAndNameAndEmployee(@Param("id) id, String empName, Employee employee); 复制代码
id使用#{id}取值,empName使用#{param2}取值,使用#{param3.email}可以取出Employee中的email信息
参数处理
SQL映射文件中SQL语句参数位置支持的属性有javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName等
jdbcType
参数也可以指定一个特殊的数据类型
#{property,javaType=int,jdbcType=NUMERIC} #{height,javaType=double,jdbcType=NUMERIC,numericScale=2} 复制代码
- javaType通常可以从参数对象中确定
- 如果null被当作值来传递,对于所有可能为空的列,需要设置jdbcType
- 对于数值类型,可以设置小数点后保留的位数
<select id="getEmpByIdAndEmpName" resultType="com.citi.entity.Employee"> select * from t_employee where id = #{id,jdbcType=INTEGER} and empname = #{name} </select> 复制代码
#{}与${}
获取参数的值可以使用#{}或者${}
- #{key}:预编译到SQL中,较安全
- ${key}:拼接到SQL中,会有SQL注入漏洞问题
修改getEmployeeByIdAndEmpName方法对应的SQL语句,使用${}取值
<select id="getEmpByIdAndEmpName" resultType="com.citi.entity.Employee"> select * from t_employee where id = ${id} and empname = #{name} </select> 复制代码
执行测试,查看执行的SQL可以发现id=1是直接拼接到SQL中的
SQL语句中只有参数位置是支持预编译的,${}可以用作动态传递表名
修改getEmployeeByIdAndName测试方法,在paramMap中增加表名信息
@Test public void getEmployeeByIdAndName(){ EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class); Map<String, Object> paramMap = new HashMap<>(); paramMap.put("id",1); paramMap.put("name","stark"); paramMap.put("tableName","t_employee"); Employee employee = employeeDao.getEmployeeByIdAndName(paramMap); System.out.println(employee); } 复制代码
修改getEmployeeByIdAndName的映射SQL,使用${tableName}获取表名
<select id="getEmployeeByIdAndName" resultType="com.citi.entity.Employee"> select * from ${tableName} where id = #{id} and empname = #{name} </select> 复制代码
执行测试
如果使用#{}传递表名,修改getEmployeeByIdAndName的映射SQL,使用#{tableName}获取表名,再次执行测试
出现报错,SQL语句中只有参数位置是支持预编译的
查询返回List
EmployeeDao接口中新增方法getAllEmployees,查询所有的员工
List<Employee> getAllEmployees(); 复制代码
employee.xml 增加映射SQL
<!--如果返回的是集合,resultType写的是集合中元素的类型--> <select id="getAllEmployees" resultType="com.citi.entity.Employee"> select * from t_employee </select> 复制代码
增加测试方法
@Test public void getAllEmployees(){ EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class); List<Employee> employeeList = employeeDao.getAllEmployees(); for (Employee employee : employeeList) { System.out.println(employee); } } 复制代码
执行该测试方法
查询结果封装成Map
查询返回单条记录的情况下列名作为Key,值作为Value
新增方法
Map<String, Object> getEmployeeByIdWithMap(Integer id); 复制代码
增加SQL映射语句,由于返回的是Map类型数据,所以resultType为map
<select id="getEmployeeByIdWithMap" resultType="map"> select * from t_employee where id = #{id} </select> 复制代码
增加测试方法
@Test public void getEmployeeByIdWithMap(){ EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class); Map<String, Object> employeeMap = employeeDao.getEmployeeByIdWithMap(1); System.out.println(employeeMap); } 复制代码
执行测试
默认封装成Map后,列名作为Key,值作为Value
查询返回多条记录情况下封装成Map
定义方法
Map<Integer, Employee> getAllEmployeesWithMap(); 复制代码
employee.xml中增加SQL映射语句
<select id="getAllEmployeesWithMap" resultType="map"> select * from t_employee </select> 复制代码
增加测试方法
@Test public void getAllEmployeesWithMap(){ EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class); Map<Integer, Employee> employeeMap = employeeDao.getAllEmployeesWithMap(); System.out.println(employeeMap); } 复制代码
执行测试
将
增加主键定义,使用@MapKey指定一个Map的主键
@MapKey("id") Map<Integer, Employee> getAllEmployeesWithMap(); 复制代码
再次执行测试
在测试方法中打印出key为1的元素的属性,在getAllEmployeesWithMap测试方法中增加代码
@Test public void getAllEmployeesWithMap(){ EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class); Map<Integer, Employee> employeeMap = employeeDao.getAllEmployeesWithMap(); System.out.println(employeeMap); Employee employee = employeeMap.get(1); System.out.println(employee.getEmpName()); } 复制代码
出现了类型转换异常
这是因为SQL映射语句中定义的resultType为Map,所以会出现这种错误,修改sql映射语句中resultType类型要是集合中元素的类型
<select id="getAllEmployeesWithMap" resultType="com.citi.entity.Employee"> select * from t_employee </select> 复制代码
再次测试
查询多条数据返回一个Map,resultType为集合Value保存的元素的类型