首页 > 代码库 > MyBatis应用开发(9)映射之参数绑定parameterType

MyBatis应用开发(9)映射之参数绑定parameterType

 

1.1. parameterType

parameterType表示SQL语句中存在占位符,对应于Mapper接口中对应方法的参数。

SQL语句中只有一个占位符时,parameterType可以是Java基本类型,也可以是Java Bean类型。当存在多个占位符时,parameterType只能是Java Bean类型。

当为Java基本类型时,可以写类型的全限定名,也可以是MyBatis提供的简化的别名。

别名int表示java.lang.Integer

别名string表示java.lang.String

 

1.1.1. Java基本类型=>Java基本类型

Mapper接口方法只有一个参数,为Java基本类型时,如果parameterType也为Java基本类型,则对参数名称和占位符名称没有特殊要求。这种方式的限制条件是SQL语句中的占位符有且只有一个。

/**

 * 根据ID查找单个记录。

 * *@param  id

 */

Person  findPersonById(String id) throws Exception;

 

 

此时占位符的名称没有特别的要求,可以是任何有意义的字符串,并不要求占位符的字符串和Mapper接口对应的方法的参数的名称一致。

以下两种定义是等效的。

 <select id="findPersonById" parameterType="java.lang.String" resultType="com.test.mybatis3.pojo.Person">  

    select * from  t_person where id=#{id}

</select>

 

 <select id="findPersonById" parameterType="java.lang.String" resultType="com.test.mybatis3.pojo.Person">  

    select * from  t_person where id=#{somestring}

</select>

 

 

1.1.2. Java Bean类型=>Java基本类型

Mapper接口方法只有一个参数,而且是Java Bean类型时,如果parameterTypeJava基本类型,则使用Java Bean对象的属性来为SQL语句中的相应占位符赋值。这种方式由于parameterTypeJava基本类型,同样有有且仅有一个占位符的限制。优点是属性的查找支持类似OGNL语法,可以嵌套查找。

通过类似#{XXX}的方式来查找Java Bean对象中的相应属性XXX,或者通过#{XXX.YYY}的方式来查找Java Bean对象的XXX属性(是一个对象)YYY属性。

 

<select id="findPersonByIdOfCriteria" parameterType="java.lang.String" resultType="com.test.mybatis3.pojo.Person">  

    select * from  t_person where id=#{person.id}

</select>

 

 

 

PersonMapper接口的findPersonByIdOfCriteria方法的定义如下:

 

/**

 * 根据ID查找单个记录。

 * *@param  criteria,使用Criteria的person子对象的id属性。

 */

Person  findPersonByIdOfCriteria(Criteria  criteria) throws Exception;

 

 

 

 

查询条件Criteria类是这么定义的:

/**   

* @Title: Criteria.java

* @Package com.test.mybatis3.pojo

* @Description:

* @author http://www.cnblogs.com/coe2coe/

* @date 2017年4月14日 下午9:19:16

* @version V1.0   

*/

package com.test.mybatis3.pojo;

 

/**

* @ClassName: Criteria

* @Description: 查询条件

* @author http://www.cnblogs.com/coe2coe/

* @date 2017年4月14日 下午9:19:16

*  

*/

public class Criteria {

 

public Criteria()

{

this.person = new Person();

}

 

/**

 * 以Person的id作为查询条件。

 */

private Person  person;

 

public Person getPerson() {

return person;

}

 

public void setPerson(Person person) {

this.person = person;

}

}

 

 

单元测试代码如下:

@Test

public void testFindPersonByCriteria() throws Exception

{

 

//使用SqlMapConfig.xml配置文件。

InputStream  is = Resources.getResourceAsStream("SqlMapConfig.xml");

 

//构造MyBatis的SessionFactory对象.

SqlSessionFactory  sessionBuilder = new SqlSessionFactoryBuilder().build(is);

 

//将会指向MyBatis的Session对象实例。

SqlSession  session = null;

try{

//打开Session。

session = sessionBuilder.openSession();

 

//找到MyBatis自动实现的PersonMapper接口的代理对象。

PersonMapper  personMapper = session.getMapper(PersonMapper.class);

 

Person  person;

 

//根据查询条件查找。

Criteria  criteria = new Criteria();

criteria.getPerson().setId("zhangsan");

person = personMapper.findPersonByIdOfCriteria(criteria);

System.out.println(person);

 

 

}

catch(Exception ex){

ex.printStackTrace();

throw ex;

}

finally{

//确保关闭session对象。

if(null != session){

session.close();

session = null;

}
}
}

 

 

 

 

运行结果如下:

