首页 > 代码库 > 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类型时,如果parameterType为Java基本类型,则使用Java Bean对象的属性来为SQL语句中的相应占位符赋值。这种方式由于parameterType是Java基本类型,同样有有且仅有一个占位符的限制。优点是属性的查找支持类似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类型,parameterType为Java 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