五、深入理解Mybatis中的参数parameterType (传递一个简单参数,传递多个参数:@Param、使用自定义对象、按位置、使用Map)
1.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="java.lang.Integer">delete from student where id=#{studentId} </delete>1.2 MyBatis 傳遞參數
從 java 代碼中把參數傳遞到 mapper.xml 文件。
1.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是自定義的變量名稱,和方法參數名無關。
測試方法:
@Testpublic 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>測試方法:
@Testpublic 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();}1.5 多個參數-使用對象
使用 java 對象傳遞參數, java 的屬性值就是 sql 需要的參數值。 每一個屬性就是一個參數。
語法格式:
#{ property,javaType=java 中數據類型名,jdbcType=數據類型名稱 }
javaType, jdbcType 的類型 MyBatis 可以檢測出來,一般不需要設置。
常用格式 #{ property }
創建保存參數值的對象 QueryParam:
接口方法:
/*** 多個參數,使用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>測試方法:
@Testpublic 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();}1.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>測試方法:
@Testpublic 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);}}1.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> @Testpublic 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);}}1.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=1001String sql="select id,name, email,age from student where id=" + "1001";使用的Statement對象執行sql, 效率比PreparedStatement低。$:可以替換表名或者列名, 你能確定數據是安全的。可以使用$
接口方法:
mapper文件:
<!--$替換列名--><select id="selectUse$Order" resultType="com.zep.domain.Student">select * from student order by ${colName}</select>測試文件:
@Testpublic 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 # 和 $區別
1. #使用 ?在sql語句中做站位的, 使用PreparedStatement執行sql,效率高2. #能夠避免sql注入,更安全。3. $不使用占位符,是字符串連接方式,使用Statement對象執行sql,效率低4. $有sql注入的風險,缺乏安全性。5. $:可以替換表名或者列名1.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 mapperPUBLIC "-//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 {@Testpublic 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);}@Testpublic 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();}@Testpublic 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();}@Testpublic 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);}}@Testpublic 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);}}@Testpublic 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);}}@Testpublic 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();}@Testpublic 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();}}2.0 總結
總結
以上是生活随笔為你收集整理的五、深入理解Mybatis中的参数parameterType (传递一个简单参数,传递多个参数:@Param、使用自定义对象、按位置、使用Map)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Pytorch神经网络实战案例】13
- 下一篇: mysql命令速查手册