最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis如何實現(xiàn)@Select等注解動態(tài)組合SQL語句

 更新時間:2022年07月11日 11:04:36   作者:apicescn  
這篇文章主要介紹了Mybatis如何實現(xiàn)@Select等注解動態(tài)組合SQL語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、背景說明

由于以前在項目中一直使用sqlmap.xml進行mybatis語句的編寫和實現(xiàn),其xml實現(xiàn)動態(tài)更新和查詢較為方便,而目前由于技術(shù)框架所定,采用@Select、@Insert等注解方式來實現(xiàn)對應(yīng)的持久化操作(MyBatis提供了簡單的Java注解,使得我們可以不配置XML格式的Mapper文件,也能方便的編寫簡單的數(shù)據(jù)庫操作代碼)

對于簡單的數(shù)據(jù)庫操作基本能夠滿足日常需要,但注解對動態(tài)SQL的支持一直差強人意,即使MyBatis提供了InsertProvider等*Provider注解來支持注解的Dynamic SQL,也沒有降低SQL的編寫難度,甚至比XML格式的SQL語句更難編寫和維護,實現(xiàn)較為復(fù)雜的語句時還是不那么方便,團隊成員一直通過類來實現(xiàn)SQL語句的硬拼接

這樣的硬語句編寫的SQL語句很長又冗余,給維護和修改帶來一定的成本且易讀性差,為了提高效率,一次編寫重復(fù)使用的原則,Mybatis在3.2版本之后,其實提供了LanguageDriver接口,就是便于使用該接口自定義SQL的解析方式。

故在這里將研究的MyBatis如何在注解模式下簡化SQL語句的硬拼接實現(xiàn)動態(tài)組合版SQL的方案進行分享。

二、實現(xiàn)方案

我們先來看下LanguageDriver接口中的3個方法:

public interface LanguageDriver {
    ParameterHandler createParameterHandler(MappedStatement var1, Object var2, BoundSql var3);
 
    SqlSource createSqlSource(Configuration var1, XNode var2, Class<?> var3);
 
    SqlSource createSqlSource(Configuration var1, String var2, Class<?> var3);
}
  • createParameterHandler方法為創(chuàng)建一個ParameterHandler對象,用于將實際參數(shù)賦值到JDBC語句中
  • 將XML中讀入的語句解析并返回一個sqlSource對象
  • 將注解中讀入的語句解析并返回一個sqlSource對象

一旦實現(xiàn)了LanguageDriver,我們即可指定該實現(xiàn)類作為SQL的解析器,在不使用XML Mapper的形式下,我們可以使用@Lang注解

@Mapper
public interface RoleDAO {
    /**
     *  查詢角色信息列表
     *
     * @param roleParam 查詢參數(shù)
     * @return 角色列表
     */
    @Select("select id,name,description,enabled,deleted,date_created as dateCreated,last_modified as lastModified"
        + " from admin_role (#{roleParam})")
    @Lang(SimpleSelectLangDriver.class)
    List<RoleDO> findListRoleByPage(ListRoleParam roleParam);

LanguageDriver的默認實現(xiàn)類為XMLLanguageDriver和RawLanguageDriver;

分別為XML和Raw,Mybatis默認是XML語言,所以我們來看看XMLLanguageDriver中是怎么實現(xiàn)的:

public class XMLLanguageDriver implements LanguageDriver {
    public XMLLanguageDriver() {
    }
 
    public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
    }
 
    public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
        XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);
        return builder.parseScriptNode();
    }
 
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
        if(script.startsWith("<script>")) {
            XPathParser textSqlNode1 = new XPathParser(script, false, configuration.getVariables(),
                                       new XMLMapperEntityResolver());
            return this.createSqlSource(configuration, textSqlNode1.evalNode("/script"), parameterType);
        } else {
            script = PropertyParser.parse(script, configuration.getVariables());
            TextSqlNode textSqlNode = new TextSqlNode(script);
            return (SqlSource)(textSqlNode.isDynamic()?new DynamicSqlSource(configuration, textSqlNode)
                   :new RawSqlSource(configuration, script, parameterType));
        }
    }
}

發(fā)現(xiàn)其實mybatis已經(jīng)幫忙寫好了解析邏輯,而且發(fā)現(xiàn)如果是以開頭的字符串傳入后,會被以XML的格式進行解析。那么方案就可以確認了,我們繼承XMLLanguageDriver這個類,并且重寫其createSqlSource方法,按照自己編寫邏輯解析好sql后,再調(diào)用父類的方法即可。

