Trong bài trước, chúng ta đã biết cách cấu hình MyBatis bằng cách sử dụng file XML. Trong bài này, chúng ta sẽ học về cách cấu hình và tạo câu lệnh SQL trong file mapper XML.
Mapper XML là một file quan trọng trong MyBatis, chứa một tập hợp các câu lệnh để cấu hình các câu lệnh SQL khác nhau như select, insert, update, delete. Các câu lệnh này được gọi là Mapped Statements hoặc Mapped SQL Statements
Cấu trúc file mapper 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 = "alias/interface"> //mapped statements và result maps <mapper>
Nội dung chính
Các thẻ con của thẻ <mapper>
Dưới đây là các thẻ con của thẻ <mapper>.
- insert – Định nghĩa một câu lệnh INSERT.
- update – Định nghĩa một câu lệnh UPDATE.
- delete – Định nghĩa một câu lệnh DELETE.
- select – Định nghĩa một câu lệnh SELECT.
- cache – Cấu hình cache cho một namespace đã cho.
- cache-ref – Tham chiếu tới một cấu hình cache từ một namespace khác.
- resultMap – Đây là một thẻ mạnh mẽ trong MyBatis mô tả làm thế nào để tải dữ liệu cho đối tượng java từ các tập kết quả trả về của cơ sở dữ liệu.
- sql – Định nghĩa câu SQL để tái sử dụng cho các cậu lệnh khác.
Mapped SQL Statements
Mapped SQL Statements có nghĩa là các câu lệnh SQL được ánh xạ.
- Mỗi câu lệnh có id duy nhât, để thực thi bất kỳ câu lệnh nào bạn phải tuyền id tương ứng tới phương thức trong ứng dụng Java.
- File mapper XML được sử dụng nhằm giảm thiểu việc phải viết câu lệnh SQL lặp lại nhiều lần. So với JDBC, khoảng 95% code được giảm bằng cách sử dụng tệp Mapper XML trong MyBatis.
- Tất cả các câu lệnh SQL được đặt trong thẻ <mapper>, thẻ này có một thuộc tính được gọi là ‘namespace’.
Cách dùng Mapped SQL Statements
Dưới đây là cách cấu hình các câu lệnh SQL khác nhau như select, insert, update, delete, resultMap. Và ví dụ về sử dụng chúng.
Giả sử bảng có tên details.Student tồn tại trong MySQL database có dạng như sau:
+----+-------+--------+------------+-----------+---------------+ | ID | NAME | BRANCH | PERCENTAGE | PHONE | EMAIL | +----+-------+--------+------------+-----------+---------------+ | 1 | Shyam | it | 80 | 954788457 | mail@mail.com | +----+-------+--------+------------+-----------+---------------+
Giả sử tồn tại một lớp POJO có tên Student nằm trong package mybatis.entity tương ứng với bảng trên.
public class Student { private int id; private String name; private String branch; private int percentage; private int phone; private String email; //Setters and getters }
Các câu lệnh SQL trong các ví dụ dưới đây đặc đặt trong thẻ <mapper>.
<mapper namespace = "Student"> //mapped statements và result maps <mapper>
Câu lệnh insert
Trong MyBatis, để insert giá trị vào bảng, chúng ta phải cấu hình truy vấn insert. MyBatis cung cấp các thuộc tính khác nhau cho thẻ insert, nhưng phần lớn chúng ta sử dụng id và parameterType.
id là duy nhất được sử dụng để xác định câu lẹnh insert. parametertype là tên lớp hoặc alias của tham số mà được truyền vào trong câu lệnh.
Ví dụ:
<insert id = "insertStudent" parameterType = "Student"> INSERT INTO STUDENT1 (NAME, BRANCH, PERCENTAGE, PHONE, EMAIL ) VALUES (#{name}, #{branch}, #{percentage}, #{phone}, #{email}); </insert>
Bạn có thể gọi câu truy vấn 'insert' ở trên bằng việc sử dụng Java API.
//giả sử session là một đối tượng SqlSession. session.insert("Student.insertStudent", student); session.commit();
Câu lệnh update
Trong MyBatis, để update giá trị vào record đã tồn tại trong bảng, chúng ta phải cấu hình truy vấn update bằng việc sử dụng thẻ update. Các thuộc tính của thẻ update tương tự thẻ insert.
Ví dụ:
<update id = "updateStudent" parameterType = "Student"> UPDATE STUDENT SET EMAIL = #{email}, NAME = #{name}, BRANCH = #{branch}, PERCENTAGE = #{percentage}, PHONE = #{phone} WHERE ID = #{id}; </update>
Bạn có thể gọi câu truy vấn 'update' ở trên bằng việc sử dụng Java API.
//giả sử session là một đối tượng SqlSession. session.insert("Student.updateStudent", student); session.commit();
Câu lệnh delete
Trong MyBatis, để delete record tồn tại trong bảng, chúng ta phải cấu hình truy vấn delete bằng việc sử dụng thẻ delete. Các thuộc tính của thẻ delete tương tự thẻ insert.
Ví dụ:
<delete id = "deleteStudentById" parameterType = "int"> DELETE from STUDENT WHERE ID = #{id}; </delete>
Bạn có thể gọi câu truy vấn 'delete' ở trên bằng việc sử dụng Java API.
//giả sử session là một đối tượng SqlSession. session.delete("Student.deleteStudentById", 18); session.commit();
Câu lệnh select
Để lấy data từ database, chúng ta phải dùng thẻ select để cấu hình câu truy vấn select.
Ví dụ:
<select id = "getAll" resultMap = "result"> SELECT * FROM STUDENT; </select>
Bạn có thể sử dụng phương thức selectList() để thực thi câu lệnh select và lấy kết quả trả về.
List<Student> list = session.selectList("Student.getAll");
Trong ví dụ trên có sử dụng thuộc tính resultMap = "result". Vậy, resultMap là gì?
resultMap
Thẻ resultMap là thẻ quan trọng và mạnh mẽ nhất. Thẻ resultMap được sử dụng để ánh xạ tên cột trong tập dữ liệu trả về từ câu lệnh SELECT với tên trường của đối tượng Java (Beans/POJO).
Ví dụ:
<resultMap id = "result" type = "Student"> <result property = "id" column = "ID"/> <result property = "name" column = "NAME"/> <result property = "branch" column = "BRANCH"/> <result property = "percentage" column = "PERCENTAGE"/> <result property = "phone" column = "PHONE"/> <result property = "email" column = "EMAIL"/> </resultMap> <select id = "getAll" resultMap = "result"> SELECT * FROM STUDENT; </select> <select id = "getById" parameterType = "int" resultMap = "result"> SELECT * FROM STUDENT WHERE ID = #{id}; </select>
Không bắt buộc phải ghi thuộc tính 'column' của resultMap nếu cả hai property và tên 'column' của bảng giống nhau.
Khi các tên cột trong tập dữ liệu trả về từ database trùng với tên trường của đối tượng java (không phân biệt chữ hoa, chữ thường) thì không nhất thiết phải sử dụng resultMap. Bởi vì, MyBatis có cơ chế tự động map chúng với nhau.
Câu hỏi: Có cần thiết phải sử dụng resultMap để ánh xạ dữ liệu trả về của câu lệnh SELECT vào đối tượng Java (Beans/POJO)?
TH: Khi các tên cột trong tập dữ liệu trả về từ database trùng với tên trường của đối tượng java thì không cần phải sử dụng resultMap.
Chẳng hạn trong ví dụ về câu lệnh select trên có thể khai báo như sau. Không cần sử dụng resultMap vì các tên cột trong database trùng với các tên trường của đối tượng java.
<select id = "getAll" resultType = "Student"> SELECT * FROM STUDENT; </select>