第一节博客是实例中数据库操作方法定义在了接口文件StudentMapper.java中,而这些操作的实现代码定义在了映射文件StudentMapper.xml中。这里把这个映射文件StudentMapper.xml称为SQL映射器。所以这一讲其实讲的就是如何在SQL映射器中实现数据库操作。第一节在StudentMapper.xml这个映射器中通过<insert>映射语句实现了数据库添加操作:
<mapper namespace="com.test.mappers.StudentMapper">
<insert id="add" parameterType="Student" >
insert into t_student values(null,#{name},#{age})
</insert>
</mapper>
<insert>的id值要和方法名对应。这里常用的映射语句主要有insert、update、delete、select四种。
这一节继续在第一节博客的实例上进行测试。为了方便测试,引入Junit测试。在com.test.service中新建Junit类(Junit引入方法查看之前博客):
1.新建测试方法testAdd():
package com.test.service;
import static org.junit.Assert.*;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.test.mappers.StudentMapper;
import com.test.model.Student;
import com.test.util.SqlSessionFactoryUtil;
public class StudentTest2 {
private static Logger logger = Logger.getLogger(StudentTest.class);
private SqlSession sqlSession = null;
private StudentMapper studentMapper = null;
@Before
public void setUp() throws Exception {
sqlSession = SqlSessionFactoryUtil.openSession();
studentMapper = sqlSession.getMapper(StudentMapper.class);
}
@After
public void tearDown() throws Exception {
sqlSession.close();
}
@Test
public void testAdd() {
logger.info("添加学生");
Student student = new Student("王五",15);
studentMapper.add(student);
sqlSession.commit();
}
}
在每次运行测试方法前,都会获取sqlSesson以及获取sql映射器。每次运行测试方法之后都会关闭SQLSession。
运行testAdd方法:
可以看到这里添加成功了。
2.修改StudentMapper接口:
package com.test.mappers;
import java.util.List;
import com.test.model.Student;
public interface StudentMapper {
public int add(Student student);
public int update(Student student);
public int delete(Integer id);
public Student findById(Integer id);
public List<Student> find();
}
这里添加了一个对数据的操作方法,分别是修改学生信息,删除学生信息,查找单个学生信息,查找所有学生信息。
在映射器StudentMapper.xml文件中实现这几个方法。
3.实现学生信息修改:
<update id="update" parameterType="Student">
update t_student set name=#{name},age=#{age} where id=#{id}
</update>
注意id属性的值要和StudentMapper接口中相应的方法名相同。
添加测试方法testUpdate()为:
@Test
public void testUpdate() {
logger.info("修改学生");
Student student = new Student(5,"王五2",18);
studentMapper.update(student);
sqlSession.commit();
}
运行这个测试方法:
学生信息修改成功。
4.添加实现删除功能的delete映射语句为:
<delete id="delete" parameterType="Integer">
delete from t_student where id=#{id}
</delete>
添加测试方法:
@Test
public void testDelete() {
logger.info("删除学生");
studentMapper.delete(5);
sqlSession.commit();
}
运行测试方法,可以看到数据库中相应的数据也被删掉了。
5.添加实现查找单个学生的select映射语句:
<select id="findById" parameterType="Integer" resultType="Student">
select * from t_student where id=#{id}
</select>
这里注意了findById()方法不仅传入参数,还有返回值。这里通过resultType属性定义返回值类型。
添加测试方法:
@Test
public void testFindById() {
logger.info("通过ID查找学生");
Student student = studentMapper.findById(1);
System.out.println(student);
}
查找学生不会改变数据库中数据值,所以这里可以不提交事务。当然提交事务也不会有问题。
运行测试方法:
可以看到,这里查询出来相应学生的信息。
6.实现所有学生信息的查询。这里难点来了,在find方法中要返回的是一个学生集合,这里就不能通过resultType="Student"来实现了。对于这种返回类型是集合的方法,在映射器中要先定义结果映射。修改后的映射器文件为:
<?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="com.test.mappers.StudentMapper">
<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>
<insert id="add" parameterType="Student">
insert into t_student values(null,#{name},#{age})
</insert>
<update id="update" parameterType="Student">
update t_student set name=#{name},age=#{age} where id=#{id}
</update>
<delete id="delete" parameterType="Integer">
delete from t_student where id=#{id}
</delete>
<select id="findById" parameterType="Integer" resultType="Student">
select * from t_student where id=#{id}
</select>
<select id="find" resultMap="StudentResult">
select * from t_student
</select>
</mapper>
在这里先通过<resultMap>标签定义返回的结果映射,这个标签中type属性的值代表这个映射中的结果类型,id属性的值是这个映射的名字。标签里面分别定义数据库中要返回的元素:
<id property="id" column="id"/>表示将查询结果的id列的值付给Student类的主键id,使用<id>标签定义主键的赋值。
<result property="name" column="name"/>表示将查询结果的name列的值付给Student类的name属性。
<result property="age" column="age"/>表示将查询结果的age列的值付给Student类的age属性。
由于查询结果有多条数据,从而也就得到了多条Student类的结果,把这些结果返回。
最后使用select映射语句实现获取所有学生的信息。这里使用resultMap属性表示要返回的集合类型。
添加测试方法:
@Test
public void testFind() {
logger.info("查找所有学生信息");
List<Student> studentList = studentMapper.find();
for(Student s:studentList){
System.out.println(s);
}
}
运行测试方法:
可以看到这里取到了所有学生的信息。