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

SpringBoot整合MyBatis-Flex的保姆級(jí)教程

 更新時(shí)間:2026年01月18日 10:49:09   作者:悟空碼字  
MyBatis-Flex 是一個(gè)基于 MyBatis 的增強(qiáng)框架,它提供了比傳統(tǒng) MyBatis Plus 更加強(qiáng)大和靈活的功能特性,下面我們就來(lái)看看如何在SpringBoot中整合MyBatis-Flex吧

一、MyBatis-Flex 介紹

MyBatis-Flex 是一個(gè)基于 MyBatis 的增強(qiáng)框架,它提供了比傳統(tǒng) MyBatis Plus 更加強(qiáng)大和靈活的功能特性。以下是其主要特點(diǎn):

1.核心特性

  • 輕量級(jí)設(shè)計(jì):框架非常輕量,依賴少,啟動(dòng)速度快
  • 功能強(qiáng)大:提供豐富的查詢API,支持多表關(guān)聯(lián)查詢、分頁(yè)查詢等
  • 靈活的查詢方式:支持 QueryWrapper、Lambda 表達(dá)式等多種查詢方式
  • 多數(shù)據(jù)庫(kù)支持:兼容多種主流數(shù)據(jù)庫(kù)(MySQL、PostgreSQL、Oracle等)
  • 代碼生成:內(nèi)置高效的代碼生成器

2.優(yōu)勢(shì)亮點(diǎn)

  • 無(wú)侵入性:對(duì)原有 MyBatis 幾乎無(wú)侵入,遷移成本低
  • 性能優(yōu)越:查詢性能經(jīng)過(guò)優(yōu)化,比傳統(tǒng) MyBatis 更高效
  • 注解豐富:提供豐富的注解支持,簡(jiǎn)化配置
  • 動(dòng)態(tài)SQL:強(qiáng)大的動(dòng)態(tài) SQL 構(gòu)建能力
  • 多租戶支持:內(nèi)置多租戶方案,開(kāi)箱即用

二、SpringBoot 整合 MyBatis-Flex 詳細(xì)步驟

步驟1:創(chuàng)建 SpringBoot 項(xiàng)目并添加依賴

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- MyBatis-Flex SpringBoot Starter -->
    <dependency>
        <groupId>com.mybatis-flex</groupId>
        <artifactId>mybatis-flex-spring-boot-starter</artifactId>
        <version>1.8.6</version>
    </dependency>
    
    <!-- 數(shù)據(jù)庫(kù)驅(qū)動(dòng) (以MySQL為例) -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    
    <!-- Lombok (可選) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <!-- 代碼生成器 (可選) -->
    <dependency>
        <groupId>com.mybatis-flex</groupId>
        <artifactId>mybatis-flex-codegen</artifactId>
        <version>1.8.6</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

步驟2:配置 application.yml

# application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_flex_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

mybatis-flex:
  # 配置 Mapper 掃描路徑
  mapper-locations: classpath*:/mapper/**/*Mapper.xml
  # 全局配置
  configuration:
    # 下劃線轉(zhuǎn)駝峰
    map-underscore-to-camel-case: true
    # 日志實(shí)現(xiàn)
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  # 多數(shù)據(jù)源配置(可選)
  datasource:
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/master_db
      username: root
      password: 123456
    slave:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/slave_db
      username: root
      password: 123456

步驟3:創(chuàng)建實(shí)體類

package com.example.demo.entity;

import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.Data;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

@Data
@Accessors(chain = true)
@Table("tb_user")  // 指定表名
public class User {
    
    @Id(keyType = KeyType.Auto)  // 主鍵,自動(dòng)增長(zhǎng)
    private Long id;
    
    private String username;
    
    private String email;
    
    private Integer age;
    
    private Integer status;
    
    private LocalDateTime createTime;
    
    private LocalDateTime updateTime;
    
    // 邏輯刪除注解
    @com.mybatisflex.annotation.Column(isLogicDelete = true)
    private Boolean deleted;
}

步驟4:創(chuàng)建 Mapper 接口

package com.example.demo.mapper;

import com.mybatisflex.core.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 可以在此定義自定義的查詢方法
    // 復(fù)雜的查詢建議使用 QueryWrapper 或 Db + Row
    
    /**
     * 自定義查詢方法示例
     */
    User selectByUsername(String username);
}

對(duì)應(yīng)的 XML 映射文件(如果需要):

<!-- src/main/resources/mapper/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.demo.mapper.UserMapper">
    
    <select id="selectByUsername" resultType="com.example.demo.entity.User">
        SELECT * FROM tb_user WHERE username = #{username}
    </select>
    
