parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到mapper 文件的 sql 语句。
int 或 java.lang.Integer
hashmap 或 java.util.HashMap
list 或 java.util.ArrayList
student 或 com.bjpowernode.domain.Student
<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>
从 java 代码中把参数传递到 mapper.xml 文件。
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);
}
当 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 文件:
<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();
}
使用 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 文件:
<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();
}
参数位置从 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);
}
}
Map 集合可以存储多个值,使用Map向 mapper 文件一次传入多个参数。Map 集合使用 String的 key,Object 类型的值存储参数。 mapper 文件使用# { key }
引用参数值。
例如:Map
data.put(“myname”,”李力”);
data.put(“myage”,20);
接口方法:
/**
* 多个参数,使用Map存放多个值
*/
List<Student> selectMultiByMap(Map<String,Object> map);
mapper 文件:
<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);
}
}
#:占位符,告诉 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. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
2. #能够避免sql注入,更安全。
3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
4. $有sql注入的风险,缺乏安全性。
5. $:可以替换表名或者列名
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):
<mapper namespace="com.zep.dao.StudentDao">
<select id="selectStudentById" resultType="com.zep.domain.Student" parameterType="java.lang.Integer">
select id,name,email,age from student where id=#{studentId}
select>
<select id="selectMultiParam" resultType="com.zep.domain.Student">
select * from student where name=#{myname} or age=#{myage}
select>
<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>
<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();
}
}