Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Practical Techniques for Java Business Development

Tech 1

Window Management Shortcuts

Minimize all open windows with Caps Lock + Win + m, restore minimized windows with Shift + Win + m. Use Ctrl + Shift + U to toggle the case of selected text.

MyBatis-Plus Best Practices

Prefer database-side queries over Java Stream operations for improved performance. Common usage examples:

// Single record query
BizDetails detail = lambdaQuery().eq(BizDetails::getId, recordId).one();

// Update via LambdaUpdateWrapper
LambdaUpdateWrapper<ExportLog> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(ExportLog::getUpdateTime, LocalDateTime.now())
        .eq(ExportLog::getId, targetId);
update(updateWrapper);

// Alternative update approach
TreeVO treeEntity = BeanUtil.copyProperties(sourceTree, TreeVO.class);
update(treeEntity, new LambdaUpdateWrapper<TreeVO>()
        .eq(TreeVO::getId, sourceTree.getId()));

Common Query Examples

public List<DetailVO> getDetailedData(String searchKeyword, LocalDate startDate, LocalDate endDate) {
    LambdaQueryWrapper<Detail> queryWrapper = new LambdaQueryWrapper<>();

    // Fuzzy match on multiple fields if search keyword is present
    if (StringUtils.isNotBlank(searchKeyword)) {
        queryWrapper.and(w -> w.like(Detail::getRole, searchKeyword)
                .or().like(Detail::getRevenue, searchKeyword)
                .or().like(Detail::getExpense, searchKeyword));
    }

    // Filter by start date
    if (Objects.nonNull(startDate)) {
        LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
        queryWrapper.ge(Detail::getCreateTime, startDateTime);
    }

    // Filter by end date
    if (Objects.nonNull(endDate)) {
        LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
        queryWrapper.le(Detail::getCreateTime, endDateTime);
    }

    List<Detail> detailList = list(queryWrapper);
    return BeanUtil.copyToList(detailList, DetailVO.class);
}

Note: Add the generic type marker static <T> when using generic parameters, and use and() for LIKE conditions while other conditions do not require it.

Nullable Request Parameters

Use required = false to mark request parmaeters as optional:

@RequestParam(value = "floorNumber", required = false) String searchKeyword

String and Object Null Checks

// Check null for any type: collection, object, field
ObjectUtil.isEmpty(dto.getId())

// Safe string equality check
Objects.equals(firstValue, secondValue)

// Optional null handling
String sellerId = Optional.ofNullable(response.getSellerId()).orElse(StringUtils.EMPTY);
// Equivalent traditional check
String existingId = response.getSellerId();
return existingId != null ? existingId : StringUtils.EMPTY;

Entity Fields Without DTOs

Use the @TableField(exist = false) annotation to mark entity fields that do not exist in the database table, eliminating the need to create a separate DTO for temporary fields.

Database Table Design

Recommended standard columns for audit tracking:

create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Record creation time',
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Record update time'

Tree Structure Database and Frontend Implemantation

Collecsion Fuzzy Search

public List<EquipmentVO> filterEquipmentList(List<EquipmentVO> sourceList, String wasteType, String equipmentName) {
    String trimmedWasteType = StringUtils.trimToEmpty(wasteType);
    String trimmedEquipmentName = StringUtils.trimToEmpty(equipmentName);

    // Return full list if both filters are empty
    if (StringUtils.isEmpty(trimmedWasteType) && StringUtils.isEmpty(trimmedEquipmentName)) {
        return sourceList;
    }

    // Apply fuzzy filtering via stream
    return sourceList.stream()
            .filter(item -> (StringUtils.isEmpty(trimmedWasteType) || item.getWasteType().contains(trimmedWasteType))
                    && (StringUtils.isEmpty(trimmedEquipmentName) || item.getEquipmentName().contains(trimmedEquipmentName)))
            .collect(Collectors.toList());
}

Unique ID Generation

package com.company.fishery.utils;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Generates unique IDs using current timestamp plus 4-digit incremental sequence
 */
public class UniqueIdGenerator {
    private static final AtomicInteger sequenceCounter = new AtomicInteger(0);

    public static synchronized Long generateUniqueSequenceId() {
        long timestamp = System.currentTimeMillis();
        int currentSequence = sequenceCounter.incrementAndGet();
        // Ensure sequence is 4 digits, pad with leading zeros if needed
        String sequenceStr = String.format("%04d", currentSequence);
        return Long.parseLong(timestamp + sequenceStr);
    }
}

Execution Time Calculation

long startTimestamp = System.currentTimeMillis();

// Your business logic here

long endTimestamp = System.currentTimeMillis();
long elapsedTime = endTimestamp - startTimestamp;
LOG.info("Business logic execution time: {} ms", elapsedTime);

Current Time Formatting

// Format local date to Chinese style
LocalDate currentDate = LocalDate.now();
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = currentDate.format(dateFormatter);
System.out.println(formattedDate);

// Format local datetime to standard format
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDatetime = currentDateTime.format(datetimeFormatter);

MPJ Multi-table Queries

