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

MyBatis?枚舉映射的實(shí)現(xiàn)示例

 更新時(shí)間:2025年06月25日 10:52:46   作者:比特森林探險(xiǎn)記  
本文主要介紹了MyBatis?枚舉映射的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、MyBatis 枚舉映射四大實(shí)現(xiàn)方案

1. 基礎(chǔ)序數(shù)映射(EnumTypeHandler)

// Java 枚舉類
public enum OrderStatus {
    NEW, PAID, DELIVERED, CANCELLED;
}

// MyBatis實(shí)體類映射
public class Order {
    private OrderStatus status;
    // getters/setters
}

??Mapper XML 配置??:

<resultMap id="orderResultMap" type="Order">
    <result property="status" column="status"/>
</resultMap>

??MySQL 表設(shè)計(jì)??:

CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    status TINYINT COMMENT '0-新訂單,1-已支付,2-已發(fā)貨,3-已取消'
);

??優(yōu)缺點(diǎn)??:

  • ? 零配置自動(dòng)生效
  • ?? 無(wú)法修改枚舉順序
  • ?? 數(shù)據(jù)庫(kù)可讀性差

2. 枚舉名稱映射(EnumOrdinalTypeHandler)

// MyBatis 配置文件
<typeHandlers>
    <typeHandler handler="org.apache.ibatis.type.EnumTypeHandler" 
                 javaType="com.example.OrderStatus"/>
</typeHandlers>

// 或全局配置
<settings>
    <setting name="defaultEnumTypeHandler" 
             value="org.apache.ibatis.type.EnumTypeHandler"/>
</settings>

??表設(shè)計(jì)??:

ALTER TABLE orders 
MODIFY COLUMN status VARCHAR(20) COMMENT '訂單狀態(tài)';

??適配枚舉改動(dòng)??:

public enum OrderStatus {
    NEW("新訂單"),
    PAID("已支付"),
    DELIVERED("已發(fā)貨"),
    CANCELLED("已取消");
    
    private final String desc;
    
    OrderStatus(String desc) {
        this.desc = desc;
    }
}

3. 自定義類型處理器(TypeHandler)

3.1 基于字符串的轉(zhuǎn)換

@MappedTypes(OrderStatus.class)
public class OrderStatusHandler extends BaseTypeHandler<OrderStatus> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, 
                                  OrderStatus status, JdbcType jdbcType) {
        ps.setString(i, status.name());
    }

    @Override
    public OrderStatus getNullableResult(ResultSet rs, String columnName) {
        String code = rs.getString(columnName);
        return OrderStatus.valueOf(code);
    }
    
    // 其他getNullableResult方法...
}

3.2 基于編碼的轉(zhuǎn)換(推薦)

@MappedTypes(UserType.class)
public class UserTypeHandler extends BaseTypeHandler<UserType> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, 
                                  UserType userType, JdbcType jdbcType) {
        ps.setString(i, userType.getCode());
    }

    @Override
    public UserType getNullableResult(ResultSet rs, String columnName) {
        String code = rs.getString(columnName);
        return UserType.fromCode(code);
    }
}

??注冊(cè)處理器??:

<typeHandlers>
    <typeHandler handler="com.example.handler.UserTypeHandler"/>
</typeHandlers>

??實(shí)體類使用??:

public class User {
    @TableField(typeHandler = UserTypeHandler.class)
    private UserType type;
}

4. 枚舉值關(guān)聯(lián)表方案

CREATE TABLE user_types (
    id TINYINT PRIMARY KEY AUTO_INCREMENT,
    code CHAR(2) UNIQUE NOT NULL,
    name VARCHAR(20) NOT NULL
);

INSERT INTO user_types (code, name) VALUES
('A', '管理員'),
('E', '編輯'),
('U', '普通用戶');

??Mapper XML 查詢??:

<resultMap id="userResultMap" type="User">
    <result property="id" column="id"/>
    <association property="type" column="type_code" 
                select="selectUserTypeByCode"/>
</resultMap>

<select id="selectUserTypeByCode" resultType="UserType">
    SELECT code, name AS description
    FROM user_types
    WHERE code = #[code]
</select>

二、MyBatis-Plus 高級(jí)枚舉映射

1. 內(nèi)置枚舉處理器

public enum ProductStatus implements IEnum<Integer> {
    DRAFT(0), PUBLISHED(1), ARCHIVED(2);
    
    private final int value;
    
    ProductStatus(int value) {
        this.value = value;
    }
    
    @Override
    public Integer getValue() {
        return this.value;
    }
}

