欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java進行異常處理的9種最佳實踐

 更新時間:2025年05月25日 08:25:13   作者:風象南  
異常處理是Java編程中不可或缺的部分,但也是最容易被忽視或?qū)崿F(xiàn)不當?shù)沫h(huán)節(jié),本文總結了Java異常處理的9種最佳實踐,這些實踐來自項目開發(fā)的經(jīng)驗總結,希望能幫助大家避開常見陷阱

異常處理是Java編程中不可或缺的部分,但也是最容易被忽視或?qū)崿F(xiàn)不當?shù)沫h(huán)節(jié)。

優(yōu)秀的異常處理機制不僅能提高系統(tǒng)的健壯性,還能讓問題排查變得簡單高效。

本文總結了Java異常處理的9種最佳實踐,這些實踐來自項目開發(fā)的經(jīng)驗總結,希望能幫助你避開常見陷阱,構建更加健壯和可維護的Java應用。

一、設計合理的異常層次結構

良好的異常設計應遵循層次化和語義化原則,這樣有利于異常的分類處理和統(tǒng)一管理。

不良實踐

// 所有異常使用同一個類型,缺乏語義
public class BusinessException extends RuntimeException {
    public BusinessException(String message) {
        super(message);
    }
}

// 調(diào)用代碼
if (user == null) {
    throw new BusinessException("User not found");
} else if (user.getBalance() < amount) {
    throw new BusinessException("Insufficient balance");
}

最佳實踐

// 基礎異常類
public abstract class BaseException extends RuntimeException {
    private final String errorCode;
    
    protected BaseException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
    
    public String getErrorCode() {
        return errorCode;
    }
}

// 業(yè)務異常
public class BusinessException extends BaseException {
    public BusinessException(String errorCode, String message) {
        super(errorCode, message);
    }
}

// 用戶相關異常
public class UserException extends BusinessException {
    public static final String USER_NOT_FOUND = "USER-404";
    public static final String INSUFFICIENT_BALANCE = "USER-402";
    
    public UserException(String errorCode, String message) {
        super(errorCode, message);
    }
    
    public static UserException userNotFound(String userId) {
        return new UserException(USER_NOT_FOUND, 
            String.format("User not found with id: %s", userId));
    }
    
    public static UserException insufficientBalance(long required, long available) {
        return new UserException(INSUFFICIENT_BALANCE, 
            String.format("Insufficient balance: required %d, available %d", required, available));
    }
}

// 調(diào)用代碼
if (user == null) {
    throw UserException.userNotFound(userId);
} else if (user.getBalance() < amount) {
    throw UserException.insufficientBalance(amount, user.getBalance());
}

實施要點:

1. 創(chuàng)建一個基礎異常類,包含錯誤碼和錯誤信息

2. 按業(yè)務領域或功能模塊設計異常子類

3. 使用靜態(tài)工廠方法創(chuàng)建常見異常,增強代碼可讀性

4. 為錯誤碼定義常量,便于統(tǒng)一管理和文檔化

這種設計能讓異常信息更加標準化,有利于排查問題和系統(tǒng)監(jiān)控。

二、選擇合適的異常類型

Java的異常分為檢查型(checked)和非檢查型(unchecked),何時使用哪種類型是開發(fā)者常困惑的問題。

基本原則

1. 使用非檢查型異常(RuntimeException)的場景

  • • 程序錯誤(如空指針、數(shù)組越界)
  • • 不可恢復的系統(tǒng)錯誤
  • • 業(yè)務邏輯驗證失敗

2. 使用檢查型異常的場景

  • • 調(diào)用者必須明確處理的情況
  • • 可恢復的外部資源錯誤(如網(wǎng)絡、文件操作)
  • • API契約的一部分,要求調(diào)用者必須處理特定情況

實戰(zhàn)代碼

// 非檢查型異常:業(yè)務邏輯驗證失敗
public void transferMoney(Account from, Account to, BigDecimal amount) {
    if (amount.compareTo(BigDecimal.ZERO) <= 0) {
        throw new IllegalArgumentException("Transfer amount must be positive");
    }
    
    if (from.getBalance().compareTo(amount) < 0) {
        throw new InsufficientFundsException(
            String.format("Insufficient funds: %s available, %s required", 
                from.getBalance(), amount));
    }
    
    // 執(zhí)行轉(zhuǎn)賬邏輯
}