</mapper>

步驟5:創(chuàng)建 Service 層

package com.example.demo.service;

import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.service.IService;
import com.example.demo.entity.User;

public interface UserService extends IService<User> {
    
    User getByUsername(String username);
    
    boolean updateEmailById(Long id, String email);
}
package com.example.demo.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.service.impl.ServiceImpl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    @Override
    public User getByUsername(String username) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from(User.class)
                .where(User::getUsername).eq(username);
        return mapper.selectOneByQuery(queryWrapper);
    }
    
    @Override
    public boolean updateEmailById(Long id, String email) {
        User user = new User();
        user.setId(id);
        user.setEmail(email);
        return this.updateById(user);
    }
}

步驟6:創(chuàng)建 Controller

package com.example.demo.controller;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    /**
     * 根據(jù)ID查詢用戶
     */
    @GetMapping("/{id}")
    public User getById(@PathVariable Long id) {
        return userService.getById(id);
    }
    
    /**
     * 分頁(yè)查詢用戶
     */
    @GetMapping("/page")
    public Page<User> page(@RequestParam(defaultValue = "1") int pageNumber,
                           @RequestParam(defaultValue = "10") int pageSize) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from(User.class)
                .where(User::getAge).ge(18)
                .orderBy(User::getCreateTime, false);
        
        return userService.page(new Page<>(pageNumber, pageSize), queryWrapper);
    }
    
    /**
     * 條件查詢
     */
    @GetMapping("/list")
    public List<User> list(@RequestParam(required = false) String username,
                           @RequestParam(required = false) Integer minAge) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select()
                .from(User.class);
        
        if (username != null) {
            queryWrapper.and(User::getUsername).like(username);
        }
        
        if (minAge != null) {
            queryWrapper.and(User::getAge).ge(minAge);
        }
        
        return userService.list(queryWrapper);
    }
    
    /**
     * 新增用戶
     */
    @PostMapping
    public boolean save(@RequestBody User user) {
        return userService.save(user);
    }
    
    /**
     * 更新用戶
     */
    @PutMapping("/{id}")
    public boolean update(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        return userService.updateById(user);
    }
    
    /**
     * 刪除用戶
     */
    @DeleteMapping("/{id}")
    public boolean delete(@PathVariable Long id) {
        return userService.removeById(id);
    }
}

步驟7:使用代碼生成器(可選)

package com.example.demo;

import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;

public class CodeGenerator {
    
    public static void main(String[] args) {
        // 配置數(shù)據(jù)源
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis_flex_db");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        
        // 創(chuàng)建配置內(nèi)容
        GlobalConfig globalConfig = new GlobalConfig();
        
        // 設(shè)置根包
        globalConfig.setBasePackage("com.example.demo");
        
        // 設(shè)置表前綴和只生成哪些表
        globalConfig.setTablePrefix("tb_");
        globalConfig.setGenerateTable("tb_user", "tb_order", "tb_product");
        
        // 設(shè)置生成實(shí)體類的路徑
        globalConfig.setEntitySourceDir("src/main/java/com/example/demo/entity");
        
        // 設(shè)置生成Mapper類的路徑
        globalConfig.setMapperSourceDir("src/main/java/com/example/demo/mapper");
        
        // 設(shè)置生成Service類的路徑
        globalConfig.setServiceSourceDir("src/main/java/com/example/demo/service");
        
        // 設(shè)置生成ServiceImpl類的路徑
        globalConfig.setServiceImplSourceDir("src/main/java/com/example/demo/service/impl");
        
        // 設(shè)置生成Controller類的路徑
        globalConfig.setControllerSourceDir("src/main/java/com/example/demo/controller");
        
        // 通過(guò) datasource 和 globalConfig 創(chuàng)建代碼生成器
        Generator generator = new Generator(dataSource, globalConfig);
        
        // 生成代碼
        generator.generate();
    }
}

步驟8:高級(jí)查詢示例

package com.example.demo.service.impl;