三、 實現(xiàn)自定義注解

本例中將給出一些常見的自定義注解的實現(xiàn)和使用方式。

1、自定義Select注解

在本例中的業(yè)務(wù)場景下,我們需要根據(jù)對象中的字段進行查詢,就會寫出硬SQL語句拼接類,如下代碼:

    /**
     * 查詢
     *
     * @param userParam 查詢條件
     * @return 用戶信息列表
     */
    @SelectProvider(type = UserSql.class, method = "listByPage")
    List<UserDO> listByPage(@Param(value = "userParam") ListUserParam userParam);
public class UserSql {
    /**
     * 拼接查詢語句
     *
     * @param params 查詢條件
     * @return 查詢語句
     */
    public static String listByPage(Map params) {
 
        ListUserParam userParam = (ListUserParam)params.get("userParam");
        if (userParam == null) {
            return "";
        }
        long begin = (userParam.getPi() - 1) * userParam.getPs();
        long end = userParam.getPi() * userParam.getPs();
 
        String condition = "";
 
        StringBuffer sb = new StringBuffer(" with query as ( ");
        sb.append(
            " select row_number() over(order by user.last_modified desc, user.date_created desc) as row_nr, user.* ");
        sb.append(" from ( ");
        sb.append(" select * from admin_user where 1=1 ");
        condition = " and username like '%#{userParam.username}%'";
        sb.append(StringUtils.isBlank(userParam.getUsername()) ? "" : condition);
        condition = " and name like '%#{userParam.name}%'";
        sb.append(StringUtils.isBlank(userParam.getName()) ? "" : condition);
        condition = " and mobile like '%#{userParam.mobile}%'";
        sb.append(StringUtils.isBlank(userParam.getMobile()) ? "" : condition);
        condition = " and authorities like '%#{userParam.authorities}%'";
        sb.append(StringUtils.isBlank(userParam.getAuthorities()) ? "" : condition);
        condition = " and enabled = #{userParam.enabled}";
        sb.append(StringUtils.isBlank(userParam.getEnabled()) ? "" : condition);
        sb.append(" ) ");
        sb.append(" user) ");
        sb.append(" ");
        sb.append(" select ");
        sb.append(" id, username, password, name, mobile, authorities, enabled, deleted, ");
        sb.append(" creator_id as creatorId, creator, date_created as dateCreated, ");
        sb.append(" modifier_id as modifierId, modifier, last_modified as lastModified ");
        sb.append(" from query where row_nr > ");
        sb.append(begin);
        sb.append(" and row_nr <= ");
        sb.append(end);
        sb.append(" order by last_modified desc, date_created desc ");
 
        log.info("====UserSql.query====sb:{}", sb.toString());
 
        return sb.toString();
    }
 
}

對于這樣硬拼接的SQL語句可讀性較差,也不利用日常維護,我們可以通過實現(xiàn)LanguageDriver將where子句抽象化,以此來簡化Select查詢語句。

簡化后代碼如下( 在上述實現(xiàn)方案中已貼過代碼):

/**
     *  查詢角色信息列表
     *
     * @param roleParam 查詢參數(shù)
     * @return 角色列表
     */
    @Select("select id,name,description,enabled,deleted,date_created as dateCreated,last_modified as lastModified"
        + " from admin_role (#{roleParam})")
    @Lang(SimpleSelectLangDriver.class)
    List<RoleDO> findListRoleByPage(ListRoleParam roleParam);

其SimpleSelectLangDriver的實現(xiàn)代碼如下:

package com.szss.admin.common;
 
import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
 
import com.google.common.base.CaseFormat;
 
/**
 * @author Allen
 * @date 2018/3/9
 *
 * 自定義Select注解,用于動態(tài)生成Select語句
 */
public class SimpleSelectLangDriver extends XMLLanguageDriver implements LanguageDriver {
 
    /**
     * Pattern靜態(tài)申明
     */
    private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
 