// 檢查型異常:外部資源操作,調(diào)用者必須處理
public void saveReport(Report report, Path destination) throws IOException {
    // 文件操作可能拋出IOException,這是合理的檢查型異常
    try (BufferedWriter writer = Files.newBufferedWriter(destination)) {
        writer.write(report.getContent());
    }
}

實踐建議:

• 在微服務架構中,API邊界通常使用非檢查型異常,簡化跨服務調(diào)用

• 在核心庫和底層框架中,重要的錯誤狀態(tài)應使用檢查型異常強制處理

• 不要僅僅為了傳遞錯誤信息而使用檢查型異常

推薦優(yōu)先使用非檢查型異常,除非確實需要強制調(diào)用者處理。

三、提供詳盡的異常信息

異常信息的質(zhì)量直接影響問題診斷的效率。一個好的異常信息應包含:錯誤上下文、失敗原因和可能的解決方案。

不良實踐

// 異常信息過于簡單,缺乏上下文
if (product == null) {
    throw new ProductException("Product not found");
}

if (product.getQuantity() < orderQuantity) {
    throw new ProductException("Insufficient stock");
}

最佳實踐

// 包含完整上下文的異常信息
if (product == null) {
    throw new ProductNotFoundException(
        String.format("Product not found with ID: %s, category: %s", 
                     productId, categoryId));
}

if (product.getQuantity() < orderQuantity) {
    throw new InsufficientStockException(
        String.format("Insufficient stock for product '%s' (ID: %s): requested %d, available %d", 
                     product.getName(), product.getId(), orderQuantity, product.getQuantity()),
        product.getId(), orderQuantity, product.getQuantity());
}

提升異常信息質(zhì)量的技巧:

1. 使用參數(shù)化消息而非硬編碼字符串

2. 包含相關的業(yè)務標識符(如ID、名稱)

3. 提供操作相關的數(shù)值(如請求數(shù)量、可用數(shù)量)

4. 在適當情況下提供解決建議

5. 保存造成異常的原始數(shù)據(jù)

在實際項目中,詳盡的異常信息能大大節(jié)約解決問題所花費的時間。

四、正確處理異常鏈,保留完整堆棧

異常鏈是保留原始錯誤信息的關鍵機制。不恰當?shù)漠惓L幚砜赡軐е轮匾畔G失,增加調(diào)試難度。

錯誤示例

// 錯誤示例1:吞噬異常
try {
    fileService.readFile(path);
} catch (IOException e) {
    // 錯誤:異常信息完全丟失
    throw new ServiceException("File processing failed");
}

// 錯誤示例2:記錄但吞噬原始異常
try {
    userService.authenticate(username, password);
} catch (AuthenticationException e) {
    // 錯誤:日志中有信息,但調(diào)用鏈中異常信息丟失
    logger.error("Authentication failed", e);
    throw new SecurityException("Invalid credentials");
}

正確處理

// 正確示例1:傳遞原始異常作為cause
try {
    fileService.readFile(path);
} catch (IOException e) {
    // 正確:保留原始異常作為cause
    throw new ServiceException("File processing failed: " + path, e);
}

// 正確示例2:包裝并重新拋出,保留原始異常信息
try {
    userService.authenticate(username, password);
} catch (AuthenticationException e) {
    logger.warn("Authentication attempt failed for user: {}", username);
    throw new SecurityException("Authentication failed for user: " + username, e);
}

// 正確示例3:補充信息后重新拋出原始異常
try {
    return jdbcTemplate.query(sql, params);
} catch (DataAccessException e) {
    // 為異常添加上下文信息,但保持原始異常類型
    throw new QueryException(
        String.format("Database query failed. SQL: %s, Parameters: %s", 
                     sql, Arrays.toString(params)), e);
}

最佳實踐要點:

1. 始終將原始異常作為cause傳遞給新異常

2. 在新異常消息中包含相關上下文信息

3. 只在能增加明確業(yè)務語義時才包裝異常

4. 考慮使用自定義異常屬性保存更多上下文

5. 避免多層包裝同一異常,導致堆棧冗余

五、避免異常處理中的常見反模式