0    [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByIdOfCriteria  - ==>  Preparing: select * from t_person where id=?

67   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByIdOfCriteria  - ==> Parameters: zhangsan(String)

195  [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByIdOfCriteria  - <==    Columns: id, name, status

196  [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByIdOfCriteria  - <==        Row: zhangsan, zhang san, 0

212  [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByIdOfCriteria  - <==      Total: 1

Person [id=zhangsan, name=zhang san, status=0]

 

1.1.3. Java Bean类型=>Java Bean类型

如果Mapper接口方法的参数为Java Bean类型,parameterTypeJava Bean类型,则SQL语句可以支持多个占位符,同时支持类似OGNL的嵌套属性查找的占位符匹配方式。

<!-- parameterType为Java Bean类型,支持多个占位符,支持OGNL语法 -->

<select id="findPersonByJavaBean" parameterType="com.test.mybatis3.pojo.Criteria" resultType="com.test.mybatis3.pojo.Person">  

    select * from  t_person where id=#{person.id} and status=#{person.status}

</select>

 

PersonMapper接口的方法定义如下:

 

/**

 * 根据ID和status查找单个记录。

 * @param criteria

 * @return

 * @throws Exception

 */

Person  findPersonByJavaBean(Criteria criteria) throws Exception;

 

 

 

单元测试代码如下:

@Test

public void testFindPersonByCriteria() throws Exception

{

 

//使用SqlMapConfig.xml配置文件。

InputStream  is = Resources.getResourceAsStream("SqlMapConfig.xml");

 

//构造MyBatis的SessionFactory对象.

SqlSessionFactory  sessionBuilder = new SqlSessionFactoryBuilder().build(is);

 

//将会指向MyBatis的Session对象实例。

SqlSession  session = null;

try{

//打开Session。

session = sessionBuilder.openSession();

 

//找到MyBatis自动实现的PersonMapper接口的代理对象。

PersonMapper  personMapper = session.getMapper(PersonMapper.class);

 

Person  person;

 

//根据查询条件查找。

Criteria  criteria = new Criteria();

criteria.getPerson().setId("zhangsan");

//注意调用的方法名变化了。

person = personMapper.findPersonByJavaBean(criteria);

System.out.println(person);

 

}

catch(Exception ex){

ex.printStackTrace();

throw ex;

}

finally{

//确保关闭session对象。

if(null != session){

session.close();

session = null;

}

}

}

 

 

运行结果如下:

0    [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByJavaBean  - ==>  Preparing: select * from t_person where id=? and status=?

53   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByJavaBean  - ==> Parameters: zhangsan(String), 0(Integer)

100  [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByJavaBean  - <==    Columns: id, name, status

100  [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByJavaBean  - <==        Row: zhangsan, zhang san, 0

102  [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByJavaBean  - <==      Total: 1

Person [id=zhangsan, name=zhang san, status=0]

 

 

 

1.1.4. 字符串替换${}

MyBatis还支持通过${XXX}表达式来实现SQL语句中某部分内容替换为XXX指定的字符串。

${XXX}#{XXX}的区别在于#{XXX}产生的SQL语句会含有占位符?,而${XXX}不会形成占位符,而是先将${XXX}替换为XXX所表达的实际字符串后,再进行类似prepareStatement()的调用。

#{XXX}的值是通过类似setInteger(),setString()等调用进行占位符的赋值的,可以有效解决SQL注入攻击的问题,而${XXX}之中方式则跟通过字符串拼接产生SQL语句一样存在SQL注入攻击问题。

<!-- parameterType为Java Bean类型,${XXX}表示 字符串替换-->

<select id="findPersonByName" parameterType="com.test.mybatis3.pojo.Criteria" resultType="com.test.mybatis3.pojo.Person">  

    select * from  t_person where name like ‘%${person.name}%‘

</select>

 

 

 

 

PersonMapper接口的对应方法定义如下:

/**

 * 根据name模糊查找多个记录。

 * *@param  criteria,使用Criteria的person子对象的id属性。

 */

List<Person>  findPersonByName(Criteria  criteria) throws Exception;

 

 

 

 

单元测试代码如下:

//找到MyBatis自动实现的PersonMapper接口的代理对象。

PersonMapper  personMapper = session.getMapper(PersonMapper.class);

 

//根据查询条件查找。

Criteria  criteria = new Criteria();

criteria.getPerson().setName("zhang");

List<Person> persons = personMapper.findPersonByName(criteria);

System.out.println(persons);

 

 

运行结果如下:

0    [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByName  - ==>  Preparing: select * from t_person where name like ‘%zhang%‘

41   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByName  - ==> Parameters:

93   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByName  - <==    Columns: id, name, status

93   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByName  - <==        Row: zhangsan, zhang san, 0

95   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByName  - <==      Total: 1

[Person [id=zhangsan, name=zhang san, status=0]]

 

MyBatis应用开发(9)映射之参数绑定parameterType