import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class AdvancedQueryService {
    
    /**
     * 復(fù)雜條件查詢示例
     */
    public void complexQuery() {
        // 使用 QueryWrapper 構(gòu)建復(fù)雜查詢
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(User.ID, User.USERNAME, User.EMAIL)
                .from(User.class)
                .where(User.AGE.between(18, 60))
                .and(User.STATUS.eq(1))
                .and(User.USERNAME.like("張%"))
                .orderBy(User.CREATE_TIME.desc())
                .limit(10);
        
        // 使用 Db 執(zhí)行原生SQL
        List<Row> rows = Db.selectListBySql(
                "SELECT u.*, o.order_count FROM tb_user u " +
                "LEFT JOIN (SELECT user_id, COUNT(*) as order_count FROM tb_order GROUP BY user_id) o " +
                "ON u.id = o.user_id " +
                "WHERE u.status = ?", 1);
    }
    
    /**
     * 關(guān)聯(lián)查詢示例
     */
    public void joinQuery() {
        QueryWrapper query = QueryWrapper.create()
                .select()
                .from(User.class).as("u")
                .leftJoin("tb_order").as("o").on("u.id = o.user_id")
                .where("u.status = ?", 1);
    }
}

步驟9:事務(wù)管理

package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TransactionService {
    
    @Autowired
    private UserMapper userMapper;
    
    /**
     * 聲明式事務(wù)管理
     */
    @Transactional(rollbackFor = Exception.class)
    public void transactionalOperation(User user1, User user2) {
        // 插入第一個(gè)用戶
        userMapper.insert(user1);
        
        // 模擬業(yè)務(wù)邏輯
        if (user1.getAge() < 0) {
            throw new RuntimeException("年齡不能為負(fù)數(shù)");
        }
        
        // 插入第二個(gè)用戶
        userMapper.insert(user2);
    }
}

三、配置類示例

package com.example.demo.config;

import com.mybatisflex.core.audit.AuditManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class MyBatisFlexConfig {
    
    private static final Logger logger = LoggerFactory.getLogger(MyBatisFlexConfig.class);
    
    @PostConstruct
    public void init() {
        // 開(kāi)啟審計(jì)功能
        AuditManager.setAuditEnable(true);
        
        // 設(shè)置 SQL 審計(jì)收集器
        AuditManager.setMessageCollector(auditMessage -> {
            logger.info("執(zhí)行 SQL: {}", auditMessage.getFullSql());
            logger.info("執(zhí)行參數(shù): {}", auditMessage.getQueryParams());
            logger.info("執(zhí)行耗時(shí): {}ms", auditMessage.getElapsedTime());
        });
    }
}

四、詳細(xì)總結(jié)

1.整合優(yōu)勢(shì)

  • 簡(jiǎn)化開(kāi)發(fā):MyBatis-Flex 提供了豐富的 API,大大減少了樣板代碼
  • 靈活查詢:QueryWrapper 和 Lambda 表達(dá)式讓查詢條件構(gòu)建更加靈活
  • 性能優(yōu)越:框架經(jīng)過(guò)優(yōu)化,執(zhí)行效率高
  • 易于擴(kuò)展:良好的擴(kuò)展性,可以方便地添加自定義功能

2.使用建議

  • 簡(jiǎn)單CRUD:直接使用 BaseMapper 和 IService 提供的基礎(chǔ)方法
  • 復(fù)雜查詢:優(yōu)先使用 QueryWrapper,復(fù)雜的關(guān)聯(lián)查詢可使用原生 SQL
  • 分頁(yè)查詢:使用內(nèi)置的 Page 類,支持多種數(shù)據(jù)庫(kù)的分頁(yè)語(yǔ)法
  • 事務(wù)管理:使用 Spring 的 @Transactional 注解管理事務(wù)

3.注意事項(xiàng)

  • 實(shí)體類需要正確使用注解標(biāo)記主鍵、表名等
  • 多數(shù)據(jù)源配置時(shí)注意事務(wù)管理器的配置
  • 邏輯刪除字段需要在配置中指定
  • 生產(chǎn)環(huán)境建議關(guān)閉 SQL 日志輸出

4.最佳實(shí)踐

  • 使用代碼生成器提高開(kāi)發(fā)效率
  • 復(fù)雜業(yè)務(wù)邏輯在 Service 層處理
  • 合理使用緩存提升性能
  • 定期監(jiān)控 SQL 執(zhí)行效率

5.常見(jiàn)問(wèn)題解決

問(wèn)題1:字段名與數(shù)據(jù)庫(kù)列名映射不正確

解決:檢查 @Column 注解或配置 map-underscore-to-camel-case

問(wèn)題2:分頁(yè)查詢異常

解決:檢查數(shù)據(jù)庫(kù)方言配置,確保使用正確的分頁(yè)語(yǔ)法

問(wèn)題3:事務(wù)不回滾

解決:確保 @Transactional 注解正確使用,異常被正確捕獲