public List<AccountBalanceVO> getBalanceList(String searchKeyword) {
    MPJLambdaWrapper<AccountBalance> queryWrapper = new MPJLambdaWrapper<>()
            .selectAll(AccountBalance.class)
            .select(FinancialRecord::getExpenseAmount)
            .select(FinancialRecord::getExpenseName)
            .select(FinancialRecord::getIncomeAmount)
            .select(FinancialRecord::getIncomeName)
            .select(FinancialRecord::getRecordTime)
            .leftJoin(FinancialRecord.class, FinancialRecord::getBalanceId, AccountBalance::getId);

    String trimmedKeyword = StringUtils.trimToEmpty(searchKeyword);
    if (StringUtils.isNotBlank(trimmedKeyword)) {
        queryWrapper.and(w -> w.like(FinancialRecord::getExpenseAmount, trimmedKeyword)
                .or().like(FinancialRecord::getExpenseName, trimmedKeyword)
                .or().like(FinancialRecord::getIncomeAmount, trimmedKeyword)
                .or().like(FinancialRecord::getIncomeName, trimmedKeyword)
                .or().like(FinancialRecord::getRecordTime, trimmedKeyword));
    }

    return baseMapper.selectJoinList(AccountBalanceVO.class, queryWrapper);
}

Transaction Management

return transactionTemplate.execute(status -> {
    configService.updateConfigValue(SysConfigConstants.SPLASH_AD_SWITCH, adSwitchStatus);
    configService.updateConfigValue(SysConfigConstants.SPLASH_AD_SHOW_DURATION, config.getShowDuration().toString());
    configService.updateConfigValue(SysConfigConstants.SPLASH_AD_REFRESH_INTERVAL, config.getRefreshInterval().toString());

    if (CollUtil.isEmpty(finalAdConfigList)) {
        adGroupService.deleteByTagAndMerchantId(AdGroupConstants.TAG_SPLASH_AD, 0);
    } else {
        adGroupService.batchSave(finalAdConfigList);
    }
    return Boolean.TRUE;
});

Remote API Calls

String jsonPayload = JsonUtil.toJsonString(requestBody);
String responseBody = HttpUtil.createPost(apiUrl)
        .header("Content-Type", "application/json;charset=UTF-8")
        .body(jsonPayload)
        .timeout(20000)
        .execute()
        .body();

Database Stored String to Frontend JSON Field

// Non-database entity field for JSON list
@TableField(exist = false)
private List<String> securityLevelList;

// Read from database and convert to list
String jsonStr = entity.getSecurityLevel().replace("'", "\"");
List<String> levels = JSON.parseArray(jsonStr, String.class);
entity.setSecurityLevelList(levels);

// Save list to database as quoted string
metadata.setSecurityLevel(JSON.toJSONString(metadata.getSecurityLevelList()).replace("\"", "'"));

// Frontend request example
"securityLevelList": ["Public", "Internal", "Sensitive", "Confidential", "Top Secret"]

Expired Token Refresh and Remote Login

/**
 * Refresh expired token automatically
 */
protected String executeWithTokenRetry(HttpRequest originalRequest) {
    try (HttpResponse firstResponse = originalRequest.execute()) {
        String responseBody = firstResponse.body();
        try {
            JsonNode responseJson = JsonUtil.parseToJsonNode(responseBody);
            if (responseJson.get("code") != null) {
                // Re-login to get new token
                loginToFastGpt();
                // Update request header with new token
                originalRequest.header("Authorization", "Bearer " + getCurrentToken());

                // Retry the original request
                try (HttpResponse retryResponse = originalRequest.execute()) {
                    return retryResponse.body();
                } catch (Exception retryEx) {
                    LOG.debug("Retry request failed", retryEx);
                }
            }
            return responseBody;
        } catch (JsonProcessingException jsonEx) {
            LOG.debug("Failed to parse response body: {}", responseBody, jsonEx);
        }
    } catch (Exception requestEx) {
        LOG.debug("Initial request failed", requestEx);
    }
    return "{}";
}

/**
 * Login to FastGPT to retrieve access token
 */
private void loginToFastGpt() {
    FastGptLoginRequest loginRequest = new FastGptLoginRequest();
    loginRequest.setUsername(fastGptConfig.getAccount());
    loginRequest.setPassword(DigestUtil.sha256Hex(fastGptConfig.getPassword()));

    String loginJson = JsonUtil.toJsonString(loginRequest);
    String loginApi = fastGptConfig.getHost() + fastGptConfig.getLoginEndpoint();
    HttpResponse loginResponse = HttpUtil.createPost(loginApi)
            .header("Content-Type", "application/json")
            .body(loginJson)
            .execute();

    JsonNode loginJsonNode = JsonUtil.parseToJsonNode(loginResponse.body());
    JsonNode loginData = loginJsonNode.get("data");
    String newToken = loginData.get("token").asText();
    setCurrentToken(newToken);
}

private String currentToken;

public String getCurrentToken() {
    if (StringUtils.isEmpty(currentToken)) {
        loginToFastGpt();
    }
    return currentToken;
}

public void setCurrentToken(String token) {
    this.currentToken = token;
}

Recommended Development Plugins

  • Show Comment: Display inline comment previews for easier code reading
  • Rainbow Brackets: Colorize matching brackets to improve code readability, use Ctrl+Right Click or Alt+Right Click to select code blocks
  • Find interface implementations via the IDE's View menu
  • Configure fallback font: Go to Settings > Appearance & Behavior > Appearance > Font > Fallback font and set to SimHei for better Chinese character rendering

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.