    /**
     * 實現(xiàn)自定義Select注解
     * @param configuration 配置參數(shù)
     * @param script 入?yún)?
     * @param parameterType 參數(shù)類型
     * @return 轉(zhuǎn)換后的SqlSource
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
 
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            StringBuilder sb = new StringBuilder();
            sb.append("<where>");
 
            for (Field field : parameterType.getDeclaredFields()) {                
                    String tmp = "<if test=\"_field != null\"> AND _column=#{_field}</if>";
                    sb.append(tmp.replaceAll("_field", field.getName()).replaceAll("_column",
                        CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));
            }
 
            sb.append("</where>");
 
            script = matcher.replaceAll(sb.toString());
            script = "<script>" + script + "</script>";
        }
 
        return super.createSqlSource(configuration, script, parameterType);
    }
}

上述代碼實現(xiàn)了動態(tài)生成SQL語句的功能,但由于在VO實體類中可能有部分參數(shù)是我們不想加入到動態(tài)組合里面的或部分字段在數(shù)據(jù)庫中并不存在相應(yīng)的列(比如自動 生成的serialVersionUID等其他字段),這時我們就需要排除VO實體類的一些多余的不匹配的字段進行邏輯隱藏;我們增加一個自定義的注解,并且對Language的實現(xiàn)稍作修改即可。 

新建一個注解,其代碼如下:

package com.szss.admin.common;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * @author Allen
 * @date 2018/3/9
 *
 *  自定義的注解,用于排除多余的變量(自定義注解,過濾多余字段)
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Invisible {
}

然后在VO實體類中不需要加入的字段可進行引用該注解

package com.szss.admin.model.param;
 
import com.szss.admin.common.Invisible;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
 
/**
 * 角色查詢參數(shù)
 *
 * @author Allen
 * @date 2018/3/8
 */
@Data
public class ListRoleParam {
 
    /**
     * 角色名稱
     */
    @ApiModelProperty(value = "角色名稱", example = "管理員", position = 1)
    private String name;
 
 
    /**
     * 是否啟用:0-不可用,1-可用
     */
    @ApiModelProperty(value = "是否啟用", example = "0", position = 2)
    private Boolean enabled;
 
    /**
     * 刪除標(biāo)示:0-未刪除,1-已刪除
     */
    @ApiModelProperty(value = "刪除標(biāo)示", example = "0", position = 3)
    private Boolean deleted;
 
    /**
     * 當(dāng)前頁碼
     */
    @ApiModelProperty(value = "當(dāng)前頁碼", example = "1", position = 4)
    @Invisible
    private long pi;
    /**
     * 當(dāng)前頁面大小
     */
    @ApiModelProperty(value = "當(dāng)前頁面大小", example = "10", position = 5)
    @Invisible
    private long ps;
 
}

最后需要對上述中的SimpleSelectLangDriver實現(xiàn)類中將被該注解聲明過的字段排除操作,代碼如下:

            for (Field field : parameterType.getDeclaredFields()) {
                // 排除被Invisble修飾的變量
                if (!field.isAnnotationPresent(Invisible.class)) {
                    String tmp = "<if test=\"_field != null\"> AND _column=#{_field}</if>";
                    sb.append(tmp.replaceAll("_field", field.getName()).replaceAll("_column",
                        CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));
                }
            }

如上所示,只是對SimpleSelectLangDriver類增加了if (!field.isAnnotationPresent(Invisible.class)) 這樣的判斷,已過濾多余的變量。

需要注意的是在使用Select的時候,傳入的參數(shù)前無需加入@Param注解,否則會導(dǎo)致Mybatis找不到參數(shù)而拋出異常,如需加入 就需要綁定對象屬性(如在語句中就需要使用param.name)。

2、自定義Select in注解

在使用Mybatis注解的時候,發(fā)現(xiàn)其對Select In格式的查詢支持不是很友好,在字符串中輸入十分繁瑣,可以通過將自定義的標(biāo)簽轉(zhuǎn)成格式;下面便通過我們自己實現(xiàn)的LanguageDriver來實現(xiàn)SQL的動態(tài)解析:

DAO接口層中代碼如下:

@Select("SELECT * FROM admin_role WHERE id IN (#{roleIdList})")
@Lang(SimpleSelectInLangDriver.class)
List<RoleDO> selectRolesByRoleId(List<Integer> roleIdList);

LanguageDriver實現(xiàn)類如下:

package com.szss.admin.common;
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
 
/**
 * @author Allen
 * @date 2018/3/9
 *
 * 自定義Select in 注解,用于動態(tài)生成Select in 語句
 */
public class SimpleSelectInLangDriver extends XMLLanguageDriver implements LanguageDriver {
 
    /**
     * Pattern靜態(tài)申明
     */
    private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
 