// 實(shí)體類使用
public class Product {
    private ProductStatus status;
}

??全局配置(application.yml)??:

mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

2. 字段注解映射

public class Product {
    @TableField(value = "status", 
               typeHandler = ProductStatusHandler.class)
    private ProductStatus status;
}

3. JSON格式存儲(chǔ)枚舉屬性

public class Order {
    @TableField(typeHandler = JsonTypeHandler.class)
    private Map<OrderStatus, Integer> statusStatistics;
}

??JSON存儲(chǔ)結(jié)構(gòu)??:

{
  "NEW": 10,
  "PAID": 5,
  "DELIVERED": 3
}

三、枚舉映射最佳實(shí)踐方案

1. 防御式枚舉設(shè)計(jì)

public enum OrderStatus {
    NEW("N"), PAID("P"), DELIVERED("D"), CANCELLED("C");
    
    private final String code;
    private static final Map<String, OrderStatus> CODE_MAP = new HashMap<>();
    
    static {
        for (OrderStatus status : values()) {
            CODE_MAP.put(status.code, status);
        }
    }
    
    public static OrderStatus fromCode(String code) {
        OrderStatus status = CODE_MAP.get(code);
        if (status == null) {
            if (code == null) return null;
            String cleanCode = code.trim().toUpperCase();
            return Optional.ofNullable(CODE_MAP.get(cleanCode))
                    .orElseThrow(() -> new IllegalArgumentException(
                        "無(wú)效狀態(tài)碼: " + code));
        }
        return status;
    }
}

2. 枚舉基類設(shè)計(jì)

public interface EnumCode {
    String getCode();
    String getDescription();
}

public abstract class BaseEnumHandler<E extends Enum<E> & EnumCode> 
        extends BaseTypeHandler<E> {
        
    private final Class<E> type;
    private final Map<String, E> enumMap;
    
    public BaseEnumHandler(Class<E> type) {
        this.type = type;
        this.enumMap = Arrays.stream(type.getEnumConstants())
                .collect(Collectors.toMap(EnumCode::getCode, e -> e));
    }
    
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, 
                                  E parameter, JdbcType jdbcType) {
        ps.setString(i, parameter.getCode());
    }
    
    @Override
    public E getNullableResult(ResultSet rs, String columnName) {
        String code = rs.getString(columnName);
        return code == null ? null : enumMap.get(code);
    }
}

四、實(shí)戰(zhàn)應(yīng)用場(chǎng)景

1. 多狀態(tài)組合(BIT存儲(chǔ))

public enum Permission {
    READ(1), WRITE(2), DELETE(4), EXECUTE(8);
    
    private final int bitValue;
    
    // 存儲(chǔ)所有權(quán)限值到單個(gè)整數(shù)
    public static int encode(Set<Permission> permissions) {
        return permissions.stream()
                .mapToInt(p -> p.bitValue)
                .sum();
    }
    
    public static Set<Permission> decode(int value) {
        return Arrays.stream(values())
                .filter(p -> (value & p.bitValue) != 0)
                .collect(Collectors.toSet());
    }
}

// MyBatis類型處理器
public class PermissionSetHandler extends BaseTypeHandler<Set<Permission>> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, 
                                  Set<Permission> perms, JdbcType jdbcType) {
        ps.setInt(i, Permission.encode(perms));
    }
    
    @Override
    public Set<Permission> getNullableResult(ResultSet rs, String columnName) {
        int value = rs.getInt(columnName);
        return rs.wasNull() ? Collections.emptySet() : Permission.decode(value);
    }
}

2. 動(dòng)態(tài)狀態(tài)機(jī)驗(yàn)證

public class OrderService {
    @Transactional
    public void updateOrderStatus(Long orderId, OrderStatus newStatus) {
        Order order = orderMapper.selectById(orderId);
        OrderStatus oldStatus = order.getStatus();
        
        if (!oldStatus.isAllowedTransition(newStatus)) {
            throw new IllegalStateException("狀態(tài)轉(zhuǎn)換非法: " + 
                   oldStatus + " -> " + newStatus);
        }
        
        order.setStatus(newStatus);
        orderMapper.updateById(order);
    }
}

// 枚舉中定義狀態(tài)轉(zhuǎn)移規(guī)則
public enum OrderStatus {
    NEW {
        @Override
        public boolean isAllowedTransition(OrderStatus newStatus) {
            return newStatus == PAID || newStatus == CANCELLED;
        }
    },
    // 其他狀態(tài)定義...
}

