Dùng Mybatis nhúng Raw SQL trong Spring Boot

Tram Ho

Xin chào các bạn

Gần đây mình có dùng một framework là Mybatis để nhúng lệnh SQL vào xử lý cũng như tạo query dạng động để chạy chương trình trong (Java) Spring Boot, mình xin chia sẻ lại kinh nghiệm học Mybatis qua bài này.

Với mục đích là thử nghiệm Mybatis nên bài toán sẽ hướng sao cho ta đi qua được hết các tính năng cơ bản của Mybatis chứ không liên quan đến một bài toán thực tế nào. Một số tính năng mình mong muốn dùng qua như sau :

  • Viết RawSQL để xử lý java gọi đến và lấy kết quả được
  • Viết dạng SQL Builder để xử lý java gọi đến và lấy kết quả được
  • Viết SQL cho các cú pháp cơ bản : SELECT, INSERT, UPDATE, DELETE
  • Bài toán là viết chương trình lưu dữ liệu user và items.

Vậy mình xin bắt đầu.

0.Môi trường

Môi trường máy mình khi thực hiện như sau :

  • OS : MacOS
  • IDE : SpringToolSuite4 (Eclipse)

1.Cài đặt

1.1. Khởi tạo project

Ta dùng Spring Initializr để khởi tạo, rất thuận tiện.
https://start.spring.io/

Các lựa chọn như sau

MụcLựa chọn
ProjectMaven Project
LanguageJava
Project MetadataNhư hình
DependenciesMybatis, H2

Ta sẽ dùng Mybatis nên sẽ chọn một dependence là Mybatis.

Về database thì mình chọn Mysql vì mình quen thao tác với DB này.

Chọn Generate ta được file zip, giải nén và import vào IDE ta được cấu trúc như sau

Trong đó chú ý một thông số là mybatis ta sử dụng có phiên bản là 2.1.3 và đây là phiên bản thiết kế riêng dùng với Spring Boot chứ không phải phiên bản phổ biến (Hiện nay là 3.5.5)

Ta cũng tạo 2 package sẵn để lưu các class mybatis sau này sẽ cần dùng :

  • src/main/java/com/demo/mybatis/mapper
  • src/main/java/com/demo/mybatis/model

1.2. Cấu trúc database

Ta sẽ cần một database sẵn sàng sử dụng để các query gọi đến và thực hiện được. Ta sẽ cấu trúc database như sau :

Tạo DB mysql với docker

docker-compose.yml

Ta dựng một database với thông tin user, password, port như ở trên. Khởi động bằng
docker-compose up -d

Cấu trúc bảng

(Truy cập vào dòng lệnh database với mysql -h 0.0.0.0 -P 33061 -u demo demo -p)

Ở bài này mình thử nghiệm với 1 bảng cơ bản user với các thuộc tính của người dùng là tên (name) và ngày sinh (birthday). Sau đó là bảng items chứa foreign key đến bảng users để thử nghiệm tính năng relationship trong mybatis.

1.3. Cài đặt plugin Mybatis Generator

1.3.1. Tải từ Marketplace

Ta có thể lựa chọn tự viết các class cần thiết nhưng cũng có lựa chọn khác là dùng Mybatis Generator, đây là một tool rất hữu ích cho việc khởi tạo các class cần thiết dùng của Mybatis.

Trang chủ : http://mybatis.org/generator/

Mybatis Generator có khả năng tự tra cứu các table được chỉ định và generate các class liên quan đến database đó, nhờ đó giảm công sức implement đi rất nhiều.

Bạn có thể tải với dòng lệnh, ở bài viết này mình tải dưới dạng plugin của eclipse như sau: tra cứu từ Eclipse Marketplace (Help –> Eclipse Marketplace) với từ khoá Mybatis, chọn tải Mybatis Generator 1.4.0

Sau khi tải xong, ta tạo file generatorConfig.xml chỉ định các thiết lập cần thiết cho Generator. Mình tạo với nội dung như sau :

