Data Access 之 MyBatis(三) - SQL Mapping XML(Part B)(下)

简介: Data Access 之 MyBatis(三) - SQL Mapping XML(Part B)

当参数传入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中的

584a294201664df7b6c9c6c8ba42317b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

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>
复制代码

执行测试

3eb1ffdfa7524d0d83d38617ad8adb4b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

如果使用#{}传递表名,修改getEmployeeByIdAndName的映射SQL,使用#{tableName}获取表名,再次执行测试

f003332a6972424a932e2e3fc6cfdd96_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

出现报错,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);
    }
}
复制代码

执行该测试方法

1d1ff01d52214b67945e00f9b31d4579_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

查询结果封装成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);
}
复制代码

执行测试

adf0a5c30f8a4a34b71c0fcb85cbce3a_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

默认封装成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);
}
复制代码

执行测试

409400d20afc491b9b9adca19252dec8_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

增加主键定义,使用@MapKey指定一个Map的主键

@MapKey("id")
Map<Integer, Employee> getAllEmployeesWithMap();
复制代码

再次执行测试

d85924f34d0747a08573d075ac667a25_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

在测试方法中打印出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());
}
复制代码

出现了类型转换异常

224b301db9174f4dbc0e5b3f54e7e17e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

这是因为SQL映射语句中定义的resultType为Map,所以会出现这种错误,修改sql映射语句中resultType类型要是集合中元素的类型

<select id="getAllEmployeesWithMap" resultType="com.citi.entity.Employee">
    select * from t_employee
</select>
复制代码

再次测试

8c89760d259b43afaf70591ec3c53a54_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

查询多条数据返回一个Map,resultType为集合Value保存的元素的类型



相关文章
|
4月前
|
XML SQL 数据格式
XML动态sql查询当前时间之前的信息报错
XML动态sql查询当前时间之前的信息报错
55 2
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
16天前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
45 10
|
3月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
3月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
60 1
|
5月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
98 3
|
6月前
|
SQL 人工智能 Java
mybatis-plus配置sql拦截器实现完整sql打印
_shigen_ 博主分享了如何在MyBatis-Plus中打印完整SQL,包括更新和查询操作。默认日志打印的SQL用?代替参数,但通过自定义`SqlInterceptor`可以显示详细信息。代码示例展示了拦截器如何替换?以显示实际参数,并计算执行时间。配置中添加拦截器以启用此功能。文章提到了分页查询时的限制,以及对AI在编程辅助方面的思考。
831 5
mybatis-plus配置sql拦截器实现完整sql打印
|
5月前
|
SQL Java 数据库连接
mybatis动态SQL常用语法总结
MyBatis 使用 OGNL 表达式语言处理动态SQL,如 `if` 标签进行条件判断,`choose`、`when`、`otherwise` 实现多条件选择,`where`、`set` 管理SQL关键字,`trim` 提供通用修剪功能,`foreach` 遍历集合数据。`sql` 和 `include` 用于代码重用,`selectKey` 处理插入后的返回值。参数传递支持匿名、具名、列表、Map、Java Bean和JSON方式。注意SQL转义及使用合适的jdbcType映射Java类型。
103 7
|
6月前
|
SQL XML 数据库
后端数据库开发高级之通过在xml文件中映射实现动态SQL
后端数据库开发高级之通过在xml文件中映射实现动态SQL
57 3