1、parameterType
parameterType:接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到mapper 文件的 sql 语句。
- int 或 java.lang.Integer
- hashmap 或 java.util.HashMap
- list 或 java.util.ArrayList
- student 或 com.bjpowernode.domain.Student
<select>,<insert>,<update>,<delete>
都可以使用 parameterType 指定类型。
例如:
<delete id="deleteStudent" parameterType="int"> delete from student where id=#{studentId} </delete>
等同于
<delete id="deleteStudent" parameterType="java.lang.Integer"> delete from student where id=#{studentId} </delete>
2、MyBatis 传递参数
从 Java 代码中把参数传递到 mapper.xml 文件。
3、一个简单参数
Dao 接口中方法的参数只有一个简单类型(Java基本类型和 String)
,占位符 #{ 任意字符 },和方法的参数名无关。
接口方法:
/** * 一个简单类型的参数: * 简单类型:mybatis把java的基本数据类型和String都叫简单类型。 * 在mapper文件获取简单类型的一个参数的值,使用 #{任意字符} * @param id * @return */ public Student selectStudentById(Integer id);
mapper 文件:
<select id="selectStudentById" resultType="com.zep.domain.Student" parameterType="java.lang.Integer"> select id,name,email,age from student where id=#{studentId} </select>
注意:
#{studentId} , 这里的studentId是自定义的变量名称,和方法参数名无关。
测试方法:
@Test public void testSelectStudentById() { /** * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口) * getMapper能够获取dao接口对应的实现类对象。 */ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); // 这句代码可以自动创建dao接口的实现类对象 //调用dao的方法,执行数据库的操作 Student student = dao.selectStudentById(1001); System.out.println("学生=" + student); }
1.4 多个参数 —— 使用@Param
当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入@Param("自定义参数名"),mapper 文件使用#{自定义参数名}。
例如定义:List selectStudent( @Param("personName") String name ) { … }
mapper文件:select * from student where name = #{ personName}
接口方法:
/** * 多个参数:命名参数,在形参定义的前面加入@Param("自定义参数名称") */ public List<Student> selectMultiParam(@Param("myname") String name, @Param("myage") Integer age);
mapper 文件:
<!--多个参数,使用@Param命名--> <select id="selectMultiParam" resultType="com.zep.domain.Student"> select * from student where name=#{myname} or age=#{myage} </select>
测试方法:
@Test public void testSelectMultiParam() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectMultiParam("李四", 20); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); }
5、多个参数 —— 使用对象
使用 Java 对象传递参数, Java 的属性值就是 SQL 需要的参数值。 每一个属性就是一个参数。
语法格式:
#{ property, javaType=java中数据类型名, jdbcType=数据类型名称 }
javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。
常用格式 #{ property }
创建保存参数值的对象 QueryParam:
package com.zep.vo; public class QueryParam { private String paramName; private Integer paramAge; public String getParamName() { return paramName; } public void setParamName(String paramName) { this.paramName = paramName; } public Integer getParamAge() { return paramAge; } public void setParamAge(int paramAge) { this.paramAge = paramAge; } }
接口方法:
/** * 多个参数,使用java对象作为接口中方法的参数 * */ List<Student> selectMultiObject(QueryParam param);
mapper 文件:
<!--多个参数。使用java对象的属性值,作为参数的实际值 适用对象的语法:#{属性名,javaType=类型名称,jdbcType=数据类型} 很少用 javaType:指java中的属性数据类型 jdbcType: 在数据库中的数据类型 例如:#{paramName,javaType=java.lang.String,jdbcType=VARCHAR} select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR} or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER} 我们使用的简化方式:#{对应接口的参数的类型,即参数对象的属性名},javaType,jdbcType的值mybatis反射能获取。不用提供 --> <select id="selectMultiObject" resultType="com.zep.domain.Student"> select * from student where name=#{paramName} or age=#{paramAge} </select>
或者
<select id="selectMultiObject" resultType="com.zep.domain.Student"> select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR} or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER} </select>
测试方法:
@Test public void testSelectMultiObject() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); QueryParam queryParam = new QueryParam(); queryParam.setParamName("张三"); queryParam.setParamAge(28); List<Student> students = dao.selectMultiObject(queryParam); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); }
6、多个参数 —— 按位置
参数位置从 0 开始, 引用参数语法 #{ arg 位置 }, 第一个参数是#{arg0}, 第二个是#{arg1}
注意:mybatis-3.3 版本和之前的版本使用#{0}, #{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。
接口方法:
/** * 多个参数,简单类型的,按位置来传值 * mybatis 3.4之前,使用#{0},#{1} * mybatis 3.4之后,使用#{arg0},#{arg1} */ List<Student> selectMultiPosition(String name,Integer age);
mapper 文件:
<!--多个参数使用位置--> <select id="selectMultiPosition" resultType="com.zep.domain.Student"> select * from student where name=#{arg0} or age=#{arg1} </select>
测试方法:
@Test public void testSelectMultiPosition() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectMultiPosition("李四",20); for (Student stu : students) { System.out.println("学生=" + stu); } }
7、多个参数 —— 使用 Map
Map 集合可以存储多个值,使用Map向 mapper 文件一次传入多个参数。Map 集合使用 String的 key,Object 类型的值存储参数。 mapper 文件使用#{key}引用参数值。
例如:Map<String,Object> data = new HashMap<String,Object>();
data.put("myname", "李力");
data.put("myage", 20);
接口方法:
/** * 多个参数,使用Map存放多个值 */ List<Student> selectMultiByMap(Map<String,Object> map);
mapper 文件:
<!--多个参数,使用Map,使用的语法:#{map的key}--> <select id="selectMultiByMap" resultType="com.zep.domain.Student"> select * from student where name=#{myname} or age=#{myage} </select>
测试方法:
@Test public void testSelectMultiByMap() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Map<String,Object> data = new HashMap<>(); data.put("myname","张三"); data.put("myage",20); List<Student> students = dao.selectMultiByMap(data); for (Student stu : students) { System.out.println("学生=" + stu); } }
8、#和$
#:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法
mapper 文件
<select id="selectStudentById" resultType="com.zep.domain.Student"> select id,name,email,age from student where id=#{studentId} </select>
转为 MyBatis 的执行是:
String sql=” select id,name,email,age from student where id=?”; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1,1005);
解释:
where id=? 就是 where id=#{studentId}
ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
$ 字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置
。使用 Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。
select id,name, email,age from student where id=#{studentId}
# 的结果: select id,name, email,age from student where id=? select id,name, email,age from student where id=${studentId} $ 的结果:select id,name, email,age from student where id=1001 String sql="select id,name, email,age from student where id=" + "1001"; 使用的Statement对象执行sql, 效率比PreparedStatement低。
$:可以替换表名或者列名, 你能确定数据是安全的。可以使用$
接口方法:
List<Student> selectUse$Order(@Param("colName") String colName);
mapper文件:
<!--$替换列名--> <select id="selectUse$Order" resultType="com.zep.domain.Student"> select * from student order by ${colName} </select>
测试文件:
@Test public void testSelectUse$Order() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectUse$Order("name"); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); }
1.8.1 # 和 $区别
- #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
- #能够避免sql注入,更安全。
- $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
- $有sql注入的风险,缺乏安全性。
- $:可以替换表名或者列名
9、完整代码
StudentDao.java:
package com.zep.dao; import com.zep.domain.Student; import com.zep.vo.QueryParam; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; public interface StudentDao { /** * 一个简单类型的参数: * 简单类型:mybatis把java的基本数据类型和String都叫简单类型。 * 在mapper文件获取简单类型的一个参数的值,使用 #{任意字符} * @param id * @return */ public Student selectStudentById(Integer id); /** * 多个参数:命名参数,在形参定义的前面加入@Param("自定义参数名称") */ public List<Student> selectMultiParam(@Param("myname") String name, @Param("myage") Integer age); /** * 多个参数,使用java对象作为接口中方法的参数 * */ List<Student> selectMultiObject(QueryParam param); List<Student> selectMultiStudent(Student student); /** * 多个参数,简单类型的,按位置来传值 * mybatis 3.4之前,使用#{0},#{1} * mybatis 3.4之后,使用#{arg0},#{arg1} */ List<Student> selectMultiPosition(String name,Integer age); /** * 多个参数,使用Map存放多个值 */ List<Student> selectMultiByMap(Map<String,Object> map); /** * */ List<Student> selectUse$(@Param("myname") String name); List<Student> selectUse$Order(@Param("colName") String colName); }
mapper文件(StudentDao.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="com.zep.dao.StudentDao"> <!-- parameterType:dao接口中方法参数的数据类型。 parameterType它的值是java的数据类型全限定名称或者是mybatis定义的别名 例如:parameterType="java.lang.Integer" parameterType="int" 注意:parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型,所以可以没有。一般我们也不写。 使用#{}之后,mybatis执行sql使用的是jdbc中的PreparedStatement对象 由mybatis执行下面的代码: 1. mybatis创建Connection,PreparedStatement对象 String = "select id,name,email,age from student where id=?"; PreparedStatement pst = conn.preparedStatement(sql); pst.setInt(1,1001); 2.执行sql封装为resultType="com.zep.domain.Student"这个对象 ResultSet rs = pst.executeQuery(); Student student = null; while(rs.next){ //从数据库中取表的一行数据,存到一个java对象属性中 student = new Student(); student.setId(rs.getInt("id")); student.setName(rs.getString("name")); student.setEmail(rs.getString("email")); student.setAge(rs.getInt("age")); } return student; //赋给了dao方法调用的返回值 --> <select id="selectStudentById" resultType="com.zep.domain.Student" parameterType="java.lang.Integer"> select id,name,email,age from student where id=#{studentId} </select> <!--多个参数,使用@Param命名--> <select id="selectMultiParam" resultType="com.zep.domain.Student"> select * from student where name=#{myname} or age=#{myage} </select> <!--多个参数。使用java对象的属性值,作为参数的实际值 适用对象的语法:#{属性名,javaType=类型名称,jdbcType=数据类型} 很少用 javaType:指java中的属性数据类型 jdbcType: 在数据库中的数据类型 例如:#{paramName,javaType=java.lang.String,jdbcType=VARCHAR} select * from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR} or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER} 我们使用的简化方式:#{对应接口的参数的类型,即参数对象的属性名},javaType,jdbcType的值mybatis反射能获取。不用提供 --> <select id="selectMultiObject" resultType="com.zep.domain.Student"> select * from student where name=#{paramName} or age=#{paramAge} </select> <select id="selectMultiStudent" resultType="com.zep.domain.Student"> select * from student where name=#{name} or age=#{age} </select> <!--多个参数使用位置--> <select id="selectMultiPosition" resultType="com.zep.domain.Student"> select * from student where name=#{arg0} or age=#{arg1} </select> <!--多个参数,使用Map,使用的语法:#{map的key}--> <select id="selectMultiByMap" resultType="com.zep.domain.Student"> select * from student where name=#{myname} or age=#{myage} </select> <!--使用 ${} --> <select id="selectUse$" resultType="com.zep.domain.Student"> select * from student where name=${myname} </select> <!--$替换列名--> <select id="selectUse$Order" resultType="com.zep.domain.Student"> select * from student order by ${colName} </select> </mapper>
测试代码:
package com.zep; import com.zep.dao.StudentDao; import com.zep.domain.Student; import com.zep.utils.MybatisUtils; import com.zep.vo.QueryParam; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestMybatis { @Test public void testSelectStudentById() { /** * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口) * getMapper能够获取dao接口对应的实现类对象。 */ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); // 这句代码可以自动创建dao接口的实现类对象 //调用dao的方法,执行数据库的操作 Student student = dao.selectStudentById(1001); System.out.println("学生=" + student); } @Test public void testSelectMultiParam() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectMultiParam("李四", 20); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); } @Test public void testSelectMultiObject() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); QueryParam queryParam = new QueryParam(); queryParam.setParamName("张三"); queryParam.setParamAge(28); List<Student> students = dao.selectMultiObject(queryParam); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); } @Test public void testSelectMultiStudent(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Student student = new Student(); student.setAge(20); student.setName("张三"); List<Student> students = dao.selectMultiStudent(student); for (Student stu : students) { System.out.println("学生=" + stu); } } @Test public void testSelectMultiPosition() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectMultiPosition("李四",20); for (Student stu : students) { System.out.println("学生=" + stu); } } @Test public void testSelectMultiByMap() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); Map<String,Object> data = new HashMap<>(); data.put("myname","张三"); data.put("myage",20); List<Student> students = dao.selectMultiByMap(data); for (Student stu : students) { System.out.println("学生=" + stu); } } @Test public void testSelectUse$() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectUse$("'李四'"); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); } @Test public void testSelectUse$Order() { SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectUse$Order("email"); for (Student student : students) { System.out.println("学生=" + student); } sqlSession.close(); } }
10、总结
摘自:https://blog.csdn.net/weixin_44827418/article/details/111429783