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

dbVisitor 和 MyBatis有什么區(qū)別

 更新時(shí)間:2026年03月13日 10:30:17   作者:哈庫納  
dbVisitor是為了解決MyBatis在多數(shù)據(jù)源架構(gòu)和輕量化開發(fā)中的痛點(diǎn)而誕生的框架,它在保持MyBatis核心開發(fā)習(xí)慣的同時(shí),提供了更多的功能和便利,本文介紹dbVisitor 和 MyBatis有什么區(qū)別,感興趣的朋友跟隨小編一起看看吧

你是否經(jīng)歷過這樣的絕望:為了給一個(gè)簡單的查詢加個(gè) status != -1 的條件,你不得不在 XML 里寫一堆 <if> 標(biāo)簽? 或者,為了同時(shí)查詢 MySQL 和 MongoDB,你的 Service 層里充斥著風(fēng)格迥異的 UserMapperMongoTemplate 代碼?

MyBatis 很好,陪伴了我們十年。它穩(wěn)定、強(qiáng)大,是 Java 該領(lǐng)域的絕對霸主。但面對現(xiàn)在的多數(shù)據(jù)源架構(gòu)、輕量化開發(fā)需求,這艘巨輪是不是顯得有點(diǎn)“重”了?

dbVisitor 的誕生并非為了重復(fù)造輪子,而是為了在保持 MyBatis 核心開發(fā)習(xí)慣(Mapper/XML)的同時(shí),解決那些讓你頭疼已久的痛點(diǎn)。

