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

一文帶你輕松掌握EasyExcel的使用技巧

 更新時間:2023年06月13日 08:28:11   作者:Cosolar  
EasyExcel是一個基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具,這篇文章就來帶大家深入了解EasyExcel的使用技巧,需要的可以參考一下

作為一個經(jīng)常進(jìn)行數(shù)據(jù)分析的后端人員,免不了面對各種報表,且在日常的工作中,經(jīng)常需要處理大量的數(shù)據(jù),并進(jìn)行各種復(fù)雜的計算和分析。而Excel作為一個重要的工具,在數(shù)據(jù)處理與分析上也起到了至關(guān)重要的作用。但是,Excel的操作繁瑣、效率低下等問題也制約著我們的工作效率。為了解決這個問題,我們可以使用EasyExcel這個優(yōu)秀的Java類庫,來優(yōu)化Excel數(shù)據(jù)的讀寫,并提高我們的工作效率。在本文中,我將向大家介紹如何使用EasyExcel的高效技巧,從而更好地搞定Excel繁瑣操作。

一、EasyExcel簡介

EasyExcel是一個基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具。

他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能。

EasyExcel是一個基于POI封裝的Java類庫,它能夠?qū)xcel文件進(jìn)行讀寫操作。EasyExcel簡單易用,性能優(yōu)異,并且支持大量的Excel操作。無論是簡單的數(shù)據(jù)導(dǎo)入還是復(fù)雜的數(shù)據(jù)處理和導(dǎo)出,EasyExcel都能夠輕松實現(xiàn)。同時,EasyExcel也支持多種數(shù)據(jù)格式,包括Excel、CSV、TSV等。EasyExcel底層使用反射實現(xiàn),因此也支持泛型。EasyExcel已被廣泛應(yīng)用于各種項目中,成為Java開發(fā)者優(yōu)化Excel操作的首選庫之一。

16M內(nèi)存23秒讀取75M(46W行25列)的Excel(3.2.1+版本)

二、EasyExcel的高效技巧

1. 讀取Excel文件

在日常工作中,讀取Excel文件是我們經(jīng)常會遇到的需求之一。EasyExcel提供了多種讀取Excel文件的方式,包括讀取指定Sheet、讀取指定列等。下面是一個簡單的代碼示例:

//讀取指定Sheet
List<YourModelName> list = EasyExcel.read(fileName)
.sheet(sheetNo)
.head(YourModelName.class)
.doReadSync();
//讀取指定列
List<Object> list = EasyExcel.read(fileName)
.sheet(sheetNo)
.headRow(rowNo)
.readRowFilter(new ReadRowFilter() {
    @Override
    public boolean doFilter(List<Object> list) {
        if (list.get(0).equals("某一列的值")) {
            return true;
        }
        return false;
    }
})
.doReadSync();

2. 寫入Excel文件

除了讀取Excel文件外,我們在實際工作中也需要頻繁地向Excel文件中寫入數(shù)據(jù)。EasyExcel提供了多種寫入Excel文件的方式,包括向指定Sheet寫入數(shù)據(jù)、向指定行寫入數(shù)據(jù)、動態(tài)合并單元格等。下面是一個簡單的代碼示例:

//向指定Sheet寫入數(shù)據(jù)
ExcelWriter excelWriter = null;
try {
    excelWriter = EasyExcel.write(fileName, YourModelName.class).build();
    WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo).build();
    excelWriter.write(dataList, writeSheet);
} finally {
    if (excelWriter != null) {
        excelWriter.finish();
    }
}
//向指定行寫入數(shù)據(jù)
ExcelWriter excelWriter = null;
try {
    excelWriter = EasyExcel.write(fileName, YourModelName.class).build();
    WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo).build();
    excelWriter.write(dataList, writeSheet, new WriteTable()) .relativeHeadRowIndex(rowNo) .doWrite();
} finally {
    if (excelWriter != null) {
        excelWriter.finish();
    }
}

