亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

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

??Mapper XML 配置??:

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

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

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

??優(yōu)缺點??:

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

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è)計??:

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

??適配枚舉改動??:

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);
    }
}

??注冊處理器??:

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

??實體類使用??:

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 高級枚舉映射

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;
    }
}

// 實體類使用
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格式存儲枚舉屬性

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

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

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

三、枚舉映射最佳實踐方案

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

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(
                        "無效狀態(tài)碼: " + code));
        }
        return status;
    }
}

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

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);
    }
}

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

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

public enum Permission {
    READ(1), WRITE(2), DELETE(4), EXECUTE(8);
    
    private final int bitValue;
    
    // 存儲所有權(quán)限值到單個整數(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. 動態(tài)狀態(tài)機驗證

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ù)庫約束優(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'));

六、錯誤解決方案手冊

1. 序列化問題修復(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. 國際化方案

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

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

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

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

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

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

您可能感興趣的文章:

相關(guān)文章

  • IDEA集成DeepSeek的詳細(xì)教程(保姆級教程)

    IDEA集成DeepSeek的詳細(xì)教程(保姆級教程)

    DeepSeek作為一款強大的代碼搜索和分析工具,能夠幫助開發(fā)者快速定位代碼、理解項目結(jié)構(gòu)以及優(yōu)化代碼質(zhì)量,本文將詳細(xì)介紹如何在IntelliJ?IDEA中集成DeepSeek,并展示如何利用它來提升開發(fā)效率,感興趣的朋友一起看看吧
    2025-02-02
  • Spring整合Mybatis思路梳理總結(jié)

    Spring整合Mybatis思路梳理總結(jié)

    MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作,本篇文章帶你了解Spring整合Mybatis的思路
    2022-02-02
  • Java基礎(chǔ)教程之封裝與接口

    Java基礎(chǔ)教程之封裝與接口

    這篇文章主要介紹了Java基礎(chǔ)教程之封裝與接口,本文用淺顯易懂的語言講解了Java中的封裝與接口,很形象的說明了這兩個面向?qū)ο笮g(shù)語,需要的朋友可以參考下
    2014-08-08
  • java用類加載器的5種方式讀取.properties文件

    java用類加載器的5種方式讀取.properties文件

    這篇文章主要介紹了java用類加載器的5種方式讀取.properties文件,詳細(xì)的介紹了這5種方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Java實現(xiàn)的簡單數(shù)字時鐘功能示例

    Java實現(xiàn)的簡單數(shù)字時鐘功能示例

    這篇文章主要介紹了Java實現(xiàn)的簡單數(shù)字時鐘功能,涉及java日期時間及JFrame框架圖形界面操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-02-02
  • springboot如何接收復(fù)雜參數(shù)(同時接收J(rèn)SON與文件)

    springboot如何接收復(fù)雜參數(shù)(同時接收J(rèn)SON與文件)

    文章介紹了在Spring Boot中同時處理JSON和文件上傳時使用`@RequestPart`注解的方法,`@RequestPart`可以接收多種格式的參數(shù),包括JSON和文件,并且可以作為`multipart/form-data`格式中的key
    2025-02-02
  • 淺談java多線程 join方法以及優(yōu)先級方法

    淺談java多線程 join方法以及優(yōu)先級方法

    下面小編就為大家?guī)硪黄獪\談java多線程 join方法以及優(yōu)先級方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • MyBatis使用自定義TypeHandler轉(zhuǎn)換類型的實現(xiàn)方法

    MyBatis使用自定義TypeHandler轉(zhuǎn)換類型的實現(xiàn)方法

    這篇文章主要介紹了MyBatis使用自定義TypeHandler轉(zhuǎn)換類型的實現(xiàn)方法,本文介紹使用TypeHandler 實現(xiàn)日期類型的轉(zhuǎn)換,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • java 配置MyEclipse Maven環(huán)境具體實現(xiàn)步驟

    java 配置MyEclipse Maven環(huán)境具體實現(xiàn)步驟

    這篇文章主要介紹了 java 配置MyEclipse Maven環(huán)境具體實現(xiàn)步驟的相關(guān)資料,具有一定的參考價值,需要的朋友可以參考下
    2016-11-11
  • Java?KeyGenerator.generateKey的19個方法代碼示例

    Java?KeyGenerator.generateKey的19個方法代碼示例

    在下文中一共展示了KeyGenerator.generateKey方法的19個代碼示例,這些例子默認(rèn)根據(jù)受歡迎程度排序
    2021-12-12

最新評論