Hôm nay tôi đã chuẩn bị một ví dụ bằng cách sử dụng Spring Boot và sử dụng MyBatis cho giao tiếp truy cập dữ liệu bên cạnh Spring-MyBatis. Dưới đây là cấu hình dự án có liên quan (sử dụng maven):Tại sao giao diện và tệp bản đồ xml phải nằm trong cùng một gói và có cùng tên?
src/main/java
- edu.home.ltmj.controller
+ CategoryController.java
- edu.home.ltmj.dao
+ CategoryDao.java
- edu.home.ltmj.domain
+ Category.java
src/main/resources
- edu.home.ltmj.dao
+ CategoryMapper.xml
nội dung có liên quan của các tập tin:
CategoryDao.java:
package edu.home.ltmj.dao;
public interface CategoryDao {
List<Category> getAllCategories();
}
CategoryMapper.xml:
<mapper namespace="edu.home.ltmj.dao.CategoryDao">
<resultMap id="categoryMap"
type="edu.home.ltmj.domain.Category">
<id property="id" column="id" />
<result property="name" column="name" />
</resultMap>
<select id="getAllCategories" resultMap="categoryMap">
SELECT id, nombre
FROM category
</select>
</mapper>
Sau đó, tôi tiêm một thể hiện của dao này trong một bộ điều khiển yêu cầu (cho mục đích thử nghiệm), như thế này:
package edu.home.ltmj.controller;
@RestController
public class CategoryController {
@Autowired
private CategoryDao dao;
@RequestMapping(value="/category/all",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public List<Categoria> getAllCategories() {
return dao.getAllCategories();
}
}
tôi chạy dự án của tôi và kiểm tra việc thực hiện bằng cách sử dụng curl localhost:8080/category/all
và sau đó dự kiến để xem kết quả ở định dạng JSON, nhưng tôi có ngoại lệ này thay vì:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): edu.home.ltmj.dao.CategoryDao.getAllCategories
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
at com.sun.proxy.$Proxy45.getAllCategories(Unknown Source)
at edu.home.ltmj.controller.CategoryRestController.getAllCategories(CategoryRestController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(...)
Tôi không hiểu nguyên nhân điều này. Có một giao diện CategoryDao
và nó có phương thức thích hợp getAllCategories
khớp với <select id="getAllCategories">
. Sau một thời gian chơi với điều này, tôi đã thay đổi tên giao diện dao thành CategoryMapper
và cập nhật không gian tên trong CategoryMapper.xml. Sau khi tôi đã làm điều này, mọi thứ hoạt động bình thường. Ngoài ra, sau khi có cùng tên cho lớp và xml, tôi đã di chuyển lớp dao và trình ánh xạ xml thành các gói khác nhau (stil sử dụng cùng tên cho cả hai: CategoryMapper.), Cập nhật không gian tên trong tệp xml và có cùng ngoại lệ , với thông báo được cập nhật để hiển thị tên của gói của giao diện dao. Nhưng sau đó một lần nữa, tôi di chuyển cả hai tập tin vào cùng một gói và tất cả mọi thứ đã làm việc một lần nữa.
Vì vậy, câu hỏi của tôi là: tại sao MyBatis cần giao diện và tệp bản đồ xml có cùng tên và nằm trong cùng một gói? Đây có phải là thiết kế MyBatis hoặc sự cố trong Spring MyBatis không?
tôi sử dụng '@ MapperScan' và chỉ ra các gói cơ sở nơi MyBatis có thể quét tất cả các người vẽ bản đồ của chính nó. Chú thích này hoạt động như ' ' để tự động quét các tập tin và do đó không sử dụng ' '. –
@LuiggiMendoza: '@ MapperScan' tìm giao diện. Xem chỉnh sửa của tôi cho câu trả lời. – Bogdan
Điều này thật thú vị. Cuối cùng, đó là một điều MyBatis * * toàn bộ sự phân tách mối quan tâm giữa giao diện và người lập bản đồ, trong khi '@ MapperScan' giúp cho việc tự động đậu các giao diện dao. Cảm ơn bạn đã liên kết đến tài liệu thích hợp và ví dụ. –