一文搞懂Mybatis中Mapper配置文件获取参数的五种方式
作者:Fon |
前提提要
本系列Mybatis笔记基于mybatis3.5.2 , https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.2中有详细的文档说明,可以进行下载阅读,本文只是对Mybatis的一些常用操作进行汇总总结。
- IDE: IntelliJ IDEA 2021.3
- 构建工具: apache-maven-3.6.3
- MySQL版本:MySQL 5.7.35
- MyBatis版本:MyBatis 3.5.7
对于mybatis框架的使用,按照上次介绍的,我们配置的映射文件中,通过namespace将映射文件和接口关联起来了。
具体方法通过id精确的对应。然后,方法对应的具体数据操作,在mapper文件中的<insert><select>.... 书写具体的SQL语句来进行实现。
但是,对于一些需要传输数据的行为,如条件查询,插入操作等等,都需要将用户调用接口的实际参数数据,落实到具体的mapper文件中的各个方法中。
问题来了?
给接口的实际参数,mapper实际操作如何取对应的数据, 数据是以什么方式传递给mapper中各标签实现数据的CRUD操作的呢?
一,IDEA中设置各种配置文件的模板
这节内容主要就是平时开发过程中的技巧性操作。
1. 设置mybatis-config.xml文件模板
模板内容:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"></properties> <typeAliases> <package name=""></package> </typeAliases> <!--设置连接数据库的环境--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--引入映射文件--> <mappers> <package name=""/> </mappers> </configuration>
在IDEA
中添加mybatis-config.xml
文件模板的具体操作:
最后的效果如图所示,新建完上述模板之后,就可以按照上述你创建的模板创建一个mybatis-config.xml
文件。
2. 设置 **mapper.xml映射文件模板
和上述mybatis-confg.xml
设置文件模板一样,模板内容如下:
<?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=""> </mapper>
具体的操作和设置mybatis-config.xml
操作是一样的。
二,获取参数的两种方式
在谈将调用接口的实际参数传给mapper
中各个标签实际操作是什么样之前,我们先看看mapper
中获取参数的两种方式,我们知道JDBC
中有两种设置参数的方式:
通过参数预处理的方式 2. 通过拼接SQL的方式
@Test public void testJDBC() throws SQLException, ClassNotFoundException { String username = "cherry"; Class.forName(""); Connection connection = DriverManager.getConnection("", "", ""); // 1. 字符串拼接 ->获得预编译对象 -》sql注入问题 PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where username = '" + username + "'"); // 2. 占位符 PreparedStatement ps2 = connection.prepareStatement("select * from t_user where username = ?"); ps2.setString(1, username); }
对应于MyBatis
中,我们也有这两种方式:1. 字符串拼接 2. 占位符
MyBatis获取参数值的两种方式:${}
和#{}
,就和JDBC
中的两种方式一脉相承。
${}
的本质就是字符串拼接#{}
的本质就是占位符赋值
${}
使用字符串拼接的方式拼接sql
,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
但是#{}
使用占位符赋值的方式拼接sql
,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号(尽量使用这一种)。
三,MyBatis获取参数值的五种情况
通过了上述说明了Mybatis
中两种获取基本方式的区别。下面通过给接口
床传递实参不同的形式来划分为一下五种情况进行一一的说明。
3.1 单个字面量类型的参数
也就是如果调用的形式是:
getUserById(1)
若mapper
接口中的方法参数为单个的字面量类。此时可以使用${}
和#{}
以任意的名称获取参数的值,注意${}
需要手动加单引号。
如下所示:
public interface ParameterMapper { /** * 单个的字面量类型: * 根据用户名查询用户信息 */ User getUserByUserName(String username); }
在对应的配置类中进行配置,按照上述的方式,都可以进行配置,如下:
Notice:使用#{}
,里面内容可以随便写,都是传进来的username
的值。
方式一:
<!-- User getUserByUserName(String username);--> <!-- 使用#{},里面内容可以随便写,都是传进来的username的值--> <select id="getUserByUserName" resultType="User"> select * from t_user where username = #{username} </select>
方式二:
<!-- User getUserByUserName(String username);--> <select id="getUserByUserName" resultType="User"> <!-- select * from t_user where username = ${username} 如果使用这种方式,得到的sql语句是: Preparing: select * from t_user where username = RUOYI 而其中username的值‘RUOYI'没有单引号,语句不正确,会报错。 因此要手动添加单引号 --> select * from t_user where username = '${username}' </select>
测试类:
/** * MyBatis获取参数值的各种情况: * 情况1: mapper接口方法的参数为单个字面量的参数 * 可以通过${} #{}以任意的字符串获得参数值,但需要注意${}的单引号问题 */ @Test public void testgetUserByUserName(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.getUserByUserName(""); System.out.println(user); }
3.2 多个字面量类型的参数
若在mapper
接口的方法中有多个参数的时候,我们MyBatis
的操作是会自动的将这些参数放到一个Map
集合中。通过以arg0, arg1, arg2... argn
,以参数值为值。还有一种就是通过param1, param2...
,以参数为值。
因此,只要通过#{}
或者是${}
访问map
集合中的键就可以获取到对应的值。但是需要注意的是${}
需要手动加上单引号。
public interface ParameterMapper { /** * 验证登录 */ User checkLogin(String username, String password); }
对应在mapper
映射文件中:
<!-- User checkLogin(String username, String password);--> <select id="checkLogin" resultType="User"> <!-- 写:select * from t_user where username = #{username} and password = #{password} 会报错:Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2] 因为sql语句没有解析成功--> <!--以map集合形式存储,arg0->param0, arg1->param1,这时直接用键arg访问就好了,用param访问也行。 以下两种方式选一个:--> select * from t_user where username = #{arg0} and password = #{arg1} select * from t_user where username = '${param1}' and password = '${param2}' </select>
测试类:
/** * 情况2:mapper接口方法的参数为多个时 * 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储 * a》以arg0,arg1。。为键,参数为值 * b》以param0,param1。。为键,参数位置 * 因此只需要通过#{}和${}以键的方式访问值即可,但需要注意${}的单引号问题 */ @Test public void testCheckLogin(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.checkLogin("fangshaolei","123456"); System.out.println(user); }
Notice: 写:select * from t_user where username = #{username} and password = #{password}
会报错:Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
因为sql
语句没有解析成功
3.3 Map集合类型的参数
我们大概有了一些思路,基本上对于所有的参数。Mybatis
的操作都是先将所有的参数都封装到一个map
中,然后在mapper
中使用#{}
或者是${}
来进行取。
如果mapper
接口中的方法需要的参数为多个时,此时可以手动创建map集合,也就是我们不在通过mybatis
来进行创建参数,而是手动的自己传过去一个map
。
所以,将这些数据放在map
中只需要通过${}
和#{}
访问map
集合的键就可以获取相对应的值,注意${}
需要手动加单引号.
public interface ParameterMapper { /** * 验证登录 */ User checkLoginByMap(Map<String, Object> map); }
在对应的map
中进行取用的操作。
<!-- User checkLoginByMap(Map<String, Object> map);--> <select id="checkLoginByMap" resultType="User"> select * from t_user where username = #{username} and password = #{password} </select>
测试类:
/** * 情况3:若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储 * 只需要通过#{} ${}以键的方式访问值即可,但是需要注意${}的单引号问题 */ @Test public void testCheckLoginByMap(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); Map<String, Object> map = new HashMap<>(); map.put("username","RUOYI"); map.put("password","123456"); User user = mapper.checkLoginByMap(map); System.out.println(user); }
Notice:但是需要注意的是,对于自己封装的map
的形式,在使用两种方式进行取用的时候,需要指定在map
中的键,也就是我们自己存在map
数据中的键。
3.4 实体类参数
如果mapper
接口中的方法参数是实体类对象的时候,此时可以使用 #{}
和${}
,通过访问实体类对象中的属性名获取属性值,同样需要注意的是:${}
需要手动加上单引号。
其实,实体类对象参数,在mybatis
中会被封装成map
对象的形式。Mapper
对应的接口:
public interface ParameterMapper { /** * 添加用户信息 */ int insertUser(User user); }
Mapper.xml
文件中的配置:
<!-- int insertUser(User user);--> <!-- 找到相对应的get方法,如username->找getUsername(),看get/set方法--> <insert id="insertUser"> insert into t_user values(null, #{username}, #{password}, #{age}, #{gender}, #{email}) </insert>
测试类:
/** * 情况4:mapper接口方法的参数是实体类类型的参数(web从control层传过来的) * 只需要通过#{} ${}以属性的方式访问属性值即可,但是需要注意${}的单引号问题 */ @Test public void testInsertUser(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = new User(null, "fangshaolei", "123456", 66, "m", "sl.fang@gmail.com"); mapper.insertUser(user); }
Notice:同样需要注意的是,#{}
中的参数名称不能随意的写,要和属性名称一致。
3.5 使用@Param标识参数
通过上述的四种方法,我们知道,除了只有一个字面量参数之外。其他的参数通过#{}
或者是${}
取用的值都需要正确的给定Mybatis
内部map
的键。
如果是多个字面量,按照Mybatis
内部默认的键来进行取用。如果传过来的参数是自己定义的Map
或者是实体类对象
的形式。则在取用的时候,指定参数名称和自定义Map
的键一致和如果参数是实体类对象,则需要和对象的属性名一致。
但是,我们能够自定义Mybatis
内部已经封装好的Map
的key
,从而通过#{}
或者是${}
的形式,利用我们自定义的key
来进行取用呢?
这就需要通过@Param
来实现。
可以通过@Param
注解标识mapper
接口中的方法参数。此时,会将这些参数放在map
集合中,以@Param
注解的value
属性值为键,以参数为值;
以 param1,param2...
为键,以参数为值;
只需要通过${}
和#{}
访问map
集合的键就可以获取相对应的值, 注意${}
需要手动加单引号。
public interface ParameterMapper { /** * 验证登录 (使用@Param) */ User checkLoginByParam(@Param("username") String username, @Param("password") String password); }
对应的mapper.xml
配置:
<!-- 以@Param的值为键,参数为值; 或以"param1"/"param2"为键,参数为值--> <!-- User checkLoginByParam(@Param("username") String username, @Param("password") String password);--> <select id="checkLoginByParam" resultType="User"> select * from t_user where username = #{username} and password = #{password} </select>
测试类:
/** * 情况5:使用@Param注解来命名参数 * 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储 * a》以@Param的值为键,参数为值; @Param(value = "xxx") * b》以param0,param1...为键,参数为值 */ @Test public void testCheckLoginByParam(){ SqlSession sqlSession = SqlSessionUtils.getSqlSession(); ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class); User user = mapper.checkLoginByParam("fangshaolei","123456"); System.out.println(user); }
四,总结
以上就是一文搞懂Mybatis中Mapper配置文件获取参数的五种方式的详细内容,更多关于Mybatis Mapper获取参数的资料请关注脚本之家其它相关文章!