    /**
     * 實現(xiàn)自定義Select in 注解
     * @param configuration 配置參數(shù)
     * @param script 入?yún)?
     * @param parameterType 參數(shù)類型
     * @return 轉(zhuǎn)換后的SqlSource
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
 
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            script = matcher.replaceAll("<foreach collection=\"$1\" item=\"_item\" open=\"(\" "
                + "separator=\",\" close=\")\" >#{_item}</foreach>");
        }
 
        script = "<script>" + script + "</script>";
 
        return super.createSqlSource(configuration, script, parameterType);
    }
}

通過自己實現(xiàn)LanguageDriver,在服務(wù)器啟動的時候,就會將我們自定義的標(biāo)簽解析為動態(tài)SQL語句,其等同于:

@Select("SELECT * " +
        "FROM admin_role " +
        "WHERE id IN " +
        "<foreach item='item' index='index' collection='list'open='(' separator=',' close=')'>" +
        "#{item}" +
        "</foreach>")
List<RoleDO> selectRolesByRoleId(List<Integer> roleIdList);

通過實現(xiàn)LanguageDriver,剝離了冗長的動態(tài)拼接SQL語句,簡化了Select In的注解代碼。

需要注意的是在使用Select In的時候,則與上述相反需務(wù)必在傳入的參數(shù)前加@Param注解,否則會導(dǎo)致Mybatis找不到參數(shù)而拋出異常。

3、自定義Update的注解

在擴展update注解時,數(shù)據(jù)庫每張表的字段和實體類的字段必須遵循一個約定(數(shù)據(jù)庫中采用下劃線命名法,實體類中采用駝峰命名法)。

當(dāng)我們update的時候,會根據(jù)每個字段的映射關(guān)系,寫出如下代碼:

/**
     * 更新
     *
     * @param roleDO 角色信息
     * @return 影響行數(shù)
     */
    @Update("update admin_role set role_name = #{roleDO.roleName}, "
        + " enabled = #{roleDO.enabled}, deleted = #{roleDO.deleted}, modifierId = #{roleDO.modifierId},"
        + " modifier = #{roleDO.modifier}, last_modified = #{roleDO.lastModified} where id = #{roleDO.id}")
    int update(@Param(value = "roleDO") RoleDO roleDO);

上述的代碼我們可以將實體類中的駝峰式代碼轉(zhuǎn)換為下劃線式命名方式,這樣就可以將這種映射規(guī)律自動化,但此代碼存在一定的問題,就是當(dāng)你在更新部分字段時其余所有字段原來的值必須傳入,否則可能會將原有數(shù)據(jù)更新為null或空,亦或在更新時先查詢原數(shù)據(jù)后將變更的數(shù)據(jù)進行操作,這樣不僅增加了數(shù)據(jù)庫查詢操作且會造成代碼冗余,而經(jīng)過實現(xiàn)LanguageDriver后,注解代碼如下:

    /**
     * 更新
     *
     * @param roleParam 角色信息
     */
    @Update("update admin_role (#{roleDO}) where id=#{id}")
    @Lang(SimpleUpdateLangDriver.class)
    void update(RoleParam roleParam);

相對于原始的代碼量有很大的減少,尤其是對于一個類中字段越多,改善也就越明顯。實現(xiàn)方式為:

package com.szss.admin.common;
 
import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
 
import com.google.common.base.CaseFormat;
 
/**
 * @author Allen
 * @date 2018/3/9
 *
 * 自定義Update注解,用于動態(tài)生成Update語句
 */
public class SimpleUpdateLangDriver extends XMLLanguageDriver implements LanguageDriver {
 
    /**
     * Pattern靜態(tài)申明
     */
    private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
 
