文章目录
三、MyBatis框架动态代理及其参数的传入
3.1 动态代理
动态代理其实前面就已经用过了,就是直接使用SqlSession对象的getMapper(Dao接口.class)方法获取dao接口对象。
然后使用直接用这个dao的方法来调用我们对应的xml中操作数据库的语句。
因此这里就不多做介绍了。这里主要说一下xml文件对参数的传入和返回。
3.2 parameterType属性
parameterType属性常用于告诉mybatis,该sql语句传入的是什么类型的参数。他的值是java的数据类型全限定名称或者是mybatis定义的别名。
例如:parameterType="java.lang.Integer"或者parameterType=“integer”
官方给出的ParameterType属性能够接收的类型和别名如下:
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
不过,parameterType属性并没有强制我们一定要写,mybatis通过反射机制其实能够发现接口参数的类型,因此,实际开发中,一般也可以选择不写。
3.3 传入一个简单类型的参数
简单类型指代java的基本数据类型和String类型。在mapper文件中,获取简单类型的参数值,只需要使用 #{任意字符} 进行提取即可。
案例:通过id查找指定对象。
首先,在我们的dao中添加查询的接口如下:
public Student findOneById(Integer id);
然后在xml文件中定义他的sql实现:
<select id="findOneById" resultType="com.example.po.Student" parameterType="int">
select id,name,email,age from Student
where id = #{id}
</select>
然后在Impl类中进行实现:
@Override
public Student findOneById(Integer id) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.findOneById(id);
session.close();
return student;
}
最后在测试类进行测试:
@Test
public void testFindOne(){
StudentDao dao = new StudentDaoImpl();
Student student = dao.findOneById(1001);
System.out.println(student);
}
执行结果如下:
注意:即使我们把ParameterType给删掉,程序依然可以运行。
3.4 传入多个参数
3.4.1 使用@Param命名参数(掌握)
对于传入多个参数的情况,mybatis建议我们使用@Param命名参数的形式。
用法:
在方法的形参中使用 @Param(“参数名”) 类型 形参名 (例如:@Param(“stuName”) String name)
在mapper中使用
<select id="findStudentsByNameOrAge" resultType="com.example.po.Student">
select id,name,email,age from Student
where name = #{stuName} or age = #{stuAge}
</select>
案例:通过name和age查找对象。
首先,我们在dao接口中添加我们的接口:
public List<Student> findStudentsByNameOrAge(@Param("stuName") String name,
@Param("stuAge") Integer age);
然后我们为我们的接口写我们的mapper:
<select id="findStudentsByNameOrAge" resultType="com.example.po.Student">
select id,name,email,age from Student
where name = #{stuName} or age = #{stuAge}
</select>
再写一个impl方法:
@Override
public List<Student> findStudentsByNameOrAge(String name, Integer age) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> studentList = dao.findStudentsByNameOrAge(name, age);
session.close();
return studentList;
}
最后进行测试:
@Override
public List<Student> findStudentsByNameOrAge(String name, Integer age) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> studentList = dao.findStudentsByNameOrAge(name, age);
session.close();
return studentList;
}
结果:
3.4.2 使用对象参数(掌握)
这个其实也很简单,我们可以自己新建一个类,然后这个类有你的mapper所需要的参数(比如新建一个MyParam类,然后这个类有name和age变量),或者我们直接使用我们的原来的类(Student)。
案例:通过这个类的部分属性查找指定对象
先写接口:
public List<Student> findStudentsByObject(Student student);
在mapper中实现:
<select id="findStudentsByObject" resultType="com.example.po.Student">
select id,name,email,age from Student
where name = #{name} or age = #{age}
</select>
在Impl中实现具体操作:
@Override
public List<Student> findStudentsByObject(Student student) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> studentList = dao.findStudentsByObject(student);
session.close();
return studentList;
}
测试:
@Test
public void testFindStudentsByObject(){
StudentDao dao = new StudentDaoImpl();
Student student = new Student();
student.setName("张三");
student.setAge(23);
List<Student> studentList = dao.findStudentsByObject(student);
for (Student item : studentList){
System.out.println(item);
}
}
运行结果:
3.4.3 按位置传参(了解)
直接给代码吧:
先写接口:
public List<Student> findStudentsByPosition(String name, Integer age);
然后写mapper实现:
注意:如果是mybatis3.4之前的版本则用#{0}、#{1} 获取1、2个参数
<select id="findStudentsByPosition" resultType="com.example.po.Student">
select id,name,email,age from Student
where name = #{arg0} or age = #{arg1}
</select>
再写Impl实现:
@Override
public List<Student> findStudentsByPosition(String name, Integer age) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> studentList = dao.findStudentsByPosition(name,age);
session.close();
return studentList;
}
最后写测试方法:
@Test
public void testFindStudentsByPosition(){
StudentDao dao = new StudentDaoImpl();
Student student = new Student();
List<Student> studentList = dao.findStudentsByPosition("王五",18);
for (Student item : studentList){
System.out.println(item);
}
}
执行结果:
3.4.4 Map传参(了解)
其实就是通过Map的键值对分别设置用于MyBatis提取的键(用#{key}获取)和传入的值。
多说无益,直接看代码吧。
先写接口:
public List<Student> findStudentsByMap(Map map);
mapper实现:
这里的stuName和stuAge其实就是通过map的键来拿他对应的值
<select id="findStudentsByMap" resultType="com.example.po.Student">
select id,name,email,age from Student
where name = #{stuName} or age = #{stuAge}
</select>
然后写Impl:
@Override
public List<Student> findStudentsByMap(Map map) {
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
List<Student> studentList = dao.findStudentsByMap(map);
session.close();
return studentList;
}
最后写测试类:
@Test
public void testFindStudentsByMap(){
StudentDao dao = new StudentDaoImpl();
Student student = new Student();
Map map = new HashMap<String,Object>();
map.put("stuName","王五");
map.put("stuAge",18);
List<Student> studentList = dao.findStudentsByMap(map);
for (Student item : studentList){
System.out.println(item);
}
}
执行结果: