對Mybatis Dynamic Query 沒概念的同學可以傳送到: http://www.cnblogs.com/wz2cool/p/7268428.html
簡介
2.0 昨天打包好了,主要是整合了tk.mybatis.mapper 到項目中去,所以和1.x比起來主要多了一個通用mapper。
哈哈~ 簡單的說,單表用通用mapper, 多表查詢仍然用動態查詢。
因為作者主要是使用springboot 這里講一下Springboot 配法。有問題的話可以參照本章demo。
本章demo下載地址: https://github.com/wz2cool/mdq2.0test
配置步驟
- 添加依賴
<!-- 基本庫 -->
<dependency>
<groupId>com.github.wz2cool</groupId>
<artifactId>mybatis-dynamic-query</artifactId>
<version>2.0.0</version>
</dependency>
<!-- 主要注冊通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.1.3</version>
</dependency>
<!-- mybatis 最新版本 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 如果有Spring boot web 自帶jackson 這個可以不要,防止版本沖突 -->
<!-- <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>-->
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
- 在applicaiton.properties 注冊DynamicQueryMapper, (這里也可以注冊自己寫的mapper)。
mapper.mappers[0]=com.github.wz2cool.dynamic.mybatis.mapper.DynamicQueryMapper
- 在Application 類中設置掃描mapper包的路徑
@SpringBootApplication
@MapperScan(basePackages = "com.github.wz2cool.mdqtest.mapper")
@EnableSwagger2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2.0 新特性
單表無XML
主要是tk.mybatis.mapper 已經實現了很多默認通用模板,所以我們無需再去寫XML,DynamicQueryMapper 在tk.mybatis.mapper 基礎上對篩選使用了我們自己的篩選器進行篩選。
實體類Product
@Table(name = "product")
public class Product {
@Id
@Column(name = "product_id")
private Integer productId;
@Column(name = "name")
private String productName;
private BigDecimal price;
private Integer categoryId;
// get/set...
}
對於mapper 我們只要繼承一下DynamicQueryMapper 即可。
public interface ProductDao extends DynamicQueryMapper<Product> {
}
然后我們就可以看到通用方法已經可使用了
全程強類型編寫
當我們使用最常用的篩選表述器FilterDescriptor/SortDescriptor 的時候,我們需要填寫我們對哪個屬性進行操作,以前是寫一個String,現在我們可以使用表達式編寫。
FilterDescriptor nameFilter = new FilterDescriptor(
User.class, User::getUsername,
FilterOperator.CONTAINS, "18");
添加自定義篩選
當FilterDescriptor 和 FilterGroupDescriptor 不能滿足我們時候我們需要使用自定義篩選,比如H2數據庫在做位運算的時候,需要調用Bitand 方法。
@Test
public void testBitand() throws Exception {
if ("h2".equalsIgnoreCase(active)) {
CustomFilterDescriptor bitFilter =
new CustomFilterDescriptor(FilterCondition.AND,
"Bitand(product_id, {0}) > {1}", 2, 0);
Map<String, Object> filterParams = MybatisQueryProvider.getWhereQueryParamMap(
Product.class, "whereExpression", bitFilter);
List<Product> products = northwindDao.getProductByDynamic(filterParams);
assertEquals(true, products.size() > 0);
} else {
CustomFilterDescriptor bitFilter =
new CustomFilterDescriptor(FilterCondition.AND,
"product_id & {0} > {1}", 2, 0);
Map<String, Object> filterParams = MybatisQueryProvider.getWhereQueryParamMap(
Product.class, "whereExpression", bitFilter);
List<Product> products = northwindDao.getProductByDynamic(filterParams);
assertEquals(true, products.size() > 0);
}
}
AS 枚舉列
以前我們都是直接 SELECT * XXX
來讀取數據,這樣做有兩個非常不好的地方
- 選擇了所有的列,不是每個列都是我們需要的,增加傳輸時間。
- 當多表查詢的時候,如果你兩個表里面有列重名了,這樣會有問題。
MybatisQueryProvider 幫助類中增加columsExpression占位。
Map<String, Object> params = MybatisQueryProvider.getQueryParamMap(dynamicQuery,
"whereExpression",
"sortExpression",
"columnsExpression");
return productViewDao.getProductViewByDynamicQuery(params);
在 xml 中的寫法
<select id="getProductViewByDynamicQuery" resultType="com.github.wz2cool.mdqtest.model.entity.view.ProductView">
SELECT ${columnsExpression} FROM product LEFT JOIN category on product.category_id = category.category_id
<if test="whereExpression != null and whereExpression != ''">WHERE ${whereExpression}</if>
<if test="orderExpression != null and orderExpression != ''">ORDER BY ${orderExpression}</if>
</select>
輸出的時候我們可以看到每個列都被AS 成為對應的屬性列了
==> Preparing: SELECT product.product_id AS product_id, product.price AS price, category.description AS description, category.name AS category_name, product.name AS product_name, category.category_id AS category_id FROM product LEFT JOIN category on product.category_id = category.category_id WHERE ((product.price > ? AND product.price < ?) AND category.name = ?)
==> Parameters: 10(Integer), 20(Integer), Condiments(String)
<== Columns: PRODUCT_ID, PRICE, DESCRIPTION, CATEGORY_NAME, PRODUCT_NAME, CATEGORY_ID
<== Row: 3, 16.5000, test, Condiments, Northwind Traders Cajun Seasoning, 2
<== Row: 8, 17.4375, test, Condiments, Northwind Traders Walnuts, 2
<== Total: 2
json 序列化支持
我們篩選器現在已經支持json 序列化,這就意味着,我們查詢可以通過接口完全動態化。當然你也可以把json 放入數據庫,當做一個配置來用。
可以運行一下我們的demo,打開swagger: http://localhost:8080/swagger-ui.html
- 先去獲取一下我們示例的json (GET /serialize/getGroupPriceFilters)
- 我們把的出來的json 調用 (POST /data/getProductsByDynamicQuery)
文章整合
Mybatis Dynamic Query 簡單篩選
Mybatis Dynamic Query 組篩選
Mybatis Dynamic Query 排序
Mybatis Dynamic Query 篩選+排序
Mybatis Dynamic Query 插入
Mybatis Dynamic Query 更新
Mybatis Dynamic Query 刪除
Mybatis Dynamic Query 屬性表達式
Mybatis Dynamic Query join視圖
結束
2.0 更新概括一下:
- 整合tk.mybatis.mapper, 並自定義 DynamicQueryMapper 通用mapper。
- 添加自定義篩選 CustomFilterDescriptor。
- AS 枚舉列。
- json 序列化支持。
關注我 ##
最后大家可以關注我和 Mybatis-Dynamic-query項目 _
Follow @wz2cool Star Fork