    /**
     * 實現(xiàn)自定義Update注解
     * @param configuration 配置參數(shù)
     * @param script 入?yún)?
     * @param parameterType 參數(shù)類型
     * @return 轉(zhuǎn)換后的SqlSource
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
 
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            StringBuilder sb = new StringBuilder();
            sb.append("<set>");
 
            for (Field field : parameterType.getDeclaredFields()) {
                // 排除被Invisble修飾的變量
                if (!field.isAnnotationPresent(Invisible.class)) {
                    String tmp = "<if test=\"_field != null\">_column=#{_field},</if>";
                    sb.append(tmp.replaceAll("_field", field.getName()).replaceAll("_column",
                        CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));
                }
            }
 
            sb.deleteCharAt(sb.lastIndexOf(","));
            sb.append("</set>");
 
            script = matcher.replaceAll(sb.toString());
            script = "<script>" + script + "</script>";
        }
 
        return super.createSqlSource(configuration, script, parameterType);
    }
}

注意此處在傳入的參數(shù)前無需加入@Param注解。

4、自定義Insert的注解 同理

我們可以抽象化Insert操作,簡化后的Insert注解為:

    /**
     * 插入
     *
     * @param roleParam 角色信息
     */
    @Insert("insert into admin_role (#{roleDO})")
    @Lang(SimpleInsertLangDriver.class)
    void insert(RoleParam roleParam);

SimpleInsertLanguageDriver實現(xiàn)類代碼如下:

package com.szss.admin.common;
 
import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
 
import com.google.common.base.CaseFormat;
 
/**
 * @author Allen
 * @date 2018/3/9
 *
 * 自定義Insert注解,用于動態(tài)生成Insert語句
 */
public class SimpleInsertLangDriver extends XMLLanguageDriver implements LanguageDriver {
 
    /**
     * Pattern靜態(tài)申明
     */
    private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");
 
    /**
     * 實現(xiàn)自定義Insert注解
     * @param configuration 配置參數(shù)
     * @param script 入?yún)?
     * @param parameterType 參數(shù)類型
     * @return 轉(zhuǎn)換后的SqlSource
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
 
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            StringBuilder sb = new StringBuilder();
            StringBuilder tmp = new StringBuilder();
            sb.append("(");
 
            for (Field field : parameterType.getDeclaredFields()) {
                if (!field.isAnnotationPresent(Invisible.class)) {
                    sb.append(
                        CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())
                            + ",");
                    tmp.append("#{" + field.getName() + "},");
                }
            }
 
            sb.deleteCharAt(sb.lastIndexOf(","));
            tmp.deleteCharAt(tmp.lastIndexOf(","));
            sb.append(") values ("
                + tmp.toString() + ")");
 
            script = matcher.replaceAll(sb.toString());
            script = "<script>" + script + "</script>";
        }
 
        return super.createSqlSource(configuration, script, parameterType);
    }
}

至此我們完成了基本的@Select、@Update、@Insert自定義注解,簡單化繁雜的拼接SQL語句的尷尬,但以上代碼在SimpleSelectLangDriver中還有一定的局限性,比如對于一些字段我們需要使用like來進行查詢,這時就需要對上述自定義Seleect注解進行完善以實現(xiàn)各種業(yè)務(wù)的場景。

四、注意事項&遇到的一些坑

  • 務(wù)必確保數(shù)據(jù)庫中列名和實體類中字段能一一對應(yīng)。
  • 在使用自定義SQL解析器的時候,只能傳入一個參數(shù),即相應(yīng)的對象參數(shù)即可;傳入多個參數(shù)會導(dǎo)致解析器中獲得到的class對象改變,使得sql解析異常。
  • Update的實現(xiàn)能滿足大部分的業(yè)務(wù),但有些業(yè)務(wù)場景可以會遇到根據(jù)查詢條件來更新查詢參數(shù)的情況,比如Update user SET uesr_name = ‘王雷’  WHERE user_name = ‘小王’; 在這樣的場景中請不要使用自定義的SQL解析器。
  • 請使用Mybatis 3.3以上版本。3.2以下版本會存在一些Bug,在本例中使用的為mybatis-spring-boot-starter1.3.1,其Mybatis為3.4.5。

五、總結(jié)

通過實現(xiàn)Language Driver,我們可以很方便的自定義自己的注解。在遵循一些約定的情況下(數(shù)據(jù)庫下劃線命名,實體駝峰命名),我們可以大幅度的減少SQL的編寫量,并且可以完全的屏蔽掉麻煩的XML編寫方式,再也不用再編寫復(fù)雜的拼接動態(tài)SQL的煩惱,簡化工作,提高開發(fā)效率。

    //簡潔的數(shù)據(jù)庫操作
    /**
     *  查詢角色信息列表
     *
     * @param roleParam 查詢參數(shù)
     * @return 角色列表
     */
    @Select("select id,name,description,enabled,deleted,date_created as dateCreated,last_modified as lastModified"
        + " from admin_role (#{roleParam})")
    @Lang(SimpleSelectLangDriver.class)
    List<RoleDO> findListRoleByPage(ListRoleParam roleParam);
 
