黑莲技术资源论坛

作者: 顺势而为47
查看: 100|回复: 0

SQL IN 語法在 MyBatis 中的正確使用姿勢

SQL IN 語法在 MyBatis 中的正確使用姿勢

[复制链接]
顺势而为47 | 显示全部楼层 发表于: 2022-9-22 18:49:23
顺势而为47 发表于: 2022-9-22 18:49:23 | 显示全部楼层 |阅读模式
查看: 100|回复: 0

前言

之前在公司的慢 SQL 治理專項中,對SQL中的範圍查詢,如 >, between 等,改用 in 語法。而 in 語法在項目中的使用,有一個很重要的點,就是里邊的元素一旦發生了變化,是很難識別到相關的風險的,怎麼寫才更具有可維護性呢,這就是本文的要分享的內容了。
本文將以SpringBoot為基礎,使用MyBatis進行數據庫的更新訪問,前置知識︰
SpringBoot集成MyBatis的相關要點
思路


  • 創建一個枚舉類,在里邊定義 in() 里邊的相關元素;
  • 將枚舉中的元素聚合、過濾傳遞給 MyBatis 層;
  • MyBatis層再傳遞到SQL的 in() 中;
案例

我們寫一個demo,簡單實踐一下思路中的內容。


1.定義領域實體ProductTypeInfo
作為一個數據庫表的對接的Java對象,模擬電商中的類目,定義了幾個基礎的字段,如自增主鍵id、創建時間create_time等。
package com.example.springbootmybatisin.domain;import lombok.Data;import java.util.Date;/** * 商品類目信息 * * @author hongcunlin */@Datapublic class ProductTypeInfo {    /**     * 主鍵     */    private Integer id;    /**     * 商品名稱     */    private String name;    /**     * 創建時間     */    private Date createTime;    /**     * 更新時間     */    private Date updateTime;    /**     * 是否有效     * 1 有效     * 0 無效     */    private Integer yn;}2.定義數據庫訪問層接口ProductTypeMapper
里邊定義個了個根據條件查詢的數據庫訪問層方法,而這個條件就準備通過從枚舉中獲取。
package com.example.springbootmybatisin.mapper;import com.example.springbootmybatisin.domain.ProductTypeInfo;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Component;import java.util.List;/** * 商品類目dao * * @author hongcunlin */@Mapper@Componentpublic interface ProductTypeMapper {    /**     * 獲取指定類目     *     * @param list 指定類目     * @return 類目     */    List<ProductTypeInfo> getProductType(List<Integer> list);}3.實現數據庫訪問接口ProductTypeMapper.xml
可以看到,我們的SQL是通過拼接入參的方式實現的
<?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--><mapper namespace="com.example.springbootmybatisin.mapper.ProductTypeMapper">    <!-- 類目 -->    <select id="getProductType" resultType="com.example.springbootmybatisin.domain.ProductTypeInfo">        select *        from product_type_info        where id in        <foreach collection="list" item="item" index="index" open="(" close=")" separator=",">            #{item}        </foreach>        and yn = 1    </select></mapper>4.定義服務接口ProductTypeService
里邊就定義了一個方法,獲取一些類目
package com.example.springbootmybatisin.service;import com.example.springbootmybatisin.domain.ProductTypeInfo;import java.util.List;/** * 商品類目服務接口 * * @author hongcunlin */public interface ProductTypeService {    /**     * 獲取重要類目     *     * @return 類目     */    List<ProductTypeInfo> getImportantProductType();}5.實現服務接口ProductTypeServiceImpl
這或許就是本文的重點吧,對枚舉進行一些操作(查詢、過濾),再傳遞給mapper層,而不是直接在SQL中寫相關的枚舉元素,提高系統的可維護性。
package com.example.springbootmybatisin.service.impl;import com.example.springbootmybatisin.domain.ProductTypeInfo;import com.example.springbootmybatisin.enums.ProductType;import com.example.springbootmybatisin.mapper.ProductTypeMapper;import com.example.springbootmybatisin.service.ProductTypeService;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;/** * 商品類目服務實現 * * @author hongcunlin */@Servicepublic class ProductTypeServiceImpl implements ProductTypeService {    /**     * 商品類目dao     */    @Resource    ProductTypeMapper productTypeMapper;    @Override    public List<ProductTypeInfo> getImportantProductType() {        // 通過枚舉獲取,可以經過過濾,再傳遞到mapper層        List<Integer> importantCode = Stream.of(ProductType.values()).map(ProductType::getCode).filter(code -> code <= 2).collect(Collectors.toList());        return productTypeMapper.getProductType(importantCode);    }}6.測試
我們來簡單測試下我們寫的程序,首先往數據庫中寫幾條測試數據,


然後編寫一個集成測試方法,
package com.example.springbootmybatisin;import com.example.springbootmybatisin.service.ProductTypeService;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTestclass SpringbootMybatisInApplicationTests {    /**     * 商品類目服務     */    @Resource    private ProductTypeService productTypeService;    /**     * 商品類目服務測試     */    @Test    void contextLoads() {        System.out.println(productTypeService.getImportantProductType());    }}運行該集成測試,結果也是我們預期的,說明程序是正確的。


最後

本文分享了SQL中的in語法,在實際項目中使用時的注意實現,通過具體的案例說明了使用的方式。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|黑莲技术资源论坛 ( 闽ICP备18016623号-7 )|网站地图

GMT+8, 2022-10-7 20:02 , Processed in 0.398834 second(s), 26 queries .

Powered by BBS.HL1.NET X3.4 © 2020-2022

本站IT社区(bbs.hl1.net)所有的资源教程均来自网友分享及互联网收集

快速回复 返回顶部 返回列表