不良的異常處理模式不僅會導致代碼質(zhì)量下降,還會引入難以察覺的bug。

常見反模式及其解決方案

1. 空catch塊

// 反模式
try {
    Files.delete(path);
} catch (IOException e) {
    // 什么都不做,錯誤被忽略
}

// 最佳實踐
try {
    Files.delete(path);
} catch (IOException e) {
    logger.warn("Failed to delete file: {}, reason: {}", path, e.getMessage(), e);
    // 如果確實可以忽略,至少解釋原因
    // 只有在確實可以安全忽略時才這樣處理
}

2. 捕獲頂層異常

// 反模式:捕獲太廣泛的異常
try {
    processOrder(order);
} catch (Exception e) {
    // 處理所有異常,包括那些不應該捕獲的異常
    sendErrorEmail("Order processing failed");
}

// 最佳實踐:只捕獲能處理的具體異常
try {
    processOrder(order);
} catch (InvalidOrderException e) {
    notifyCustomer(order, "Your order is invalid: " + e.getMessage());
} catch (InventoryException e) {
    suggestAlternatives(order);
} catch (PaymentException e) {
    retryPayment(order);
} catch (RuntimeException e) {
    // 捕獲其他未預期的運行時異常
    logger.error("Unexpected error processing order: {}", order.getId(), e);
    throw e; // 重新拋出,讓上層處理
}

3. 在finally塊中拋出異常

// 反模式:finally塊拋出異常會覆蓋try/catch塊中的異常
Connection conn = null;
try {
    conn = dataSource.getConnection();
    // 數(shù)據(jù)庫操作
} catch (SQLException e) {
    logger.error("Database error", e);
} finally {
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) {
            // 這個異常會覆蓋try塊中的異常
            throw new RuntimeException("Failed to close connection", e);
        }
    }
}

// 最佳實踐:使用try-with-resources或在finally中記錄但不拋出異常
try (Connection conn = dataSource.getConnection()) {
    // 數(shù)據(jù)庫操作
} catch (SQLException e) {
    logger.error("Database error", e);
    throw new DatabaseException("Database operation failed", e);
}

4. 日志記錄與拋出的重復

// 反模式:異常記錄后又拋出,導致重復日志
try {
    processPayment(payment);
} catch (PaymentException e) {
    logger.error("Payment failed", e);
    throw e; // 導致上層可能再次記錄同一異常
}

// 最佳實踐:在異常鏈的一處記錄
try {
    processPayment(payment);
} catch (PaymentException e) {
    // 如果要重新拋出,不要記錄,讓最終處理者記錄
    throw new OrderException("Order processing failed during payment", e);
}

// 或者記錄后轉(zhuǎn)換為不同類型
try {
    processPayment(payment);
} catch (PaymentException e) {
    logger.error("Payment processing error", e);
    // 轉(zhuǎn)換為不同類型,表示已處理并記錄
    throw new OrderFailedException(e.getMessage());
}

六、使用try-with-resources進行資源管理

資源泄漏是Java應用中常見的問題,在異常處理中尤為突出。使用try-with-resources可以有效解決這一問題。

傳統(tǒng)資源管理

// 傳統(tǒng)方式:容易出錯且冗長
FileInputStream fis = null;
BufferedReader reader = null;
try {
    fis = new FileInputStream(file);
    reader = new BufferedReader(new InputStreamReader(fis));
    String line;
    while ((line = reader.readLine()) != null) {
        // 處理每一行
    }
} catch (IOException e) {
    logger.error("Error reading file", e);
} finally {
    // 繁瑣的資源關閉邏輯
    if (reader != null) {
        try {
            reader.close();
        } catch (IOException e) {
            logger.error("Error closing reader", e);
        }
    }
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException e) {
            logger.error("Error closing file input stream", e);
        }
    }
}

使用try-with-resources

// 現(xiàn)代方式:簡潔可靠
try (BufferedReader reader = new BufferedReader(
        new InputStreamReader(new FileInputStream(file)))) {
    String line;
    while ((line = reader.readLine()) != null) {
        // 處理每一行
    }
} catch (IOException e) {
    logger.error("Error reading file", e);
    // 不需要finally塊,資源會自動關閉
}

擴展:處理多個資源