五、性能優(yōu)化技巧

??靜態(tài)映射緩存??:

public abstract class CachedEnumHandler<E extends Enum<E> & EnumCode> 
        extends BaseTypeHandler<E> {
    
    private final Map<String, E> codeEnumMap;
    private final Map<E, String> enumCodeMap;
    
    public CachedEnumHandler(Class<E> enumClass) {
        E[] enums = enumClass.getEnumConstants();
        codeEnumMap = Arrays.stream(enums)
                .collect(Collectors.toMap(EnumCode::getCode, e -> e));
        
        enumCodeMap = Arrays.stream(enums)
                .collect(Collectors.toMap(e -> e, EnumCode::getCode));
    }
}

??批量處理優(yōu)化??:

@Mapper
public interface BatchMapper {
    @Insert("<script>" +
            "INSERT INTO users (type, name) VALUES " +
            "<foreach item='item' collection='list' separator=','>" +
            "(#{item.type, typeHandler=com.example.UserTypeHandler}, #{item.name})" +
            "</foreach>" +
            "</script>")
    int batchInsertUsers(@Param("list") List<User> users);
}

??數(shù)據(jù)庫(kù)約束優(yōu)化??:

-- MySQL ENUM 類型約束
status ENUM('NEW','PAID','DELIVERED','CANCELLED') NOT NULL DEFAULT 'NEW'
COMMENT '訂單狀態(tài)'

-- PostgreSQL檢查約束
ALTER TABLE orders
ADD CONSTRAINT status_check 
CHECK (status IN ('NEW', 'PAID', 'DELIVERED', 'CANCELLED'));

六、錯(cuò)誤解決方案手冊(cè)

1. 序列化問(wèn)題修復(fù)

// 添加枚舉序列化配置
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum OrderStatus implements EnumCode {
    // ...
}

// 或自定義序列化器
public class EnumCodeSerializer extends StdSerializer<EnumCode> {
    public EnumCodeSerializer() {
        super(EnumCode.class);
    }
    
    @Override
    public void serialize(EnumCode value, JsonGenerator gen, 
                        SerializerProvider provider) {
        gen.writeStartObject();
        gen.writeStringField("code", value.getCode());
        gen.writeStringField("description", value.getDescription());
        gen.writeEndObject();
    }
}

2. 國(guó)際化方案

public interface LocalizedEnum {
    String getCode();
    
    default String getMessage(Locale locale) {
        ResourceBundle bundle = ResourceBundle.getBundle(
            "enum_messages", locale);
        return bundle.getString(this.getClass().getSimpleName() + "." + getCode());
    }
}

// 多語(yǔ)言資源文件
// en_US.properties
UserType.A=Administrator
UserType.E=Editor
UserType.U=User

// zh_CN.properties
UserType.A=管理員
UserType.E=編輯
UserType.U=普通用戶

總結(jié):MyBatis枚舉映射決策樹

graph TD
    A[需要映射枚舉] --> B{是否簡(jiǎn)單狀態(tài)值?}
    B --> |是| C{是否確定永不修改順序?}
    C --> |是| D[使用EnumTypeHandler默認(rèn)序數(shù)映射]
    C --> |否| E[使用EnumOrdinalTypeHandler名稱映射]
    B --> |否| F{是否需要業(yè)務(wù)編碼?}
    F --> |是| G[自定義TypeHandler+編碼設(shè)計(jì)]
    F --> |否| H{是否多語(yǔ)言/復(fù)雜屬性?}
    H --> |是| I[關(guān)聯(lián)表映射方案]
    H --> |否| J[直接使用MyBatis-Plus枚舉方案]

??企業(yè)級(jí)應(yīng)用建議??:

  1. 選擇??自定義編碼映射??作為默認(rèn)方案
  2. 對(duì)性能敏感的常量枚舉使用??序數(shù)映射??
  3. 需要多語(yǔ)言支持的使用??關(guān)聯(lián)表映射??
  4. 組合狀態(tài)使用??BIT存儲(chǔ)+解碼方案??

遵循這些模式,可構(gòu)建出健壯且易維護(hù)的枚舉持久化層,完美平衡數(shù)據(jù)庫(kù)高效存儲(chǔ)與業(yè)務(wù)代碼的可讀性需求。

