Mybatis与其它ORM框架的一个很大的不同之处就在于,Mybatis能够充分地使用SQL语句。
本篇博客来详细介绍在Mybatis中如何进行SQL映射。
映射配置文件和映射接口
假设使用了下面的方式来定义一个SQL映射
<?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="code.test.mybatis.mybatis_demo.StudentMapper">
<select id="findStudentById" parameterType="int"
resultType="blog.zdk.mybatis.mybatis_beginning_demo.Student">
SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB
FROM STUDENTS WHERE STUD_ID=#{Id}
</select>
</mapper>
然后通过这种方式来与数据库交互
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
Student student = sqlSession.selectOne("code.test.mybatis.mybatis_demo.StudentMapper.findStudentById", 1);
sqlSession.selectOne("code.test.mybatis.mybatis_demo.StudentMapper.findStudentById", 1)
这行代码是通过一个很长的字符串来调用的,我担心把字符串写错,mybatis是否支持通过强类型的方式来调用某个SQL代码?
强类型的调用方式可以很好地利用编译器的纠错功能。
我们新建一个与映射配置文件的namespace相同的接口,在接口中定义一个与SQL语句对应的id一样的方法名,参数签名和返回值类型也要一致,如下
package code.test.mybatis.mybatis_demo;
import java.util.List;
public interface StudentMapper {
Student findStudentById(Integer id);
}
然后,通过强类型的方式来调用
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
return studentMapper.findStudentById(1);
这种方式与通过长长的字符串来调用相比,是一种更好的编程体验。
定义SQL语句
我们在映射配置文件中可以通过<insert>
,<update>
,<delete>
,<select>
元素来分别定义插入、更新、删除、查询。
<?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="code.test.mybatis.mybatis_demo.StudentMapper">
<select id="findAllStudents" resultType="Student">
SELECT * FROM STUDENTS
</select>
<select id="findStudentById" parameterType="int"
resultType="Student">
SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB
FROM STUDENTS WHERE STUD_ID=#{Id}
</select>
<!-- 如果数据表的主键是自增长的,则需要指定useGeneratedKeys属性和keyProperty属性(Java对象的属性) -->
<insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="studId">
INSERT INTO STUDENTS(NAME,EMAIL,DOB)
VALUES(#{name},#{email},#{dob})
</insert>
<update id="updateStudent" parameterType="Student">
UPDATE STUDENTS SET NAME=#{name},EMAIL=#{email},DOB=#{dob}
WHERE STUD_ID=#{studId}
</update>
<delete id="deleteStudent" parameterType="int">
DELETE FROM STUDENTS WHERE STUD_ID=#{studId}
</delete>
</mapper>
定义映射接口
package code.test.mybatis.mybatis_demo;
import java.util.List;
import blog.zdk.mybatis.mybatis_beginning_demo.Student;
public interface StudentMapper {
public List<Student> findAllStudents();
public Student findStudentById(int id);
public int insertStudent(Student student) ;
public int deleteStudent(int id);
}
调用方法如下:
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
try {
//通过字符串调用,仅供参考
//Student student = sqlSession.selectOne("code.test.mybatis.mybatis_demo.StudentMapper.findStudentById", 1);
//获取映射接口对象
StudentMapper studentMapper=sqlSession.getMapper(StudentMapper.class);
//调用select语句
Student student=studentMapper.findStudentById(1);
System.out.println("name=" + student.getName());
System.out.println("email=" + student.getEmail());
System.out.println("birth=" + student.getDob());
//调用insert语句
Student newStudent=new Student();
newStudent.setName("kai");
newStudent.setEmail("kai@163.com");
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
String dateString="1994-01-01";
newStudent.setDob(dateFormat.parse(dateString));
int rows= studentMapper.insertStudent(newStudent);
sqlSession.commit();
System.out.println(rows);
System.out.println(newStudent.getStudId());
//调用delete语句
rows= studentMapper.deleteStudent(3);
System.out.println(rows);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
sqlSession.close();
}
注意:
- 如果在配置文件中定义的transactionManager的type=”JDBC”的话,除了select语句以外,其他的SQL语句最后需要调用
sqlSession.commit();
,否则数据将不会持久化。如果type=”MANAGED”,则无需调用commint()方法。 - 在定义SQL语句时,如果只有一个普通类型的参数,则这个参数的名字可以任意指定,例如:将
WHERE STUD_ID=#{Id}
修改为WHERE STUD_ID=#{XXX}
,结果不受影响。
SQL语句中包含’<’等特殊符号
如果sql中包含’<’等特殊符号,则执行该sql时会报错,此时需要稍作修改
<select id="findStudentByScore" parameterType="int"
resultType="Student">
<![CDATA[
SELECT STUD_ID AS STUDID, NAME, EMAIL, DOB
FROM STUDENTS WHERE STUD_ID < #{score}
]]>
</select>