src/main/resources/generatorConfig.xml

Trong đó :

  • connectionURL : url chứa thông tin kết nối đến database
  • userId : tên user cho database
  • password : password cho user trên
  • javaModelGenerator : chỉ định generate các class Model (User, Item)
  • javaClientGenerator : chỉ định generate các class Mapper và Support
  • table : chỉ định các table cần generate

1.3.2.Tạo Generator (Run Configuration)

Run –> Run Configuration –> Mybatis Generator (New)

ở đây ta chỉ định Configuration File đến file config vừa rồi ở 1.3.1 là được.

2.Viết chương trình

2.1.Run Generator

Thử Run với cấu hình ở trên, ta nhận được log ở Console như sau :

Sau khi chạy xong, ta nhận được các class sau được generate :

Mybatis Generator tạo cho ta 3 lớp cơ bản sau :

  • Các Model : là class mô hình hoá kết quả cũng như tham số của các câu lệnh SQL, thường tương đương với một bảng trong database
  • Các Mapper : là class có vai trò lưu các query mà ta dùng truy vấn đến cơ sở dữ liệu
  • Các Support : hỗ trợ viết xử lý với Mapper qua cung cấp các biến thể hiện ứng với cấu trúc bảng

Ta sẽ xem qua nội dung các file này :

2.1.1.Các Model (Users và Items)

src/main/java/com/demo/mybatis/model/Users.java

Ta có thể thấy là Mybatis Generator đã generate đầy đủ các field mà table users chứa (id, name, birthday) và ánh xạ chúng với kiểu dữ liệu trong java gần nhất (Integer, Date, String)

Mỗi field được gắn annotation đánh dấu mốc chúng được generate thế nào.

2.1.2. Mapper

Mybatis generate cho ta tầm hơn 2 chục hàm tiện ích, ta sẽ điểm qua một số hàm ban đầu

  • selectList : chứa danh sách các field ứng với model tương ứng.
  • long count() : hàm đếm danh sách dựa trên lệnh select cho vào tham số. Sau ta có thể đếm số record thoả mãn điều kiện với gọi lệnh ItemsMapper.count(…)
  • int delete() : hàm xoá record dựa trên điều kiện được cho vào tham số
  • int insert() : tương tự 2 hàm trên với lệnh insert

2.1.3. Support

Bên trong mỗi class Support chứa một class con thể hiện cho table mà đó trỏ đến (Users), class con này chứa các thuộc tính ứng với các field của table mà nó trỏ đến.

Class Support cha (UsersDynamicSqlSupport) chứa một thể hiện của class con đó, và mỗi thuộc tính khác chính là tham chiếu đến thuộc tính của thể hiện này.

Ta sẽ thực sự sử dụng các thuộc tính trên ở phần sau.

2.2.Viết xử lý thử dùng mybatis

2.2.1.Viết custom Model và Mapper cho relationship giữa Items và Users

Đoạn này có thể hơi nâng cao một chút, ở trên mình đã dùng Mybatis Generator để generate các model và mapper ứng với từng bảng trong database.

Tuy nhiên mình muốn dùng mapper dạng sử dụng được relationship giữa các bảng, yêu cầu phải join, tính năng này thì Mybatis Generator vẫn chưa hỗ trợ tạo được class và mapper phù hợp.

https://mybatis.org/mybatis-dynamic-sql/docs/select.html

Do đó nên mình tự tạo mới

2.2.1.1.ItemsUsers (Model)

src/main/java/com/demo/mybatis/model/ItemsUsers

Đây là 4 thuộc tính mà mình muốn lấy ra sau khi join 2 bảng với nhau.

2.2.1.2.ItemsUsersMapper.java

Tương tự ta sẽ tạo Mapper chứa hàm gọi đến xử lý relationship giữa 2 bảng.
src/main/java/com/demo/mybatis/mapper/ItemsUsersMapper

