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保存的元素的类型



相关文章
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
1683 0
|
9月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
529 18
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
957 0
|
9月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
399 0
|
12月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
1153 5
|
XML Java 数据库连接
二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)
二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)
429 21
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
SQL XML Java
九、MyBatis动态SQL
九、MyBatis动态SQL
251 2