3. 填充Excel

在實際工作中,我們也經(jīng)常需要對Excel文件進(jìn)行填充。EasyExcel提供了多種填充Excel的方式,包括對象填充、自定義填充等。下面是一個簡單的代碼示例:

//對象填充
List<YourModelName> dataList = getDataList();
OutputStream outputStream = new FileOutputStream(fileName);
EasyExcel.write(outputStream, YourModelName.class)
    .sheet(sheetNo)
    .doWrite(dataList);
outputStream.close();
//自定義填充
List<Object> headList = getHeadList();
List<List<Object>> dataList = getDataList();
ExcelWriter excelWriter = null;
try {
    excelWriter = EasyExcel.write(fileName).build();
    WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo).build();
    FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).build();
    excelWriter.fill(headList, fillConfig, writeSheet);
    excelWriter.fill(dataList, fillConfig, writeSheet);
} finally {
    if (excelWriter != null) {
        excelWriter.finish();
    }
}

4. 注意事項

在使用EasyExcel進(jìn)行Excel操作時,我們也需要注意一些細(xì)節(jié)問題。下面是一些需要注意的事項:

EasyExcel默認(rèn)對讀取到的單元格內(nèi)容進(jìn)行trim操作,因此如果需要保留前后空格需要手動設(shè)置。

//禁止EasyExcel對單元格內(nèi)容進(jìn)行trim操作
Object value = cell.getStringCellValue();
cell.setCellValue(new HSSFRichTextString(value.toString()));

如果需要讀取大量數(shù)據(jù),可以使用異步讀取的方式,提高讀取效率。

//異步讀取
EasyExcel.read(fileName, YourModelName.class, new ReadListener<YourModelName>() {
    // 重寫方法
}).sheet().doRead();

5. 內(nèi)部核心源碼剖析

EasyExcel的底層代碼實現(xiàn)是基于POI實現(xiàn)的,在POI的基礎(chǔ)上又進(jìn)一步進(jìn)行了封裝。具體來說,EasyExcel是通過反射來實現(xiàn)Excel文件的讀寫操作的,它利用了Java的泛型機(jī)制、注解等來實現(xiàn)高效簡潔的Excel操作。EasyExcel底層的實現(xiàn)思路比較簡單,我們可以通過閱讀其源碼來更好地理解其實現(xiàn)原理,從而更好地應(yīng)用EasyExcel進(jìn)行Excel數(shù)據(jù)的讀寫操作。

EasyExcel的底層代碼實現(xiàn)主要基于Apache POI(Poor Obfuscation Implementation)和Java反射機(jī)制,其中Apache POI是一個支持Microsoft Office格式的Java類庫,可以實現(xiàn)對Excel、Word、PowerPoint等文檔格式的讀寫操作。EasyExcel利用了POI提供的接口來讀寫Excel文件,并在此基礎(chǔ)上進(jìn)行了封裝和優(yōu)化,以提高讀寫效率。

EasyExcel的數(shù)據(jù)讀取主要涉及以下步驟:

  • 創(chuàng)建Workbook對象,打開Excel文件,獲取Sheet對象;
  • 根據(jù)Sheet對象獲取行和列對象,從而遍歷Excel文件中的所有數(shù)據(jù)單元格;
  • 通過反射機(jī)制將數(shù)據(jù)單元格中的值賦值給Java對象中的屬性,最終得到完整的Java對象;
  • 將Java對象添加到List集合中并返回。

EasyExcel的數(shù)據(jù)寫入主要涉及以下步驟:

  • 創(chuàng)建Workbook對象,創(chuàng)建Sheet對象;
  • 遍歷要寫入的Java對象集合,將每個屬性值寫入Excel文件對應(yīng)的單元格中;
  • 加鎖操作,將數(shù)據(jù)持久化到磁盤中。

在實際代碼實現(xiàn)過程中,EasyExcel還采用了一些技術(shù)手段來提高性能和易用性:

  • 使用線程池技術(shù)并發(fā)讀寫,多線程帶來了更高的并發(fā)度,提高了讀寫效率。
  • 緩存讀取數(shù)據(jù),將讀取到的數(shù)據(jù)先緩存起來,再進(jìn)行批量處理,大大提高了數(shù)據(jù)讀取效率。
  • 使用緩存技術(shù),緩存Workbook、Sheet等對象,避免重復(fù)創(chuàng)建和銷毀對象,從而提高運行效率。
  • 利用Java的泛型機(jī)制和注解技術(shù)進(jìn)行簡潔的編程實現(xiàn),減少了代碼的冗余度,使代碼更加易于維護(hù)和擴(kuò)展。

EasyExcel的底層實現(xiàn)離不開Apache POI和Java反射機(jī)制,通過這些技術(shù)的應(yīng)用,EasyExcel實現(xiàn)了對Excel文件的高效讀寫操作。

EasyExcel的核心源碼實現(xiàn)主要涉及到以下幾個方面:

1.使用POI進(jìn)行Excel文件的讀取和寫入,POI提供了SXSSF等優(yōu)化機(jī)制來提高讀寫效率。

2.采用反射機(jī)制自動將Excel中的數(shù)據(jù)映射為Java對象,并進(jìn)行類型轉(zhuǎn)換等操作。

3.使用注解來為Java對象中的屬性和Excel中的表頭進(jìn)行映射,例如@ExcelProperty注解用于標(biāo)記Java對象中的屬性是Excel中的第幾列。

4.使用緩存技術(shù)對Workbook、Sheet等對象進(jìn)行緩存,避免重復(fù)創(chuàng)建和銷毀對象,提高運行效率。

下面我們來具體看一下EasyExcel源碼中的注解部分:

1.@ExcelProperty注解

@ExcelProperty注解用于標(biāo)記Java對象中的屬性是Excel中的第幾列。該注解包含三個屬性:index、value和converter。

  • index屬性表示Java對象中的屬性在Excel中對應(yīng)的列的索引,默認(rèn)值為-1,表示自動匹配。如果該值設(shè)置為2,則表示該屬性與Excel中第3列對應(yīng)。
  • value屬性表示Excel中該列的表頭名稱。如果設(shè)置了該值,則Excel中該列的表頭名稱為value的值;如果未設(shè)置,則默認(rèn)為該屬性的名稱或字段名稱。
  • converter屬性表示數(shù)據(jù)類型轉(zhuǎn)換器,可將Excel文件中的數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換。例如,當(dāng)Excel中的數(shù)據(jù)為字符串時可以通過設(shè)置converter屬性將其轉(zhuǎn)換為指定的數(shù)據(jù)類型。

2.@ExcelIgnore注解

@ExcelIgnore注解用于標(biāo)記Java對象中不需要映射為Excel中的列的屬性。使用該注解后,EasyExcel將自動忽略該屬性,不對其進(jìn)行映射。

3.@ExcelPropertyRange注解

@ExcelPropertyRange注解用于標(biāo)記Excel文件中某個列的取值范圍。該注解包含兩個屬性:min和max。如果Excel文件中該列的取值范圍不符合要求,則EasyExcel會拋出異常。

4.@ExcelHeadRowNumber注解

@ExcelHeadRowNumber注解用于標(biāo)記Excel文件中表頭所在的行號,默認(rèn)為0,即第一行。如果設(shè)置為1,則表示表頭在第二行。使用該注解可以靈活地配置表頭所在的位置。

EasyExcel的主要核心源碼涉及到數(shù)據(jù)讀取和寫入兩個方面,下面將分別進(jìn)行詳細(xì)的代碼展示如下。

1. 數(shù)據(jù)讀取

(1) ExcelReader類

首先來看ExcelReader類,它是EasyExcel中的核心類之一,用于讀取Excel文件中的數(shù)據(jù)。以下是ExcelReader的定義:

public class ExcelReader<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelReader.class);
    private Sheet sheet;
    private Workbook workbook;
    private Class<T> currentSheetClazz;
    // 省略部分成員變量及構(gòu)造方法
}

ExcelReader類包含了Sheet對象、Workbook對象和當(dāng)前Sheet對應(yīng)的Java類信息,這些信息在進(jìn)行數(shù)據(jù)讀取時都會用到。

(2) read(ReadSheet readSheet)方法

read(ReadSheet readSheet)方法是ExcelReader類中讀取數(shù)據(jù)的核心方法,其定義如下:

public void read(ReadSheet readSheet) {
    try {
        readSheet.setClazz(currentSheetClazz);
        readSheet.init();
        process(readSheet);
    } finally {
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                LOGGER.warn("Close IO exception ,msg is {}", e.getMessage());
            }
        }
    }
}

該方法首先將當(dāng)前Sheet對應(yīng)的Java類信息設(shè)置到讀取配置ReadSheet中,然后初始化ReadSheet對象,并調(diào)用process方法進(jìn)行數(shù)據(jù)讀取。

(3) process(ReadSheet readSheet)方法

process(ReadSheet readSheet)方法是ExcelReader中最核心的數(shù)據(jù)讀取方法,其定義如下:

private void process(ReadSheet readSheet) {
    // 從Excel文件中讀取所有的數(shù)據(jù)行
    List<List<String>> rows = readSheet.getHead() == null ? sheet2List() : sheet2List(readSheet.getStartSheetIndex(), readSheet.getEndSheetIndex());
    // 獲取Java類中用于映射Excel中數(shù)據(jù)的屬性列表
    List<Field> fieldList = ReflectionUtil.getFieldListWithExcelColumn(currentSheetClazz);
    // 緩存讀取到的Java對象列表
    List<T> dataList = new ArrayList<>();
    if (CollectionUtils.isEmpty(rows)) {
        return;
    }
    // 遍歷Excel文件中每一行數(shù)據(jù),將每一行數(shù)據(jù)映射為Java對象并添加到dataList中
    for (int i = readSheet.getHead().getRowIndex(); i < rows.size(); i++) {
        List<String> row = rows.get(i);
        T data = ReflectionUtil.newInstance(currentSheetClazz);
        for (int j = 0; j < fieldList.size(); j++) {
            Field field = fieldList.get(j);
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            int index = excelProperty.index();
            if (index >= row.size()) {
                continue;
            }
            String value = row.get(index);
            ReflectionUtil.setFieldValue(field, data, value);
        }
        dataList.add(data);
    }
    // 將讀取到的數(shù)據(jù)返回給調(diào)用方
    readSheet.getResultList().addAll(dataList);
}

該方法首先通過sheet2List方法將Excel文件中的每一行數(shù)據(jù)讀取到List<List>類型的rows集合中,然后通過反射機(jī)制將Excel中的數(shù)據(jù)映射為Java對象并添加到dataList中,最后將dataList返回給調(diào)用方。

(4) sheet2List方法

sheet2List方法是ExcelReader類中的一個私有方法,用于將Excel文件中的所有數(shù)據(jù)讀取到List<List>類型的rows集合中。以下是sheet2List方法的實現(xiàn):

private List<List<String>> sheet2List() {
    // 從Sheet中獲取所有行
    int rownum = sheet.getLastRowNum();
    List<List<String>> rows = new ArrayList<>(rownum);
    for (int i = sheet.getFirstRowNum(); i <= rownum; i++) {
        Row row = sheet.getRow(i);
        if (null == row) {
            continue;
        }
        List<String> cells = new ArrayList<>(row.getLastCellNum());
        for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
            Cell cell = row.getCell(j, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
            String cellValue = ExcelUtil.getCellValue(cell);
            cells.add(cellValue);
        }
        rows.add(cells);
    }
    return rows;
}

該方法首先通過Sheet對象的getLastRowNum方法獲取Excel文件中的總行數(shù),然后遍歷每一行數(shù)據(jù),將每一行數(shù)據(jù)讀取到List類型的cells集合中,并將所有行的數(shù)據(jù)添加到一個List<List>類型的rows集合中,最終返回rows集合。

2. 數(shù)據(jù)寫入

(1) ExcelWriter類

ExcelWriter類是EasyExcel中的另一個核心類,用于寫入數(shù)據(jù)到Excel文件中。以下是ExcelWriter類的定義:

public class ExcelWriter extends AbstractExcelWriter<WriteSheet> {
    // 省略部分代碼及構(gòu)造方法
}

ExcelWriter類繼承自AbstractExcelWriter類,其主要作用是將WriteSheet對象中的數(shù)據(jù)寫入到Excel文件中。

(2) write(List data, WriteSheet sheet)方法

write(List data, WriteSheet sheet)方法是ExcelWriter類中最核心的方法之一,它負(fù)責(zé)將Java對象集合data寫入到Excel文件中。以下是write方法的定義:

public void write(List data, WriteSheet sheet) {
    sheetHolder.set(sheet);
    if (sheet == null) {
        return;
    }
    sheet.init();
    int index = sheetHolder.get().getIndex() == null ? 0 : sheetHolder.get().getIndex();
    String sheetName = sheetHolder.get().getSheetName() == null ? "Sheet" + index : sheetHolder.get().getSheetName();
    currentSheet = workbook.createSheet(sheetName);
    write(data);
    sheetHolder.remove();
}

該方法首先將當(dāng)前的WriteSheet對象設(shè)置到sheetHolder中,并進(jìn)行相應(yīng)的初始化工作,然后創(chuàng)建一個新的Sheet對象,并將Java對象中的數(shù)據(jù)寫入到該Sheet對象中,最后清空sheetHolder中的內(nèi)容。

(3) write(List data)方法

write(List data)方法是ExcelWriter類中真正的數(shù)據(jù)寫入方法,其定義如下:

private void write(List data) {
    WriteHandler handler = sheetHolder.get().getWriteHandler();
    if (handler != null && handler instanceof WorkbookHolder) {
        ((WorkbookHolder) handler).setWorkbook(workbook);
    }
    // 獲取Java對象中用于映射Excel中數(shù)據(jù)的屬性列表
    List<Field> fieldList = ReflectionUtil.getFieldListWithExcelColumn(data.get(0).getClass());
    // 設(shè)置Excel文件中的表頭
    setHead(handler, fieldList);
    try {
        // 遍歷Java對象并將其寫入到Excel文件中
        for (int i = 0; i < data.size(); i++) {
            Object rowModel = data.get(i);
            setIndexValue(i + 1);
            Row row = currentSheet.createRow(getRowIndex());
            for (int j = 0; j < fieldList.size(); j++) {
                Field field = fieldList.get(j);
                if (needIgnore(j)) {
                    continue;
                }
                String stringValue = ReflectionUtil.getFieldStringValue(field, rowModel);
                Cell cell = row.createCell(j);
                if (handler != null && handler instanceof AbstractCellStyleStrategy) {
                    ((AbstractCellStyleStrategy) handler).setCellStyle(cell, field, rowModel, getStringValue(stringValue));
                }
                CellData cellData = converterAndSet(cell, stringValue, field);
                setCellComment(row, field, cellData);
            }
        }
    } finally {
        setIndexValue(null);
    }
}

在該方法中,首先獲取Java對象中用于映射Excel中數(shù)據(jù)的屬性列表,并設(shè)置Excel文件中的表頭。然后遍歷Java對象并將其寫入到Excel文件中,將Java對象中的每個屬性值寫入到Excel文件對應(yīng)單元格中,并設(shè)置單元格樣式、注釋等信息。

三、小結(jié)一下

通過本文的簡單介紹,相信大家對于了解使用EasyExcel進(jìn)行高效的Excel數(shù)據(jù)操作已經(jīng)有了一個基礎(chǔ)的入門認(rèn)識。無論是讀取Excel文件、寫入Excel文件還是填充Excel文件,EasyExcel都提供了非常簡單、易用且高效的解決方案。在實際工作中,我們可以結(jié)合自身的需求,選擇不同的EasyExcel技巧來更好地完成任務(wù)。同時,我們還需要注意一些細(xì)節(jié)問題,以確保Excel操作的正確性和效率。最后,我也希望大家能夠通過閱讀本文,更好地掌握Springboot和EasyExcel的使用技巧,并在實際工作中得到應(yīng)用,給具體的項目添磚加瓦~ v ~ v ~。

以上就是一文帶你輕松掌握EasyExcel的使用技巧的詳細(xì)內(nèi)容,更多關(guān)于EasyExcel使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring data 連接mongodb的兩種方式

    spring data 連接mongodb的兩種方式

    這篇文章主要介紹了spring data mongodb連接方式詳解,本文給大家分享兩種連接方式,通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • Spring報錯:Error creating bean with name的問題及解決

    Spring報錯:Error creating bean with name的問

    這篇文章主要介紹了Spring報錯:Error creating bean with name的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • JVM調(diào)優(yōu)實戰(zhàn)

    JVM調(diào)優(yōu)實戰(zhàn)

    本文主要介紹了JVM調(diào)優(yōu)實戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java數(shù)據(jù)結(jié)構(gòu)專題解析之棧和隊列的實現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)專題解析之棧和隊列的實現(xiàn)

    從數(shù)據(jù)結(jié)構(gòu)的定義看,棧和隊列也是一種線性表。其不同之處在于棧和隊列的相關(guān)運算具有特殊性,只是線性表相關(guān)運算的一個子集。更準(zhǔn)確的說,一般線性表的插入、刪除運算不受限制,而棧和隊列上的插入刪除運算均受某種特殊限制。因此,棧和隊列也稱作操作受限的線性表
    2021-10-10
  • 一篇文章帶你了解Maven的生命周期

    一篇文章帶你了解Maven的生命周期

    這篇文章主要為大家介紹了Maven的生命周期?,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Maven指令打包SpringBoot項目提示沒有主清單文件問題

    Maven指令打包SpringBoot項目提示沒有主清單文件問題

    在Java開發(fā)中,打包Jar時常會遇到“沒有主清單屬性”的錯誤,這通常是因為在pom.xml文件中沒有正確配置maven插件導(dǎo)致的,特別是在使用自定義的<parent/>節(jié)點而非spring-boot-starter-parent時
    2024-09-09
  • SpringBoot整合ES解析搜索返回字段問題

    SpringBoot整合ES解析搜索返回字段問題

    這篇文章主要介紹了SpringBoot整合ES解析搜索返回字段問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 利用maven引入第三方j(luò)ar包以及打包

    利用maven引入第三方j(luò)ar包以及打包

    Maven是通過倉庫對依賴進(jìn)行管理的,當(dāng)Maven項目需要某個依賴時,只要其POM中聲明了依賴的坐標(biāo)信息,Maven就會自動從倉庫中去下載該構(gòu)件使用,如何將jar引用到項目,并且能夠讓項目正常調(diào)用該jar包的方法,本篇文章重點針對于這兩點進(jìn)行講解
    2023-05-05
  • Springboot如何優(yōu)雅的關(guān)閉應(yīng)用

    Springboot如何優(yōu)雅的關(guān)閉應(yīng)用

    這篇文章主要介紹了Springboot如何優(yōu)雅的關(guān)閉應(yīng)用問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • spring?jpa設(shè)置多個主鍵遇到的小坑及解決

    spring?jpa設(shè)置多個主鍵遇到的小坑及解決

    這篇文章主要介紹了spring?jpa設(shè)置多個主鍵遇到的小坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評論