2.2.1.3.ItemsUsersMapper.xml

src/main/java/com/demo/mybatis/mapper/ItemsUsersMapper.xml

Ở đây ta đã tạo một query thuần có chứa lệnh join. Spring có thể tự phát hiện và gắn xml này với mapper java tương ứng của nó.

Chú ý là ta ở query ta cần khai báo id đúng với tên hàm trong mapper java và kiểu trả về phù hợp.

(Mặc dù kiểu trả về là List nhưng mybatis vẫn chấp nhận khai báo resultType không phải rõ ràng kiểu List mà là kiểu phần tử)

2.2.2.Tạo playground

Playground ý mình ở đây là class sử dụng chuyên để thử nghiệm, dùng thử các xử lý mới dùng lần đầu. Ta sẽ viết các xử lý cơ bản với model trên playground này.

src/main/java/com/demo/mybatis/MybatisPlayground.java

ta để tham số truyền vào khởi tạo là mapper cần dùng, còn khởi tạo mapper sẽ để cho Spring xử lý ở ngoài.

Với mục đích là thử nghiệm dùng mybatis nên mình tạo các hàm đi qua các query cơ bản như delete, select, update, insert

Một điểm thú vị khi sử dụng mybatis là mình đã có thể sử dụng xử lý kiểu lambda cho các gọi hàm này.

Đến đây là xong các xử lý cơ bản, tiếp đến ta sẽ sửa ở xử lý khởi đầu chương trình để gọi đến các xử lý này.

2.2.3.Sửa MybatisApplication

Đây là đầu mối bắt đầu chương trình, hiện tại chỉ có startup Spring.
Ta sẽ sửa để gọi đến các thử nghiệm xử lý mybatis ở trên.

src/main/java/com/demo/mybatis/MybatisApplication.java

Plugin mybatis ở phần đầu ta tải không đơn thuần là mybatis đơn thuần mà là phiên bản đã được xử lý cho tiện ích với Spring.
Với tiện ích này ta chỉ cần khai báo với annotation Autowire mapper sẽ được Spring phát hiện và khởi tạo khi bắt đầu chương trình.

Với khai báo annotation Bean và khuôn mẫu hàm như trên, Spring sẽ tự phát hiện và gọi đến nên ta không cần sửa ở main()

Ở trên ta đã khai báo gọi hết các xử lý đã tạo playground.

2.2.4.Viết JUnit

Ta sẽ viết unit test với JUnit để kiểm tra xem các hàm liệu đã hoạt động đúng như ý muốn chưa, cũng như thử nghiệm xem Mapper với kiểu Join có hoạt động đúng không

src/test/java/com/demo/mybatis/MybatisApplicationTests.java

3.Chạy chương trình

Ta có thể chạy chương trình với Run Configuration với Project là mybatis và Main class là
com.demo.mybatis.MybatisApplication như trong ảnh

ta được kết quả

hoặc chạy với maven : ./mvnw spring-boot:run

Sau khi chạy, ta được cấu trúc database đã insert :

Bảng users

idnamebirthday
32test user 22010-12-01

Bảng items

idnamebirthday
22test item 132
23test item 232

Tiếp theo ta sẽ chạy thử test xem lệnh join đã được mô hình hóa dạng xml và gọi ra chạy đúng chưa. Lần này mình sẽ chạy với Maven

Kết quả

–> Chạy với 0 lỗi, xử lý gọi relation có vẻ hoạt động ổn!

4.Kết

Đến đây mình đã chia sẻ về cách sử dụng Mybatis và Mybatis Generator để nhúng lệnh SQL vào xử lý cũng như gọi query SQL dạng dynamic với framework là Spring Boot.

Hi vọng sẽ có ích cho các bạn có nghiệp vụ liên quan.

Source code : https://github.com/mytv1/mybatis-sample

Tham khảo : https://qiita.com/kazuki43zoo/items/ea79e206d7c2e990e478

Hết.

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo