前面两篇分别介绍了mybatis的增删改查和主键生成,遇到在查询中使用多个查询条件的情况,使用前面的sql无法解决,运行程序出现错误。这一篇主要介绍一下mybatis查询sql的参数传递问题。
1.单个参数
创建对象类Employee
package org.mybatis.crud;
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email
+ ", gender=" + gender + "]";
}
}
创建方法接口
public interface EmployeeMapper {
//通过id获取对象
public Employee getEmployeeById(int id);
//通过id和lastName获取对象
public Employee getEmployeeByIdAndLastName(int id,String lastName);
}
创建mapper文件
<?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.mybatis.crud.EmployeeMapper">
<!-- 查询方法1,传递一个参数 -->
<select id="getEmployeeById" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={id}
</select>
</mapper>
创建主配置文件
<?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="db.properties"></properties>
<!-- 配置驼峰命名规则 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/crudmapper.xml"/>
</mappers>
</configuration>
创建测试类
package org.mybatis.crud;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
/**
* 使用接口式編程
* @author DDKK.COM 弟弟快看,程序员编程资料站
* SqlSessionFactory为非线程安全,所以不能够将SqlSessionFactory定义为成员变量
*/
public class MybatisTest {
public SqlSessionFactory getSqlSessionFactory() throws IOException{
String resource = "mybatis-config-crud.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
@Test
public void testMybatisSelect1() {
//测试查询
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
sqlSessionFactory = getSqlSessionFactory();
sqlSession = sqlSessionFactory.openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmployeeById(1);
System.out.println("--------------------------" + employee + "--------------------------");
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
}
单个参数,传递过程中不需要做特殊处理
直接使用#{参数名}:取出参数值
2.多个参数
如传递多个参数
public Employee getEmployeeByIdAndLastName(int id,String lastName);
如果使用如下配置
<!-- 查询方法2,传递多个参数 -->
<select id="getEmployeeByIdAndLastName" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={id} and last_name ={lastName}
</select>
@Test
public void testMybatisSelect2() {
//测试查询
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
sqlSessionFactory = getSqlSessionFactory();
sqlSession = sqlSessionFactory.openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//传递两个参数
Employee employee = mapper.getEmployeeByIdAndLastName(1, "zhangsan");
System.out.println("--------------------------" + employee + "--------------------------");
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
运行结果出现绑定错误,那么这种参数传递方式是有错误的
org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter ‘id’ not found. Available parameters are [0, 1, param1, param2]
The error may exist in mapper/crudmapper.xml
The error may involve defaultParameterMap
The error occurred while setting parameters
SQL: select * from mybatis_employee where id = ? and last_name = ?
Cause: org.apache.ibatis.binding.BindingException: Parameter ‘id’ not found. Available parameters are [0, 1, param1, param2]
错误里面显示使用param1,param2作为参数
<!-- 查询方法2,传递多个参数
多个参数会被封装成一个map
key:param1,param2...paramn或者参数的索引
value:传入的参数值
{}就是从map中获取指定key的值
-->
<select id="getEmployeeByIdAndLastName" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={param1} and last_name ={param2}
</select>
测试结果正确
————————–Employee [id=1, lastName=zhangsan, email=bestjinyi@163.com, gender=1]————————–
将param1和param2分别替换成下标0 1
<select id="getEmployeeByIdAndLastName" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={0} and last_name ={1}
</select>
也可以得到正确的结果。
3.命名参数
传递多个参数的时候,如果通过下标或者param1,param2,paramn这种形式,容易发生错位导致传递错误。mybatis提供了一个传递参数的注解@Param。将原来的接口方法做一下修改
public Employee getEmployeeByIdAndLastName(@Param("id")int id,@Param("lastName")String lastName);
<!--
查询方法2,传递多个参数使用@Param(参数名)
多个参数会被封装成一个map
key:@Param指定的值
value:为传递的参数
-->
<select id="getEmployeeByIdAndLastName" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={id} and last_name ={lastName}
</select>
继续测试,结果正常。
4.传递pojo参数
接口中添加方法
public Employee getEmployeeByEmployeeField(Employee employee);
mapper配置文件中添加
<select id="getEmployeeByEmployeeField" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={id} and last_name ={lastName}
</select>
测试方法使用
@Test
public void testMybatisSelect3() {
//测试查询
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
sqlSessionFactory = getSqlSessionFactory();
sqlSession = sqlSessionFactory.openSession();
Employee emp = new Employee();
emp.setId(1);
emp.setLastName("zhangsan");
Employee employee = mapper.getEmployeeByEmployeeField(emp);
System.out.println("--------------------------" + employee + "--------------------------");
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
5.map传递参数
新建接口方法
public Employee getEmployeeByMap(Map<String,Object> conditionsMap);
添加配置
<select id="getEmployeeByMap" resultType="org.mybatis.crud.Employee">
select * from mybatis_employee where id ={id} and last_name ={lastName}
</select>
新增测试方法
@Test
public void testMybatisSelect4() {
//测试查询
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
sqlSessionFactory = getSqlSessionFactory();
sqlSession = sqlSessionFactory.openSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Map<String,Object> conditionsMap = new HashMap<String,Object>();
conditionsMap.put("id", 1);
conditionsMap.put("lastName", "zhangsan");
Employee employee = mapper.getEmployeeByMap(conditionsMap);
System.out.println("--------------------------" + employee + "--------------------------");
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}