// 處理多個資源
try (Connection conn = dataSource.getConnection();
     PreparedStatement stmt = conn.prepareStatement(SQL_QUERY);
     ResultSet rs = stmt.executeQuery()) {
    
    while (rs.next()) {
        // 處理結果集
    }
} catch (SQLException e) {
    throw new DatabaseException("Query execution failed", e);
}

自定義AutoCloseable資源

// 自定義資源類,實現(xiàn)AutoCloseable接口
public class DatabaseTransaction implements AutoCloseable {
    private final Connection connection;
    private boolean committed = false;
    
    public DatabaseTransaction(DataSource dataSource) throws SQLException {
        this.connection = dataSource.getConnection();
        this.connection.setAutoCommit(false);
    }
    
    public void execute(String sql) throws SQLException {
        // 執(zhí)行SQL
    }
    
    public void commit() throws SQLException {
        connection.commit();
        committed = true;
    }
    
    @Override
    public void close() throws SQLException {
        if (!committed) {
            // 未提交的事務自動回滾
            connection.rollback();
        }
        connection.close();
    }
}

// 使用自定義AutoCloseable資源
try (DatabaseTransaction transaction = new DatabaseTransaction(dataSource)) {
    transaction.execute("INSERT INTO orders VALUES (?, ?, ?)");
    transaction.execute("UPDATE inventory SET quantity = quantity - ?");
    transaction.commit();
} catch (SQLException e) {
    // 如果發(fā)生異常,transaction會自動關閉且回滾事務
    throw new OrderException("Failed to process order", e);
}

使用try-with-resources不僅使代碼更簡潔,還能防止資源泄漏。在一個處理大量文件的系統(tǒng)中,切換到try-with-resources后,文件句柄泄漏問題完全消除,系統(tǒng)穩(wěn)定性大大提高。

七、實現(xiàn)優(yōu)雅的全局異常處理

特別是在Web應用和微服務中,全局異常處理可以集中管理異常響應,保持一致的錯誤處理策略。

Spring Boot中的全局異常處理

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
    // 處理業(yè)務異常
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
        logger.warn("Business exception: {}", ex.getMessage());
        ErrorResponse error = new ErrorResponse(
            ex.getErrorCode(),
            ex.getMessage(),
            HttpStatus.BAD_REQUEST.value()
        );
        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
    }
    
    // 處理資源不存在異常
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
        logger.warn("Resource not found: {}", ex.getMessage());
        ErrorResponse error = new ErrorResponse(
            "RESOURCE_NOT_FOUND",
            ex.getMessage(),
            HttpStatus.NOT_FOUND.value()
        );
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
    
    // 處理接口參數(shù)驗證失敗
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult()
            .getFieldErrors()
            .stream()
            .map(error -> error.getField() + ": " + error.getDefaultMessage())
            .collect(Collectors.toList());
        
        logger.warn("Validation failed: {}", errors);
        ErrorResponse error = new ErrorResponse(
            "VALIDATION_FAILED",
            "Validation failed: " + String.join(", ", errors),
            HttpStatus.BAD_REQUEST.value()
        );
        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
    }
    
    // 處理所有其他異常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
        logger.error("Unhandled exception occurred", ex);
        ErrorResponse error = new ErrorResponse(
            "INTERNAL_SERVER_ERROR",
            "An unexpected error occurred. Please contact support.",
            HttpStatus.INTERNAL_SERVER_ERROR.value()
        );
        // 生產(chǎn)環(huán)境不應該返回詳細錯誤給客戶端,但可以返回跟蹤ID
        error.setTraceId(generateTraceId());
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
    private String generateTraceId() {
        return UUID.randomUUID().toString();
    }
}

// 統(tǒng)一的錯誤響應格式
@Data
public class ErrorResponse {
    private final String errorCode;
    private final String message;
    private final int status;
    private String traceId;
    private long timestamp = System.currentTimeMillis();
    
    // 構造函數(shù)、getter和setter
}

實現(xiàn)高質(zhì)量異常處理器的關鍵點:

1. 區(qū)分不同類型的異常,給予不同的HTTP狀態(tài)碼

2. 為生產(chǎn)環(huán)境異常提供追蹤ID,方便關聯(lián)日志

3. 屏蔽敏感的技術細節(jié),返回對用戶友好的錯誤信息