功能體驗(yàn)MyBatisMyBatis-PlusdbVisitor備注
Mapper 接口開發(fā)???都支持定義 Interface 自動(dòng)代理
XML SQL 定義???標(biāo)簽結(jié)構(gòu)高度兼容 (ResultMap/select...)
注解 SQL 定義???@Select / @Insert 等注解支持
DTO/Bean 映射???自動(dòng)駝峰轉(zhuǎn)換、ResultMap 映射
Lambda 鏈?zhǔn)秸{(diào)用???類型安全的 CRUD 構(gòu)建器
分頁查詢???直接在 API 或 SQL 中控制分頁
即時(shí) SQL 執(zhí)行???無需定義 Mapper 也能直接運(yùn)行 SQL
動(dòng)態(tài)規(guī)則 (Rules)???腳本式動(dòng)態(tài) SQL @{and ...}
NoSQL 支持???一套 API 操作 MySQL/Mongo/ES

1. 熟悉的配方

通過對比 dbVisitor 和 MyBatis 的 XSD 定義文件,可以發(fā)現(xiàn)驚人的相似性(兩者都以 <mapper> 為根節(jié)點(diǎn), 核心標(biāo)簽 <select>, <insert> 完全一致)。 這意味著:MyBatis 開發(fā)者無需閱讀文檔,憑借直覺即可編寫 dbVisitor 的 XML 文件,甚至可以直接復(fù)用現(xiàn)有的 XML 文件。接下來讓我們詳細(xì)看看兩者在經(jīng)典用法上有何差異?

1.1 Mapper 接口開發(fā)

dbVisitor 沿用了 Mapper 接口的開發(fā)模式,對于習(xí)慣了 MyBatis 的開發(fā)者來說幾乎沒有學(xué)習(xí)成本。

MyBatis

使用 @Mapper 標(biāo)記接口,并配合 @Select, @Insert 等注解。

@Mapper
public interface UserMapper {
    User selectById(Long id);
    @Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
    int insert(User user);
}

dbVisitor

使用 @SimpleMapper 標(biāo)記接口,使用 @Query 代替 @Select(語義更寬泛,涵蓋所有查詢),其他如 @Insert 等保持一致。

@SimpleMapper
public interface UserMapper {
    // 對應(yīng) XML 中的 id 或直接使用 @Query
    User selectById(@Param("id") Long id);
    @Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
    int insert(User user);
}

1.2 XML SQL 定義

dbVisitor 的 XML 定義與 MyBatis 在結(jié)構(gòu)和核心標(biāo)簽上高度一致。

MyBatis (UserMapper.xml)

<?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 namespace="com.example.mapper.UserMapper">
    <select id="selectById" resultType="com.example.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

dbVisitor (UserMapper.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//dbvisitor.net//DTD Mapper 1.0//EN"
        "https://www.dbvisitor.net/schema/dbvisitor-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectById" resultType="com.example.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

1.3 注解 SQL 定義

MyBatis

@Select("SELECT * FROM user WHERE name = #{name}")
User selectByName(String name);

dbVisitor

@Query("SELECT * FROM user WHERE name = #{name}")
User selectByName(@Param("name") String name);

1.4 DTO/Bean 映射

在字段名不一致(如 DB 是 user_name,Java 是 name)的場景下,映射方式的繁簡程度決定了開發(fā)效率。

MyBatis (XML 派)

MyBatis 傾向于通過 XML 中的 ResultMap 來解決字段映射問題。雖然開啟駝峰配置 (mapUnderscoreToCamelCase) 能解決簡單場景,但面對差異較大的字段名,開發(fā)者不得不編寫冗長的 resultMap 標(biāo)簽。

<!-- 必須顯式定義映射關(guān)系 -->
<resultMap id="userMap" type="com.example.User">
    <result column="user_name" property="name"/>
    <result column="user_age" property="age"/>
</resultMap>
<select id="selectById" resultMap="userMap"> ... </select>

MyBatis-Plus (注解派)

MP 引入了注解驅(qū)動(dòng),允許直接在實(shí)體類上定義映射關(guān)系,從而擺脫對 ResultMap 的依賴。

public class User {
    @TableField("user_name") // 使用注解解決映射
    private String name;
}

dbVisitor (全兼容)

dbVisitor 選擇了 “我全都要” 的兼容策略,你可以在三種模式中任意切換:

  1. 自動(dòng)映射(默認(rèn)):內(nèi)置智能的駝峰轉(zhuǎn)換,90% 的場景無需任何配置。
  2. 注解模式(MP 風(fēng)格):使用 @Column 注解定義特定字段,無需 XML。
    public class User {
        @Column("user_name") // 類似 MP 的 @TableField
        private String name;
    }
    
  3. ResultMap 模式(MyBatis 風(fēng)格):完全兼容 MyBatis 的 <resultMap> 標(biāo)簽。如果你正在遷移舊項(xiàng)目,或者需要非常復(fù)雜的嵌套映射,直接把舊的 XML 拿來用即可。
    <!-- 完全兼容 MyBatis 語法的 ResultMap -->
    <resultMap id="userMap" type="com.example.User">
        <result column="user_name" property="name"/>
    </resultMap>
    

1.5 Lambda 鏈?zhǔn)秸{(diào)用

dbVisitor 提供了一套類型安全的 Lambda 構(gòu)建器,它的核心價(jià)值不僅僅是像 MyBatis-Plus 那樣避免手寫 SQL,更在于它實(shí)現(xiàn)了 "One API Access Any DataBase" 的理念。 無論底層是 MySQL、Oracle 還是 MongoDB、Elasticsearch,你都可以使用同一套 Lambda API 進(jìn)行操作。這意味著你的團(tuán)隊(duì)只需要掌握一種 CRUD 語法。

用法對比

  • MyBatis-Plus:強(qiáng)依賴 Mapper 接口,API 設(shè)計(jì)主要面向 SQL 數(shù)據(jù)庫。
  • dbVisitor:基于 LambdaTemplate,無需定義接口即可直接使用。
// 統(tǒng)一入口:無論操作什么數(shù)據(jù)庫,起點(diǎn)都是 template new 出來即可
JdbcTemplate template = ...;

場景 1:標(biāo)準(zhǔn) SQL 查詢 (MySQL/PG)

// 使用 Java 方法引用避免字段拼寫錯(cuò)誤
UserInfo user = template.lambdaQuery(UserInfo.class)
    .eq(UserInfo::getType, "admin")
    .gt(UserInfo::getAge, 18)
    .list();

場景 2:統(tǒng)一關(guān)系型非關(guān)系型數(shù)據(jù)庫

神奇之處在于,完全相同的代碼,也可以用于操作 Elasticsearch 或 MongoDB,dbVisitor 會(huì)自動(dòng)將查詢條件轉(zhuǎn)譯為對應(yīng)的 DSL。

// 操作 Elasticsearch (自動(dòng)轉(zhuǎn)換為 DSL)
// GET /user_index/_search { "query": { "bool": ... } }
EsUser user = template.lambdaQuery(EsUser.class)
    .eq(EsUser::getId, "1001") // 通過 EsUser 的字段映射為 _id
    .one();
// 操作 MongoDB
// db.access_log.insert({ ... })
template.lambdaInsert(AccessLog.class)
    .applyEntity(new AccessLog(...))
    .executeSumResult();

這種統(tǒng)一性極大地降低了多數(shù)據(jù)源混合架構(gòu)的維護(hù)成本。

2. 拒絕 XML 地獄

2.1 即時(shí) SQL 執(zhí)行

即時(shí) SQL 執(zhí)行能力不僅是 “能執(zhí)行 SQL”,更代表了框架在不同抽象層級上的靈活度。dbVisitor 允許你在三種層級上自由切換,無需被 XML 束縛。

A. 純血 SQL

這是 dbVisitor 最基礎(chǔ)的模式。它高度復(fù)刻了 Spring JDBC 的能力(如 queryForList, query, execute 等)

// 1. 獲取 Template
JdbcTemplate jdbc = ...;
// 2. 直接執(zhí)行 SQL,利用 dbVisitor 強(qiáng)大的 Mapper 映射結(jié)果
List<UserInfo> users = jdbc.queryForList(
            "select * from user where age > ?", UserInfo.class, 18);
// 3. 甚至執(zhí)行腳本
jdbc.execute("delete from user where age < 10");

B. Lambda API 上使用 SQL

LambdaTemplate 雖然主打類型安全的構(gòu)建器,但它同樣允許你在 Lambda 中直接執(zhí)行原生 SQL。

LambdaTemplate lambda = ...;
lambda.jdbc().queryForList(
            "select * from user where status = ?", User.class, 1);

C. Mapper 接口上使用 SQL

這是 MyBatisMyBatis-Plus 不具備的,同時(shí)也被詬病最多的地方。

  • 用戶:我就是想用一下 SQL 不要給我搞注解、搞 XML 好不好!
  • MyBatis/MP:抱歉不行!
  • dbVisitor:沒問題馬上安排!
@SimpleMapper
public interface UserMapper extends BaseMapper<UserInfo> {
    // 方式 1: 傳統(tǒng)的注解模式
    @Query("select * from user where type = #{type}")
    List<UserInfo> findByType(@Param("type") String type);
    // 方式 2: default 方法 + 內(nèi)置 JDBC 能力
    // 適合:邏輯復(fù)雜,不想寫 XML,但又想封裝在 Mapper 里的場景
    default List<UserInfo> findActiveUsers() {
        return this.jdbc().queryForList(
                "select * from user where active = 1", UserInfo.class);
    }
}

2.2 動(dòng)態(tài)規(guī)則

本質(zhì)是對動(dòng)態(tài) SQL 拼接的一種創(chuàng)新解決方案。它改變了 MyBatis 系列中 <if> 標(biāo)簽泛濫的問題。

  • MyBatis 系列:依賴 XML 標(biāo)簽(<if>, <where>, <choose>)來實(shí)現(xiàn)動(dòng)態(tài) SQL,導(dǎo)致 XML 結(jié)構(gòu)臃腫且難以維護(hù)。
  • dbVisitor:引入 @{...} 語法,將條件動(dòng)態(tài)嵌入 SQL 字符串中,極大簡化了動(dòng)態(tài) SQL 的編寫。
<!-- MyBatis 系列 -->
<select id="findUser">
    SELECT * FROM user
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age > :age
        </if>
    </where>
</select>
<!-- dbVisitor 方式 -->
<select id="findUser">
    SELECT * FROM user
    @{and name = :name}
    @{and age > :age}
</select>

還能這么用?

// 在 SQL 中使用
JdbcTemplate jdbc = ...;
List<UserInfo> users = jdbc.queryForList(
            "SELECT * FROM user @{and name = :name} @{and age > :age}",
            UserInfo.class, 18);
// 在 Mapper 接口注解中用
@SimpleMapper
public interface UserMapper extends BaseMapper<UserInfo> {
    @Query("SELECT * FROM user @{and name = :name} @{and age > :age}")
    List<UserInfo> findByType(UserInfo info);
}

優(yōu)勢總結(jié)

  • 極簡主義:沒有 <if>,沒有 Wrapper,只有純粹的 SQL。
  • 直觀:看一眼就知道這段 SQL 包含哪些條件邏輯。
  • 復(fù)用性:這行 SQL 字符串可以寫在 XML 里,也可以寫在注解里,甚至寫在純血 SQL 里面。

3. 一套 API 統(tǒng)一訪問

僅僅十年前,一個(gè) MySQL 可能就承載了一個(gè)系統(tǒng)的所有數(shù)據(jù)。但現(xiàn)在的應(yīng)用架構(gòu)往往是混合的。

? MyBatis/MP 的困境:割裂

MyBatis 設(shè)計(jì)之初就是為了 RDBMS(SQL)服務(wù)的。在一個(gè)混合架構(gòu)(MySQL 存用戶,MongoDB 存日志,ES 存商品)中,代碼往往是分裂的:

// 1. MySQL (MyBatis) - 面向 Mapper
userMapper.selectById(1L);
// 2. MongoDB (Spring Data) - 面向 Repository/Template
Query query = new Query(Criteria.where("userId").is(1L));
mongoTemplate.find(query, UserLog.class);
// 3. Elasticsearch (RestHighLevelClient) - 面向 Request 構(gòu)建
SearchRequest request = new SearchRequest("goods");
request.source(new SearchSourceBuilder().query(QueryBuilders.matchQuery("name", "手機(jī)")));
client.search(request, RequestOptions.DEFAULT);

痛點(diǎn)

  • 認(rèn)知負(fù)荷高:團(tuán)隊(duì)需要掌握 3 套不同的 API 風(fēng)格(Mapper, Criteria, Builder)。
  • 維護(hù)困難:無法統(tǒng)一處理事務(wù)、日志監(jiān)控和異常體系。
  • 代碼割裂:業(yè)務(wù)邏輯中充斥著不同風(fēng)格的 DAL 代碼。

? dbVisitor 的解法:統(tǒng)一

dbVisitor 通過雙層適配器設(shè)計(jì)實(shí)現(xiàn)了 “One API Access Any DataBase”。無論是關(guān)系型數(shù)據(jù)庫還是 NoSQL,你都可以用 完全相同的 Lambda 語法 進(jìn)行操作。

同一套 API,操作所有數(shù)據(jù)源:

// 1. MySQL - 查用戶
// 生成 SQL: select * from user where id = 1
UserInfo user = template.lambdaQuery(UserInfo.class)
    .eq(UserInfo::getId, 1)
    .one();
// 2. MongoDB - 查日志
// 生成 Mondo Shell: db.user_log.find({ "user_id": 1 })
List<UserLog> logs = template.lambdaQuery(UserLog.class)
    .eq(UserLog::UserId, 1)
    .list();
// 3. Elasticsearch - 查商品
// 生成 DSL: { "query": { "term": { "name": "手機(jī)" } } }
List<Goods> goods = template.lambdaQuery(Goods.class)
    .eq(Goods::getName, "手機(jī)")
    .list();

優(yōu)勢

  • 零學(xué)習(xí)成本:只要會(huì)寫 MySQL 查詢,就會(huì)寫 ES 查詢。
  • 統(tǒng)一管控:所有的查詢(無論底層是 SQL 還是 DSL)都走統(tǒng)一的執(zhí)行鏈路,這意味著可以輕松實(shí)現(xiàn)統(tǒng)一的 SQL 耗時(shí)打印、慢查詢報(bào)警。

4. 結(jié)語:該如何選擇?

回到最初的問題:dbVisitor 和 MyBatis 你會(huì)怎么選?

  • 堅(jiān)守 MyBatis 的理由
    • 你的項(xiàng)目是單純的 RDBMS(關(guān)系型數(shù)據(jù)庫) 項(xiàng)目,且團(tuán)隊(duì)成員對 MyBatis 倒背如流。
    • 你需要極其精細(xì)的 SQL 控制能力,或者項(xiàng)目依賴了大量基于 MyBatis 的老舊插件(如特定的 PageHelper 版本)。
    • 追求絕對的穩(wěn)健,認(rèn)為“也是一種美”,不愿意嘗試新框架。
  • 擁抱 dbVisitor 的理由
    • 你的項(xiàng)目是 混合架構(gòu)(MySQL + MongoDB/ES),你受夠了在 Mapper、Repository 和各種 Client 之間精神分裂般的切換。
    • 你厭倦了 MyBatis 繁瑣的 XML <if> 標(biāo)簽,渴望更現(xiàn)代、更簡潔的動(dòng)態(tài) SQL 寫法。
    • 你需要 更高的靈活性,比如在 Service 層直接執(zhí)行 SQL,或者不寫 XML 直接用 Lambda 梭哈。
    • 你是一個(gè)追求開發(fā)效率的“實(shí)用主義者”,希望用 20% 的代碼量完成 80% 的工作。

一句話總結(jié): 如果你想要 MyBatis 的 穩(wěn),請繼續(xù)使用 MyBatis;如果你想要 MyBatis 的穩(wěn),再加上 Spring Data 的 和 Lambda 的 ,那么 dbVisitor 是你當(dāng)下最好的選擇。

到此這篇關(guān)于dbVisitor 和 MyBatis有什么區(qū)別的文章就介紹到這了,更多相關(guān)dbVisitor 和 MyBatis區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的Semaphore信號量使用方法代碼實(shí)例

    Java中的Semaphore信號量使用方法代碼實(shí)例

    這篇文章主要介紹了Java中的Semaphore信號量使用方法代碼實(shí)例,Semaphore是一種基于計(jì)數(shù)的信號量,它可以設(shè)定一個(gè)閾值,基于此,多個(gè)線程競爭獲取許可信號,做自己的申請后歸還,超過閾值后,線程申請?jiān)S可信號將會(huì)被阻塞,需要的朋友可以參考下
    2023-11-11
  • java:抽象類與模板方法模式詳解

    java:抽象類與模板方法模式詳解

    這篇文章主要介紹了Java抽象類的構(gòu)造模板模式用法,結(jié)合實(shí)例形式分析了java使用抽象類構(gòu)造模板模式相關(guān)操作技巧,需要的朋友可以參考下
    2021-09-09
  • 徹底理解Java中的ThreadLocal

    徹底理解Java中的ThreadLocal

     ThreadLocal翻譯成中文比較準(zhǔn)確的叫法應(yīng)該是:線程局部變量。使用這個(gè)工具類可以很簡潔地編寫出優(yōu)美的多線程程序。 接下來通過本文給大家介紹Java中的ThreadLocal,需要的朋友可以參考下
    2017-03-03
  • Java實(shí)現(xiàn)二分法變種的示例代碼

    Java實(shí)現(xiàn)二分法變種的示例代碼

    這篇文章主要為大家介紹了Java實(shí)現(xiàn)二分法變種的示例代碼復(fù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 詳解Spring Data JPA使用@Query注解(Using @Query)

    詳解Spring Data JPA使用@Query注解(Using @Query)

    本篇文章主要介紹了詳解Spring Data JPA使用@Query注解(Using @Query),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • springMVC如何將controller中Model數(shù)據(jù)傳遞到j(luò)sp頁面

    springMVC如何將controller中Model數(shù)據(jù)傳遞到j(luò)sp頁面

    本篇文章主要介紹了springMVC如何將controller中Model數(shù)據(jù)傳遞到j(luò)sp頁面,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • 如何用Jfinal連接多個(gè)數(shù)據(jù)庫

    如何用Jfinal連接多個(gè)數(shù)據(jù)庫

    這篇文章主要介紹了如何用Jfinal連接多個(gè)數(shù)據(jù)庫,幫助大家更好的理解和學(xué)習(xí)使用Jfinal,感興趣的朋友可以了解下
    2021-03-03
  • Spring核心方法refresh的使用解析

    Spring核心方法refresh的使用解析

    這篇文章主要介紹了Spring核心方法refresh的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Spring batch批處理框架

    Spring batch批處理框架

    本文主要介紹了Spring batch批處理框架的相關(guān)知識。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-04-04
  • Java8 forEach常用場景代碼實(shí)例

    Java8 forEach常用場景代碼實(shí)例

    這篇文章主要介紹了Java8 forEach常用場景代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評論

巨鹿县| 南投县| 江城| 金塔县| 静安区| 甘孜县| 和硕县| 麦盖提县| 彰化市| 河南省| 星子县| 长葛市| 托里县| 漳平市| 白城市| 正定县| 蒲城县| 长寿区| 宁津县| 七台河市| 涿鹿县| 瑞丽市| 高密市| 沙河市| 宣威市| 进贤县| 荃湾区| 徐水县| 达拉特旗| 花莲市| 恭城| 朝阳区| 尉氏县| 偃师市| 北京市| 张家口市| 三原县| 徐汇区| 尚义县| 新闻| 宁津县|