Mybatis在接口上使用註解配置SQL語句以及接口與xml一起使用
阿新 • • 發佈:2018-04-01
Mybatis 持久層框架 在接口上使用註解配置SQL語句
MyBatis對於大部分的基於XML的映射器元素(包括<select>,<update>
)提供了對應的基於註解的配置項。然而在某些情況下,基於註解配置 還不能支持基於XML的一些元素。MyBatis提供了多種註解來支持不同類型的語句(statement)如SELECT,INSERT,UPDATE,DELETE。下面我們通過一個小demo來簡單演示一下這些基本註解的使用方式:
我現在有一張student表,表格結構如下:
首先編寫表格的字段封裝類,代碼如下:
package org.zero01.pojo; public class Student { private int sid; private String sname; private int age; private String sex; private String address; ... getter setter 略 ... }
然後需要寫一個接口,在該接口的方法上配置註解,註解的名稱基本都能自註釋了,我這裏就不贅述它們的作用了。代碼如下:
package org.zero01.mapper; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.zero01.pojo.Student; import java.util.List; public interface StudentMapper { @Insert("insert into student(sname,age,sex,address) values(#{sname},#{age},#{sex},#{address})") public int insertStu(Student student); @Delete("delete from student where sid=#{0}") public int delStu(int sid); @Select("select * from student where sid=#{0}") public Student selectById(int sid); @Select("select * from student") public List<Student> selectAll(); @Select("select * from student limit #{param1},#{param2}") public List<Student> selectByLimit(int startRow, int endRow); @Update("update student set sname=#{sname},age=#{age},sex=#{sex},address=#{address} where sid=#{sid}") public int updateStu(Student student); }
mybatis配置文件內容如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias type="org.zero01.pojo.Student" alias="Student"/> <typeAlias type="org.zero01.pojo.StudentLog" alias="StudentLog"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///school"/> <property name="username" value="root"/> <property name="password" value="your_password"/> </dataSource> </environment> </environments> <mappers> <!-- 通過包名引入接口 --> <mapper class="org.zero01.mapper.StudentMapper"/> </mappers> </configuration>
編寫一個測試類進行測試,代碼如下:
package org.zero01.test;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.zero01.student.Student;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestMyBatis {
private SqlSession sqlSession;
private StudentMapper studentMapper;
// 加載資源
@Before
public void testStart() throws IOException {
// 配置文件路徑
String confPath = "mybatis-config.xml";
// 讀取配置文件得到輸入流
InputStream inputStream = Resources.getResourceAsStream(confPath);
// 創建sql Session工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 建立與數據庫的會話
sqlSession = sqlSessionFactory.openSession();
// 得到的是一個動態代理類
studentMapper = sqlSession.getMapper(StudentMapper.class);
}
@Test
public void testInsertStu() {
Student student = new Student();
student.setSname("Milen");
student.setAge(20);
student.setSex("女");
student.setAddress("深圳");
int result = studentMapper.insertStu(student);
Assert.assertNotEquals(result, 0);
sqlSession.commit();
}
@Test
public void testDelStu() {
int result = studentMapper.delStu(23);
Assert.assertNotEquals(result, 0);
sqlSession.commit();
}
@Test
public void testSelectById() {
Student student = studentMapper.selectById(2);
Assert.assertNotNull(student);
JSONObject stuJSON = new JSONObject(student);
Assert.assertNotNull(stuJSON);
System.out.println(stuJSON);
}
@Test
public void testSelectAll() {
List<Student> students = studentMapper.selectAll();
Assert.assertNotEquals(students.size(), 0);
Assert.assertNotNull(students);
System.out.println("id\tsname\tage\tsex\taddress");
for (Student student : students) {
System.out.print(student.getSid() + "\t");
System.out.print(student.getSname() + "\t");
System.out.print(student.getAge() + "\t");
System.out.print(student.getSex() + "\t");
System.out.print(student.getAddress() + "\n");
}
}
@Test
public void testSelectByLimit() {
List<Student> students = studentMapper.selectByLimit(0, 5);
Assert.assertNotEquals(students.size(), 0);
Assert.assertNotNull(students);
System.out.println("id\tsname\tage\tsex\taddress");
for (Student student : students) {
System.out.print(student.getSid() + "\t");
System.out.print(student.getSname() + "\t");
System.out.print(student.getAge() + "\t");
System.out.print(student.getSex() + "\t");
System.out.print(student.getAddress() + "\n");
}
}
@Test
public void testUpdateStu() {
Student student = new Student();
student.setSid(7);
student.setSname("Mkans");
student.setAge(23);
student.setSex("男");
student.setAddress("湖南");
int result = studentMapper.updateStu(student);
Assert.assertNotEquals(result, 0);
sqlSession.commit();
}
// 關閉資源
@After
public void testEnd() {
if (sqlSession != null) {
// 結束與數據庫的會話
sqlSession.close();
}
}
}
結果映射
除了基本的sql語句的配置外,我們還可以通過註解配置結果映射,如下示例:
@Select("select * from student")
@Results({
@Result(id = true, property = "sid",column = "sid"),
@Result(property = "sname",column = "sname"),
@Result(property = "age",column = "age"),
@Result(property = "sex",column = "sex"),
@Result(property = "address",column = "address")
})
public List<Student> selectAll();
註:@Results註解與XML配置文件中的<resultMap>
標簽相對應。
我們在XML配置文件中可以配置一對多的連接查詢,但是需要通過標簽設置結果集與字段的映射關系。在註解裏我們沒法這麽做,因為沒有對應的註解支持。但是我們可以先在XML配置好映射關系,然後通過@ResultMap註解來引用它。如下示例:
<?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="org.zero01.mapper.StudentMapper">
<resultMap id="stuMap" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<association property="studentLog" resultMap="stuLogMap"/>
</resultMap>
<resultMap id="stuLogMap" type="StudentLog">
<id property="log_id" column="log_id"/>
<result property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<result property="operation_type" column="operation_type"/>
<result property="log_time" column="log_time"/>
</resultMap>
</mapper>
註解配置內容如下:
@Select("select * from student stu inner join studentlog stulog on stu.`sid`=stulog.`sid`")
@ResultMap("org.zero01.mapper.StudentMapper.stuMap") // 引用XML裏配置的映射器
public List<Student> selectInnerLog();
接口與xml一起使用
通常情況下我們都是將接口與XML配置文件混合使用,這樣比純XML或者純註解的方式要簡單一些。
將接口代碼的註解刪除,修改如下:
package org.zero01.mapper;
import org.zero01.pojo.Student;
import java.util.List;
public interface StudentMapper {
public int insertStu(Student student);
public int delStu(int sid);
public Student selectById(int sid);
public List<Student> selectAll();
public List<Student> selectByLimit(int startRow, int endRow);
public int updateStu(Student student);
public List<Student> selectInnerLog();
}
然後在mybatis配置文件中,加入如下內容:
<mappers>
<mapper class="org.zero01.mapper.StudentMapper"/>
<mapper resource="org/zero01/mapper/StudentMapper.xml"/>
</mappers>
新增的StudentMapper.xml文件內容如下:
<?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="org.zero01.mapper.StudentMapper">
<resultMap id="stuMap" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<association property="studentLog" resultMap="stuLogMap"/>
</resultMap>
<resultMap id="stuLogMap" type="StudentLog">
<id property="log_id" column="log_id"/>
<result property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<result property="operation_type" column="operation_type"/>
<result property="log_time" column="log_time"/>
</resultMap>
<select id="selectInnerLog" resultMap="stuMap">
select * from student stu inner join studentlog stulog on stu.`sid`=stulog.`sid`
</select>
<insert id="insertStu" parameterType="Student">
insert into student(sname,age,sex,address) values(#{sname},#{age},#{sex},#{address})
</insert>
<delete id="delStu" parameterType="int">
delete from student where sid=#{0}
</delete>
<select id="selectById" parameterType="int" resultType="Student">
select * from student where sid=#{0}
</select>
<select id="selectAll" resultType="Student">
select * from student
</select>
<update id="updateStu" parameterType="Student">
update student set sname=#{sname},age=#{age},sex=#{sex},address=#{address} where sid=#{sid}
</update>
</mapper>
註:標簽id屬性的值需要與接口方法的名稱相對應。
Mybatis在接口上使用註解配置SQL語句以及接口與xml一起使用