4. 記錄適當?shù)漠惓H罩?,區(qū)分警告和錯誤級別

5. 為驗證錯誤提供詳細的字段錯誤信息

八、異常與日志結合的最佳實踐

日志和異常處理應協(xié)同工作,既不重復又不遺漏關鍵信息。

異常日志記錄原則

1. 選擇合適的日志級別

  • • ERROR:影響系統(tǒng)運行的嚴重問題
  • • WARN:潛在問題或業(yè)務異常
  • • INFO:正常但重要的業(yè)務事件
  • • DEBUG:用于排查問題的詳細信息

2. 在異常鏈的一處記錄:避免同一異常在多處記錄,造成日志重復

3. 包含上下文信息:不僅記錄異常本身,還要包含相關業(yè)務數(shù)據(jù)

// 不良實踐:缺乏上下文
try {
    processOrder(order);
} catch (Exception e) {
    logger.error("Order processing failed", e);
}

// 良好實踐:包含相關上下文信息
try {
    processOrder(order);
} catch (Exception e) {
    logger.error("Order processing failed. OrderID: {}, Customer: {}, Amount: {}", 
        order.getId(), order.getCustomerId(), order.getAmount(), e);
}

MDC(Mapped Diagnostic Context)提升日志上下文

// 使用MDC添加上下文信息
public void processOrderWithMDC(Order order) {
    // 放入MDC上下文
    MDC.put("orderId", order.getId());
    MDC.put("customerId", order.getCustomerId());
    
    try {
        // 此處所有日志自動包含orderId和customerId
        logger.info("Started processing order");
        validateOrder(order);
        processPayment(order);
        updateInventory(order);
        logger.info("Order processed successfully");
    } catch (PaymentException e) {
        // 異常日志自動包含MDC中的上下文信息
        logger.error("Payment processing failed", e);
        throw new OrderProcessingException("Payment failed for order", e);
    } catch (InventoryException e) {
        logger.error("Inventory update failed", e);
        throw new OrderProcessingException("Inventory update failed", e);
    } finally {
        // 清理MDC
        MDC.clear();
    }
}

結構化異常日志

對于復雜系統(tǒng),考慮使用結構化日志格式如JSON,便于日志分析系統(tǒng)處理:

// 使用標準化結構記錄異常
private void logStructuredError(Exception e, Map<String, Object> context) {
    Map<String, Object> errorInfo = new HashMap<>();
    errorInfo.put("type", e.getClass().getName());
    errorInfo.put("message", e.getMessage());
    errorInfo.put("context", context);
    errorInfo.put("timestamp", Instant.now().toString());
    errorInfo.put("thread", Thread.currentThread().getName());
    
    if (e instanceof BaseException) {
        errorInfo.put("errorCode", ((BaseException) e).getErrorCode());
    }
    
    try {
        String jsonLog = objectMapper.writeValueAsString(errorInfo);
        logger.error(jsonLog, e);
    } catch (JsonProcessingException jpe) {
        // 轉(zhuǎn)換JSON失敗,退回到簡單日志
        logger.error("Error processing order. Context: {}", context, e);
    }
}

// 使用方式
try {
    processOrder(order);
} catch (Exception e) {
    Map<String, Object> context = new HashMap<>();
    context.put("orderId", order.getId());
    context.put("amount", order.getAmount());
    context.put("customerId", order.getCustomerId());
    logStructuredError(e, context);
    throw e;
}

這種結構化日志對于ELK(Elasticsearch, Logstash, Kibana)等日志分析系統(tǒng)特別有用,能實現(xiàn)更高效的日志搜索和分析。

九、異常處理的性能考量

異常處理會影響系統(tǒng)性能。在高性能場景下,需要注意異常使用對性能的影響。

避免使用異??刂茦I(yè)務流程

異常應該用于異常情況,而不是正常的業(yè)務流程控制。

// 不良實踐:使用異??刂屏鞒?
public boolean isUsernameTaken(String username) {
    try {
        userRepository.findByUsername(username);
        return true; // 找到用戶,用戶名已存在
    } catch (UserNotFoundException e) {
        return false; // 沒找到用戶,用戶名可用
    }
}

// 良好實踐:使用返回值控制流程
public boolean isUsernameTaken(String username) {
    return userRepository.existsByUsername(username);
}

