Mybatis获取参数值的两种方式
mybatis获取参数值的方式有两种: ${} 和 #{}
- ${} 这个的本质就是字符串拼接
- 这个无法避免sql注入攻击
- #{} 这个的本质就是占位符(尽量使用 #{} 的方式)
- 可以避免sql注入
mybatis获取参数值的情况
1.mapper接口方法的参数为单个字面量类型
通过${} 和 #{} 以任意名称获取参数值, 但是${} 需要注意单引号的问题
mapper.xml文件
<!----> <select id="queryUserById" resultType="org.xiji.enty.User"> <!--通过 #{}--> <!-- select * from user where id=#{id} --> <!--单个的名字可以随意 --> <!-- select * from user where id=#{sdasd} --> <!--使用${id} 也是可以的但是要注意 ${}中的单引号拼接问题--> select * from user where id=${id} </select>
mapper接口文件
/**
* 通过用户id查询数据
*/
User queryUserById(int id);
测试代码
/** * 单一类型变量取值 * #{} * ${} 这个需要注意 单引号问题 */ @Test public void test2(){ User user1 = userMapper.queryUserById(1); System.out.println(user1.toString()); }
2.mapper接口方法的参数为多个时
当mapper接口的参数为多个时,名字随意写,或者与接口名对应会爆错
org.apache.ibatis.binding.BindingException: Parameter
Mapper接口
/** * 通过用户名和密码查询数据 */ User queryUserInfoBYUsernameAndPassword(String username,String password);
Mapper.xml
<!--通过用户名和密码查询数据--> <select id="queryUserInfoBYUsernameAndPassword" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select>
测试代码
/** * 多个参数变量取值 */ @Test public void test3(){ User xiji = userMapper.queryUserInfoBYUsernameAndPassword("xiji", "123456"); System.out.println(xiji.toString()); }
错误收集
org.mybatis.spring.MyBatisSystemException:
### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
###at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:99)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:347)
at jdk.proxy2/jdk.proxy2.$Proxy20.selectOne(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:154)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at jdk.proxy2/jdk.proxy2.$Proxy21.queryUserInfoBYUsernameAndPassword(Unknown Source)
at MyBatisTest.test3(MyBatisTest.java:42)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:210)
at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:46)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:115)
at org.apache.ibatis.executor.BaseExecutor.createCacheKey(BaseExecutor.java:225)
at org.apache.ibatis.executor.CachingExecutor.createCacheKey(CachingExecutor.java:149)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:333)
... 10 more
解决方法
1)使用arg1,arg0,或者param1,param2
注
#{} 和 ${} 以键取值
Cause: org.apache.ibatis.binding.BindingException: Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
<!--通过用户名和密码查询数据--> <select id="queryUserInfoBYUsernameAndPassword" resultType="org.xiji.enty.User"> select * from user where username=#{arg0} and password=#{arg1} </select>
3.修改mapper接口参数为map
通过mapper集合传入的值,我们可以自定义键,通过键取值
注:这个方式需要你知道mapper.xml文件中自定定义的键值
mapper接口文件
/**
* 通过map集合传入值
*/
User queryUserInfoByMap(Map<String,Object> map);
mapper.xml文件
<!--通过map集合传值,虽然可以自定义键,但是需要知道xml的键名--> <select id="queryUserInfoByMap" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select>
map测试代码
/**
* 以map集合为例
*/
@Test
public void testByMap(){
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("username","zs");
objectObjectHashMap.put("password","456789");
User xiji = userMapper.queryUserInfoByMap(objectObjectHashMap);
System.out.println(xiji.toString());}
测试结果
4.通过对象获取参数值
mapper接口
/**
* 通过对象获取值
*/
User queryUserInfoByUser(User user);
mapper.xml文件
<!--通过对象获取值--> <select id="queryUserInfoByUser" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select>
测试代码
/** * 通过对象获取值 */ @Test public void testByUser(){ User user = new User(); user.setUsername("xiji"); user.setPassword("123456"); User xiji = userMapper.queryUserInfoByUser(user); System.out.println(xiji.toString()); }
测试结果
5.通过@param注解获取
@Param 注解 相当于自定义键 ===》 可以通过键名取去取值
mapper接口
/** * * 通过param注解访问 */ User queryUserInfoByParam(@Param("username") String name,@Param("password") String password);
mapper.xml文件
<!--通过param注解 获取值--> <select id="queryUserInfoByParam" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select>
测试代码
/** * 通过param注解获取参数 */ @Test public void testByParam(){ User xiji = userMapper.queryUserInfoByParam("xiji","123456"); System.out.println(xiji.toString()); }
测试结果
附加
1)完整的UserMapper接口
package org.xiji.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.xiji.enty.User; import java.util.Map; /** * userMapper */ @Mapper public interface UserMapper { /** * 增加用户 */ int addUser(@Param("user") User user); /** * 通过用户id查询数据 */ User queryUserById(int id); /** * 通过用户名和密码查询数据 */ User queryUserInfoBYUsernameAndPassword(String username,String password); /** * 通过map集合传入值 */ User queryUserInfoByMap(Map<String,Object> map); /** * 通过对象获取值 */ User queryUserInfoByUser(User user); /** * * 通过param注解访问 */ User queryUserInfoByParam(@Param("username") String name,@Param("password") String password); }
2)完整的UserMapper.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="org.xiji.mapper.UserMapper"> <insert id="addUser"> insert into user(username,password,userInfo) values(#{user.username},#{user.password},#{user.userInfo}) </insert> <!----> <select id="queryUserById" resultType="org.xiji.enty.User"> <!--通过 #{}--> <!-- select * from user where id=#{id} --> <!--单个的名字可以随意 --> <!-- select * from user where id=#{sdasd} --> <!--使用${id} 也是可以的但是要注意 ${}中的单引号拼接问题--> select * from user where id=${id} </select> <!--通过用户名和密码查询数据--> <select id="queryUserInfoBYUsernameAndPassword" resultType="org.xiji.enty.User"> select * from user where username=#{arg0} and password=#{arg1} </select> <!--通过map集合传值,虽然可以自定义键,但是需要知道xml的键名--> <select id="queryUserInfoByMap" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select> <!--通过对象获取值--> <select id="queryUserInfoByUser" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select> <!--通过param注解 获取值--> <select id="queryUserInfoByParam" resultType="org.xiji.enty.User"> select * from user where username=#{username} and password=#{password} </select> </mapper>
3)完整的测试代码
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.xiji.enty.User; import org.xiji.mapper.UserMapper; import java.util.HashMap; import java.util.Map; @SpringJUnitConfig(locations = {"classpath:springConfig.xml"}) public class MyBatisTest { @Autowired UserMapper userMapper; @Test public void test(){ User user = new User(); user.setUsername("xiji"); user.setPassword("123456"); user.setUserInfo("hello world"); userMapper.addUser(user); } /** * 单一类型变量取值 * #{} * ${} 这个需要注意 单引号问题 */ @Test public void test2(){ User user1 = userMapper.queryUserById(1); System.out.println(user1.toString()); } /** * 多个参数变量取值 */ @Test public void test3(){ User xiji = userMapper.queryUserInfoBYUsernameAndPassword("xiji", "123456"); System.out.println(xiji.toString()); } /** * 以map集合为例 */ @Test public void testByMap(){ HashMap<String, Object> objectObjectHashMap = new HashMap<>(); objectObjectHashMap.put("username","zs"); objectObjectHashMap.put("password","456789"); User xiji = userMapper.queryUserInfoByMap(objectObjectHashMap); System.out.println(xiji.toString()); } /** * 通过对象获取值 */ @Test public void testByUser(){ User user = new User(); user.setUsername("xiji"); user.setPassword("123456"); User xiji = userMapper.queryUserInfoByUser(user); System.out.println(xiji.toString()); } /** * 通过param注解获取参数 */ @Test public void testByParam(){ User xiji = userMapper.queryUserInfoByParam("xiji","123456"); System.out.println(xiji.toString()); } }
4)User实体
package org.xiji.enty; public class User { private int id; private String username; private String password; private String userInfo; public User() { } public User(int id, String username, String password, String userInfo) { this.id = id; this.username = username; this.password = password; this.userInfo = userInfo; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUserInfo() { return userInfo; } public void setUserInfo(String userInfo) { this.userInfo = userInfo; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", userInfo='" + userInfo + '\'' + '}'; } }
5)所用sql文件
/* Navicat Premium Data Transfer Source Server : mybatis Source Server Type : MySQL Source Server Version : 80025 Source Host : localhost:3306 Source Schema : mybatis Target Server Type : MySQL Target Server Version : 80025 File Encoding : 65001 Date: 13/09/2024 22:45:23 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '用户id', `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名字', `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户密码', `userInfo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户信息', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
user.sql官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