MyBatis-Flex 作為一個(gè)現(xiàn)代化的 MyBatis 增強(qiáng)框架,在保持 MyBatis 靈活性的同時(shí),提供了更多便捷的功能,特別適合需要復(fù)雜查詢和高性能要求的項(xiàng)目。通過(guò)合理的配置和使用,可以大大提高開(kāi)發(fā)效率和系統(tǒng)性能。

到此這篇關(guān)于SpringBoot整合MyBatis-Flex的保姆級(jí)教程的文章就介紹到這了,更多相關(guān)SpringBoot整合MyBatis-Flex內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中notify是順序喚醒還是隨機(jī)喚醒的

    Java中notify是順序喚醒還是隨機(jī)喚醒的

    這篇文章主要介紹了Java中notify是順序喚醒還是隨機(jī)喚醒的,有很多人會(huì)認(rèn)為?notify?是隨機(jī)喚醒的,但它真的是隨機(jī)喚醒的嗎?帶著疑問(wèn)一起進(jìn)入文章了解具體的內(nèi)容吧
    2022-05-05
  • 匯總java調(diào)用python方法

    匯總java調(diào)用python方法

    這篇文章主要為大家詳細(xì)介紹了java調(diào)用python的方法,文章中介紹了三種java調(diào)用python方法,感興趣的朋友可以參考一下
    2016-02-02
  • jenkins如何部署應(yīng)用到多個(gè)環(huán)境

    jenkins如何部署應(yīng)用到多個(gè)環(huán)境

    本文介紹了如何基于流水線的方式將應(yīng)用程序部署到多個(gè)環(huán)境,包括測(cè)試環(huán)境和生產(chǎn)環(huán)境,通過(guò)創(chuàng)建項(xiàng)目、設(shè)置參數(shù)、配置流水線、設(shè)置環(huán)境變量、配置Maven工具、構(gòu)建階段、部署測(cè)試環(huán)境和生產(chǎn)環(huán)境、以及清理階段,實(shí)現(xiàn)了自動(dòng)化部署流程
    2024-11-11
  • Java中對(duì)AtomicInteger和int值在多線程下遞增操作的測(cè)試

    Java中對(duì)AtomicInteger和int值在多線程下遞增操作的測(cè)試

    這篇文章主要介紹了Java中對(duì)AtomicInteger和int值在多線程下遞增操作的測(cè)試,本文得出AtomicInteger操作 與 int操作的效率大致相差在50-80倍上下的結(jié)論,需要的朋友可以參考下
    2014-09-09
  • static關(guān)鍵字有何魔法?竟讓Spring Boot搞出那么多靜態(tài)內(nèi)部類(推薦)

    static關(guān)鍵字有何魔法?竟讓Spring Boot搞出那么多靜態(tài)內(nèi)部類(推薦)

    這篇文章主要介紹了static關(guān)鍵字有何魔法?竟讓Spring Boot搞出那么多靜態(tài)內(nèi)部類,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • springboot 整合 freemarker代碼實(shí)例

    springboot 整合 freemarker代碼實(shí)例

    這篇文章主要介紹了springboot 整合 freemarker代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • ThreadPoolExecutor線程池的使用方法

    ThreadPoolExecutor線程池的使用方法

    這篇文章主要為大家詳細(xì)介紹了ThreadPoolExecutor線程池的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • springboot項(xiàng)目使用Disruptor做內(nèi)部消息隊(duì)列的實(shí)現(xiàn)

    springboot項(xiàng)目使用Disruptor做內(nèi)部消息隊(duì)列的實(shí)現(xiàn)

    本文主要介紹了springboot項(xiàng)目使用Disruptor做內(nèi)部消息隊(duì)列的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java基于redis實(shí)現(xiàn)分布式鎖代碼實(shí)例

    Java基于redis實(shí)現(xiàn)分布式鎖代碼實(shí)例

    這篇文章主要介紹了Java基于redis實(shí)現(xiàn)分布式鎖代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java解析XML的四種方式

    Java解析XML的四種方式

    本文詳細(xì)講解了Java解析XML的四種方式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12

最新評(píng)論

伽师县| 策勒县| 江川县| 岳西县| 柳林县| 酒泉市| 吴川市| 南召县| 富民县| 赫章县| 张家口市| 体育| 泗洪县| 沁阳市| 桐乡市| 洪江市| 温州市| 房产| 拜城县| 遂溪县| 故城县| 新民市| 哈巴河县| 靖宇县| 淮安市| 鹤山市| 茂名市| 金乡县| 北碚区| 蕲春县| 舟曲县| 正蓝旗| 琼结县| 镇康县| 仙居县| 顺平县| 安阳市| 师宗县| 灯塔市| 黄大仙区| 东山县|