頻繁操作避免創(chuàng)建和拋出異常

異常創(chuàng)建成本高,包含調(diào)用棧捕獲,在熱點代碼中尤其要注意。

// 性能低下的實現(xiàn)
public int divide(int a, int b) {
    if (b == 0) {
        throw new ArithmeticException("Division by zero");
    }
    return a / b;
}

// 高性能實現(xiàn):在外部API邊界進行校驗
public Result<Integer> divide(int a, int b) {
    if (b == 0) {
        return Result.error("Division by zero");
    }
    return Result.success(a / b);
}

// 返回對象定義
public class Result<T> {
    private final T data;
    private final String error;
    private final boolean success;
    
    // 構造函數(shù)、getter和工廠方法
    public static <T> Result<T> success(T data) {
        return new Result<>(data, null, true);
    }
    
    public static <T> Result<T> error(String error) {
        return new Result<>(null, error, false);
    }
}

總結

異常處理不僅僅是錯誤處理,更是系統(tǒng)可靠性設計的重要組成部分

好的異常處理能夠讓系統(tǒng)在面對意外情況時保持穩(wěn)定,為用戶提供更好的體驗。

以上就是Java進行異常處理的9種最佳實踐的詳細內(nèi)容,更多關于Java異常處理的資料請關注腳本之家其它相關文章!

相關文章

  • Java調(diào)用Python的四種方法小結

    Java調(diào)用Python的四種方法小結

    在現(xiàn)代開發(fā)中,結合不同編程語言的優(yōu)勢往往能達到事半功倍的效果,本文將詳細介紹四種在Java中調(diào)用Python的方法,并推薦一種最常用且實用的方法,希望對大家有一定的幫助
    2025-05-05
  • Java并發(fā)編程之線程狀態(tài)介紹

    Java并發(fā)編程之線程狀態(tài)介紹

    這篇文章主要介紹了Java并發(fā)編程之線程狀態(tài),當線程被創(chuàng)建并啟動以后,它既不是一啟動就進入了執(zhí)行狀態(tài),也不是一直處于執(zhí)行狀態(tài),下面和小編一起進入文章了解具體的相關介紹吧
    2022-04-04
  • java基本事件處理機制解析

    java基本事件處理機制解析

    這篇文章主要介紹了java基本事件處理機制解析,?Java事件處理機制是一種用于處理用戶交互和系統(tǒng)事件的編程模型,它基于事件驅(qū)動的思想,通過監(jiān)聽和響應事件來實現(xiàn)程序的交互性和動態(tài)性,需要的朋友可以參考下
    2023-10-10
  • 簡單了解Java的默認和靜態(tài)方法

    簡單了解Java的默認和靜態(tài)方法

    這篇文章主要介紹了簡單了解Java的默認和靜態(tài)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Spring整合ehCache全過程

    Spring整合ehCache全過程

    這篇文章主要介紹了Spring整合ehCache全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 詳解Mybatis是如何把數(shù)據(jù)庫數(shù)據(jù)封裝到對象中的

    詳解Mybatis是如何把數(shù)據(jù)庫數(shù)據(jù)封裝到對象中的

    這篇文章主要介紹了Mybatis是如何把數(shù)據(jù)庫數(shù)據(jù)封裝到對象中的,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Mybatis中通用Mapper的InsertList()用法

    Mybatis中通用Mapper的InsertList()用法

    文章介紹了通用Mapper中的insertList()方法在批量新增時的使用方式,包括自增ID和自定義ID的情況,對于自增ID,使用tk.mybatis.mapper.additional.insert.InsertListMapper包下的insertList()方法;對于自定義ID,需要重寫insertList()方法
    2025-02-02
  • java程序員必須要學會的linux命令總結(推薦)

    java程序員必須要學會的linux命令總結(推薦)

    下面小編就為大家分享一篇java程序員必須要學會的linux命令總結(推薦)。具有很好的參考價值。希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • 詳解Gradle安裝并配置到IDEA的方法

    詳解Gradle安裝并配置到IDEA的方法

    這篇文章主要介紹了Gradle安裝并配置到IDEA的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • java面試常見模式問題---代理模式

    java面試常見模式問題---代理模式

    代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息
    2021-06-06

最新評論