    /**
     * 插入
     *
     * @param roleParam 角色信息
     */
    @Insert("insert into admin_role (#{roleDO})")
    @Lang(SimpleInsertLangDriver.class)
    void insert(RoleParam roleParam);
 
    /**
     * 更新
     *
     * @param roleParam 角色信息
     */
    @Update("update admin_role (#{roleDO}) where id=#{id}")
    @Lang(SimpleUpdateLangDriver.class)
    void update(RoleParam roleParam);

通過@Lang注解以及自定義LanguageDriver類實現(xiàn)來簡化數(shù)據(jù)庫操作,不僅代碼減少便于可讀的同時,還避免了在更新時需要獲取原數(shù)據(jù)的操作。

注:上述通過@Lang及實現(xiàn)LanguageDriver類的方法目前已基本不建議采用了,可采取Mybatis Plus來進行取代更為方便和快捷,具體可參加本博客的另一篇文章<Spring Boot環(huán)境下Mybatis Plus的快速應(yīng)用>

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解 Java靜態(tài)代理

    詳解 Java靜態(tài)代理

    這篇文章主要介紹了 Java靜態(tài)代理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java代理的知識,感興趣的朋友可以了解下
    2020-08-08
  • SpringBoot一個非常蛋疼的無法啟動的問題解決

    SpringBoot一個非常蛋疼的無法啟動的問題解決

    這篇文章主要介紹了SpringBoot一個非常蛋疼的無法啟動的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • SpringCloud配置服務(wù)端的ConfigServer設(shè)置安全認證

    SpringCloud配置服務(wù)端的ConfigServer設(shè)置安全認證

    這篇文章主要為大家介紹了SpringCloud配置服務(wù)端的ConfigServer設(shè)置安全認證,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 淺談Java并發(fā)中的內(nèi)存模型

    淺談Java并發(fā)中的內(nèi)存模型

    這篇文章主要介紹了Java并發(fā)中的內(nèi)存模型,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Java繼承的實現(xiàn)與繼承限制分析

    Java繼承的實現(xiàn)與繼承限制分析

    這篇文章主要介紹了Java繼承的實現(xiàn)與繼承限制,結(jié)合具體實例形式分析了Java繼承的定義、實現(xiàn)以及繼承的相關(guān)限制,需要的朋友可以參考下
    2019-01-01
  • Springboot報錯java.lang.NullPointerException: null問題

    Springboot報錯java.lang.NullPointerException: null問題

    這篇文章主要介紹了Springboot報錯java.lang.NullPointerException: null問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java使用Queryable-pageable實現(xiàn)分頁效果

    Java使用Queryable-pageable實現(xiàn)分頁效果

    這篇文章主要為大家介紹了Java如何使用Queryable-pageable從而實現(xiàn)分頁效果,文中的示例代碼簡潔易懂,感興趣的小伙伴可以動手嘗試一下
    2022-06-06
  • Mybatis使用update更新值為null時不生效問題解決

    Mybatis使用update更新值為null時不生效問題解決

    這篇文章主要介紹了Mybatis使用update更新值為null時不生效問題解決,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • java自定義日志輸出文件(log4j日志文件輸出多個自定義日志文件)

    java自定義日志輸出文件(log4j日志文件輸出多個自定義日志文件)

    打印日志的在程序中是必不可少的,如果需要將不同的日志打印到不同的地方,則需要定義不同的Appender,然后定義每一個Appender的日志級別、打印形式和日志的輸出路徑,下面看一個示例吧
    2014-01-01
  • Spring IOC 三種配置方式詳解

    Spring IOC 三種配置方式詳解

    這篇文章主要介紹了Spring IOC 三種配置方式,基于xml配置方式組件管理,基于注解方式管理和配置類方式管理,這三種方式,通過圖文講解的非常詳細,需要的朋友可以參考下
    2024-05-05

最新評論

沙田区| 林州市| 固阳县| 北碚区| 和田县| 安宁市| 都兰县| 宝兴县| 南川市| 扎赉特旗| 兴国县| 沛县| 浦北县| 肥乡县| 张家口市| 灵武市| 兰考县| 凌源市| 临武县| 东乡| 获嘉县| 紫金县| 盐池县| 罗定市| 鹤庆县| 台南市| 深水埗区| 新竹市| 任丘市| 沿河| 柳林县| 呼和浩特市| 齐齐哈尔市| 拜城县| 湖州市| 苍山县| 衢州市| 福泉市| 松溪县| 滦南县| 富民县|