到此這篇關(guān)于MyBatis 枚舉映射的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)MyBatis 枚舉映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Kotlin委托機(jī)制使用方式和原理解析

    Kotlin委托機(jī)制使用方式和原理解析

    委托類(代理類)持有真實(shí)類的對(duì)象,然后委托類(代理類)調(diào)用真實(shí)類的同名方法,最終真正實(shí)現(xiàn)的是方法的是真實(shí)類,這其實(shí)就是代理模式,下面通過(guò)本文給大家介紹Kotlin委托機(jī)制使用方式和原理解析,感興趣的朋友一起看看吧
    2025-06-06
  • Java?CompletableFuture實(shí)現(xiàn)多線程異步編排

    Java?CompletableFuture實(shí)現(xiàn)多線程異步編排

    這篇文章主要為大家介紹了Java?CompletableFuture實(shí)現(xiàn)多線程異步編排,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • JAVA利用泛型返回類型不同的對(duì)象方法

    JAVA利用泛型返回類型不同的對(duì)象方法

    下面小編就為大家?guī)?lái)一篇JAVA利用泛型返回類型不同的對(duì)象方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • Java中的Semaphore如何使用

    Java中的Semaphore如何使用

    Semaphore實(shí)際上是一種共享鎖,因?yàn)樗试S多個(gè)線程并發(fā)獲取共享的資源,在Semaphore對(duì)象創(chuàng)建時(shí)必須設(shè)置可用令牌的初始數(shù)量permits,用于控制并發(fā)時(shí)同時(shí)獲取資源權(quán)限的線程數(shù)量,這篇文章主要介紹了Java中的Semaphore如何使用,需要的朋友可以參考下
    2022-06-06
  • java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間問(wèn)題解決

    java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間問(wèn)題解決

    這篇文章主要介紹了java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間,本文給大家分享三種解決方法,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 淺談idea live template高級(jí)知識(shí)_進(jìn)階(給方法,類,js方法添加注釋)

    淺談idea live template高級(jí)知識(shí)_進(jìn)階(給方法,類,js方法添加注釋)

    下面小編就為大家?guī)?lái)一篇淺談idea live template高級(jí)知識(shí)_進(jìn)階(給方法,類,js方法添加注釋)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Spring Retry重試框架的使用講解

    Spring Retry重試框架的使用講解

    重試的使用場(chǎng)景比較多,比如調(diào)用遠(yuǎn)程服務(wù)時(shí),由于網(wǎng)絡(luò)或者服務(wù)端響應(yīng)慢導(dǎo)致調(diào)用超時(shí),此時(shí)可以多重試幾次。用定時(shí)任務(wù)也可以實(shí)現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個(gè)注解搞定所有,感興趣的可以了解一下
    2023-01-01
  • Java 中synchronize函數(shù)的實(shí)例詳解

    Java 中synchronize函數(shù)的實(shí)例詳解

    這篇文章主要介紹了Java 中synchronize函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家理解使用synchronize函數(shù)的使用方法,需要的朋友可以參考下
    2017-09-09
  • Java Swing中的表格(JTable)和樹(JTree)組件使用實(shí)例

    Java Swing中的表格(JTable)和樹(JTree)組件使用實(shí)例

    這篇文章主要介紹了Java Swing中的表格(JTable)和樹(JTree)組件使用實(shí)例,本文同時(shí)講解了表格和樹的基本概念、常用方法、代碼實(shí)例,需要的朋友可以參考下
    2014-10-10
  • MyEclipse如何將項(xiàng)目的開發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致

    MyEclipse如何將項(xiàng)目的開發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致

    我們使用MyEclipse開發(fā)Java項(xiàng)目開發(fā)中,偶爾會(huì)遇到因項(xiàng)目開發(fā)環(huán)境不協(xié)調(diào),導(dǎo)致這樣那樣的問(wèn)題,在這里以把所有環(huán)境調(diào)整為JDK1.6 為例,給大家詳細(xì)介紹MyEclipse如何將項(xiàng)目的開發(fā)環(huán)境與服務(wù)器的JDK 版本保持一致,需要的朋友參考下吧
    2024-04-04

最新評(píng)論

建宁县| 大渡口区| 高青县| 库伦旗| 赣榆县| 和田市| 堆龙德庆县| 中江县| 大姚县| 左云县| 达州市| 新邵县| 定安县| 晋江市| 开原市| 长海县| 乌恰县| 凌源市| 正宁县| 正阳县| 望都县| 小金县| 丰镇市| 岳池县| 二连浩特市| 高安市| 山东省| 双辽市| 丰镇市| 武穴市| 海林市| 泊头市| 桦南县| 八宿县| 博客| 永兴县| 大厂| 贞丰县| 体育| 砀山县| 五家渠市|