`
king_c
  • 浏览: 222753 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Berkeley DB Java Edition使用说明

 
阅读更多

在使用Berkeley DB c++ Edition的时候发现有些接口不是太了解,发现网上好多都是Java版本的信息,对付发现他们的命名基本相同。所以转载一下以便以后查找。

一、 简介 
Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。 
l 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。 
l 多线程支持,JE使用超时的方式来处理线程间的死琐问题。 
l Database都采用简单的key/value对应的形式。 
l 事务支持。 
l 允许创建二级库。这样我们就可以方便的使用一级key,二级key来访问我们的数据。 
l 支持RAM缓冲,这样就能减少频繁的IO操作。 
l 支持日志。 
l 数据备份和恢复。 
l 游标支持。 
二、 获取JE 
JE下载地址: 
http://www.oracle.com/technology/software/products/berkeley-db/je/index.html 
解开包后 把JE_HOME/lib/je-<version>.jar 中的jar文件添加到你的环境变量中就可以使用je了。 
相关帮助文档可以参考 JE_HOME/docs/index.html 
源代码见JE_HOME/src/*.* 
三、 JE常见的异常 
DatabaseNotFoundException 当没有找到指定的数据库的时候会返回这个异常 
DeadlockException 线程间死锁异常 
RunRecoveryException 回收异常,当发生此异常的时候,你必须得重新打开环境变量。 
四、 关于日志文件必须了解的六项 
JE的日志文件跟其他的数据库的日志文件不太一样,跟C版的DBD也是有区别的 
l JE的日志文件只能APPEND,第一个日志文件名是 00000000.jdb,当他增长到一定大小的时候(默认是10M),开始写第二个日志文件00000001.jdb,已此类推。 
l 跟C版本有所不同,JE的数据日志和事务日志是放在一起的,而不是分开放的。 
l JE cleaner负责清扫没用到的磁盘空间,删除后,或者更新后新的记录会追加进来,而原有的记录空间就不在使用了,cleaner负责清理不用的空间。 
l 清理并不是立即进行的,当你关闭你的数据库环境后,通过调用一个cleaner方法来清理。 
l 清理也不是只动执行的,需要你自己手动调用cleaner 方法来定时清理的。 
l 日志文件的删除仅发生在检查点之后。cleaner准备出哪些log 文件需要被删除,当检查点过后,删掉一些不在被使用的文件。每写20M的日志文件就执行一次检查点,默认下。 
五、 创建数据库环境 
JE要求在任何DATABASE操作前,要先打开数据库环境,就像我们要使用数据库的话必须得先建立连接一样。你可以通过数据库环境来创建和打开database,或者更改database名称和删除database. 
可以通过Environments对象来打开环境,打开环境的时候设置的目录必须是已经存在的目录,否则会出错误。默认情况下,如果指定的database不存在则不会自动创建一个新的detabase,但可以通过设置setAllowCreate来改变这一情况。 
1. 打开database环境 
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
 
...
 
Environment myDbEnvironment = null;
 
try {
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setAllowCreate(true);//如果不存在则创建一个
    myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
} catch (DatabaseException dbe) {
    // 错误处理
}

2. 关闭database环境 
可以通过Environment.close()这个方法来关闭database环境,当你完成数据库操作后一定要关闭数据库环境。 
示例:
1
2
3
4
5
6
7
8
9
10
11
12
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
 
...
 
try {
    if (myDbEnvironment != null) {
        myDbEnvironment.close();
    } 
} catch (DatabaseException dbe) {
    // Exception handling goes here
}

3. 清理日志 
通常在关闭数据库连接的时候,有必要清理下日志,用以释放更多的磁盘空间。我们可以在Environment.close前执行下Environment.cleanLog()来达到此目的。 
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
 
...
 
try {
    if (myDbEnvironment != null) {
        myDbEnvironment.cleanLog(); // 在关闭环境前清理下日志
        myDbEnvironment.close();
    } 
} catch (DatabaseException dbe) {
    // Exception handling goes here
}

4. Database环境的配置 
可以通过EnvironmentConfig这个对象来配置database环境。如果想得到当前环境的配置信息则可以通过Environment.getConfig()方法得到当前环境的配置信息。 
也可以使用EnvironmentMutableConfig来配置环境,其实 EnvironmentConfig是EnvironmentMutableConfig的子类,所以EnvironmentMutableConfig能够使用的设置,EnvironmentConfig也同样能够使用。 
如果你要获取当前环境的使用情况,那么你可以通过使用EnvironmentStats.getNCacheMiss().来监视RAM cache命中率。EnvironmentStats可以由Environment.getStats()方法获取。 
EnvironmentConfig常见方法介绍 
l EnvironmentConfig.setAllowCreate() ; 
如果设置了true则表示当数据库环境不存在时候重新创建一个数据库环境,默认为false. 
l EnvironmentConfig.setReadOnly() 
以只读方式打开,默认为false. 
l EnvironmentConfig.setTransactional() 
事务支持,如果为true,则表示当前环境支持事务处理,默认为false,不支持事务处理。 
EnvironmentMutableConfig的介绍 
l setCachePercent() 
设置当前环境能够使用的RAM占整个JVM内存的百分比。 
l setCacheSize() 
设置当前环境能够使用的最大RAM。单位BYTE 
l setTxnNoSync() 
当提交事务的时候是否把缓存中的内容同步到磁盘中去。 
true 表示不同步,也就是说不写磁盘 
l setTxnWriteNoSync() 
当提交事务的时候,是否把缓冲的log写到磁盘上 
true 表示不同步,也就是说不写磁盘 
示例一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
 
...
 
Environment myDatabaseEnvironment = null;
try {
    EnvironmentConfig envConfig = new EnvironmentConfig();
    //当环境不存在的时候自动创建环境
       envConfig.setAllowCreate(true);
       //设置支持事务
       envConfig.setTransactional(true);
    myDatabaseEnvironment = 
        new Environment(new File("/export/dbEnv"), envConfig);
} catch (DatabaseException dbe) {
   System.err.println(dbe.toString());
   System.exit(1);
}

示例二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentMutableConfig;
import java.io.File;
...
try {
    Environment myEnv = new Environment(new File("/export/dbEnv"), null);
    EnvironmentMutableConfig envMutableConfig = 
        new EnvironmentMutableConfig();
    envMutableConfig.setTxnNoSync(true);
    myEnv.setMutableConfig(envMutableConfig); 
} catch (DatabaseException dbe) {
    // Exception handling goes here
}

示例三:
1
2
3
4
5
import com.sleepycat.je.Environment;
...
//没有命中的CACHE
long cacheMisses = myEnv.getStats(null).getNCacheMiss();
...

5. Database操作 
在BDB中,数据是以key/value方式成队出现的。 
打开database 
可以通过environment.openDatabase()方法打开一个database,在调用这个方法的时候必须指定database的名称。和databaseConfig() (注:数据库设置) 
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package je.gettingStarted;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import java.io.File;
...
Environment myDbEnvironment = null;
Database myDatabase = null;
...
try {
    // 打开一个环境,如果不存在则创建一个
    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setAllowCreate(true);
    myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
 
    // 打开一个数据库,如果数据库不存在则创建一个
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setAllowCreate(true);
    myDatabase = myDbEnvironment.openDatabase(null, 
"sampleDatabase", dbConfig); //打开一个数据库,数据库名为
                                   //sampleDatabase,数据库的配置为dbConfig
} catch (DatabaseException dbe) {
    // 错误处理
}

关闭database 
通过调用Database.close()方法来关闭数据库,但要注意,在关闭数据库前必须得先把游标先关闭。 
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Database;
import com.sleepycat.je.Environment;
...
try {
        if (myDatabase != null) {
            myDatabase.close();
        }
        if (myDbEnvironment != null) {
            myDbEnvironment.close();
        }
} catch (DatabaseException dbe) {
    // 错误处理
}

设置数据库属性 
其实设置数据库属性跟设置环境属性差不多,JE中通过DatabaseConfig对象来设置数据库属性。你能够设置的数据库属性如下。 
l DatabaseConfig.setAllowCreate() 
如果是true的话,则当不存在此数据库的时候创建一个。 
l DatabaseConfig.setBtreeComparator() 
设置用于Btree比较的比较器,通常是用来排序 
l DatabaseConfig.setDuplicateComparator() 
设置用来比较一个key有两个不同值的时候的大小比较器。 
l DatabaseConfig.setSortedDuplicates() 
设置一个key是否允许存储多个值,true代表允许,默认false. 
l DatabaseConfig.setExclusiveCreate() 
以独占的方式打开,也就是说同一个时间只能有一实例打开这个database。 
l DatabaseConfig.setReadOnly() 
以只读方式打开database,默认是false. 
l DatabaseConfig.setTransactional() 
如果设置为true,则支持事务处理,默认是false,不支持事务。 
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package je.gettingStarted;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
...
// Environment open omitted for brevity
...
Database myDatabase = null;
try {
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setAllowCreate(true);
    dbConfig.setSortedDuplicates(true);
    myDatabase = 
        myDbEnv.openDatabase(null, 
                             "sampleDatabase", 
                             dbConfig); 
} catch (DatabaseException dbe) {
    // Exception handling goes here.
}

一些用来管理的方法 
l Database.getDatabaseName() 
取得数据库的名称 
如:String dbName = myDatabase.getDatabaseName(); 
l Database.getEnvironment() 
取得包含这个database的环境信息 
如:Environment theEnv = myDatabase.getEnvironment(); 
l Database.preload() 
预先加载指定bytes的数据到RAM中。 
如:myDatabase.preload(1048576l); // 1024*1024 
l Environment.getDatabaseNames() 
返回当前环境下的数据库列表 
如:
1
2
3
4
5
import java.util.List;
List myDbNames = myDbEnv.getDatabaseNames();
for(int i=0; i < myDbNames.size(); i++) {
    System.out.println("Database Name: " + (String)myDbNames.get(i));
}

l Environment.removeDatabase() 
删除当前环境中指定的数据库。 
如:
1
2
3
String dbName = myDatabase.getDatabaseName();
myDatabase.close();
myDbEnv.removeDatabase(null, dbName);

l Environment.renameDatabase() 
给当前环境下的数据库改名 
如:
1
2
3
4
String oldName = myDatabase.getDatabaseName();   
String newName = new String(oldName + ".new", "UTF-8");
myDatabase.close();
myDbEnv.renameDatabase(null, oldName, newName);

l Environment.truncateDatabase() 
清空database内的所有数据,返回清空了多少条记录。 
如:
1
2
3
Int numDiscarded= myEnv.truncate(null,
myDatabase.getDatabaseName(),true); 
System.out.println("一共删除了 " + numDiscarded +" 条记录 从数据库 " + myDatabase.getDatabaseName());

6. Database 记录 
JE的记录包含两部分,key键值和value数据值,这两个值都是通过DatabaseEntry对象封装起来,所以说如果要使用记录,则你必须创建两个DatabaseEntry对象,一个是用来做为key,另外一个是做为value. 

DatabaseEntry能够支持任何的能够转换为bytes数组形式的基本数据。包括所有的JAVA基本类型和可序列化的对象. 

使用记录 
示例一:把字符串转换DatabaseEntry
1
2
3
4
5
6
7
8
9
10
11
12
package je.gettingStarted;
import com.sleepycat.je.DatabaseEntry;
...
String aKey = "key"; 
String aData = "data";
try {
 //设置key/value,注意DatabaseEntry内使用的是bytes数组
 DatabaseEntry theKey=new DatabaseEntry(aKey.getBytes("UTF-8"));
 DatabaseEntry theData=new DatabaseEntry(aData.getBytes("UTF-8"));
} catch (Exception e) {
    // 错误处理
}

示例二:把DatabaseEntry里的数据转换成字符串
1
2
3
4
byte[] myKey = theKey.getData();
byte[] myData = theData.getData();
String key = new String(myKey, "UTF-8");
String data = new String(myData, "UTF-8");

读和写database 记录 
读和写database记录的时候大体是基本一样的,唯一有区别的是每个key写是否允许写多条记录,默认情况下是不支持多条记录的。 
a) 你可以使用如下方法向database 里添加记录 
l Database.put() 
向database中添加一条记录。如果你的database不支持一个key对应多个data或当前database中已经存在该key了,则使用此方法将使用新的值覆盖旧的值。 
l Database.putNoOverwrite() 
向database中添加新值但如果原先已经有了该key,则不覆盖。不管database是否允许支持多重记录(一个key对应多个value),只要存在该key就不允许添加,并且返回perationStatus.KEYEXIST信息。 
l Database.putNoDupData() 
想database中添加一条记录,如果database中已经存在了相同的 key和value则返回 OperationStatus.KEYEXIST. 
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
package je.gettingStarted;
    import com.sleepycat.je.Database;
    import com.sleepycat.je.DatabaseEntry;
    ...
    String aKey = "myFirstKey";
    String aData = "myFirstData";
    try {
        DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
        DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
        myDatabase.put(null, theKey, theData);
    } catch (Exception e) {
        // Exception handling goes here
    }

b) 你可以使用如下方法从database 里读取记录 
1. Database.get() 
基本的读记录的方法,通过key的方式来匹配,如果没有改记录则返回OperationStatus.NOTFOUND。 
l Database.getSearchBoth() 
通过key和value来同时匹配,同样如果没有记录匹配key和value则会返回OperationStatus.NOTFOUND。 
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package je.gettingStarted;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
...
String aKey = "myFirstKey";
 
try {
    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();
    
    if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==
        OperationStatus.SUCCESS) {
        byte[] retData = theData.getData();
        String foundData = new String(retData, "UTF-8");
        System.out.println("For key: '" + aKey + "' found data: '" + 
                            foundData + "'.");
    } else {
        System.out.println("No record found for key '" + aKey + "'.");
    } 
} catch (Exception e) {
    // Exception handling goes here
}

c) 删除记录 
可以使用Database.delete()这个方法来删除记录。如果你的database支持多重记录,则当前key下的所有记录都会被删除,如果只想删除多重记录中的一条则可以使用游标来删除。 
当然你也可以使用Environment.truncateDatabase()这个方法来清空database 中的所有记录。 

使用示例:
1
2
3
4
5
6
7
8
9
10
package je.gettingStarted;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
...
try {
    String aKey = "myFirstKey";
    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
    myDatabase.delete(null, theKey); 
} catch (Exception e) {
}

d) 提交事务 
当你对database进行了写操作的时候,你的修改不一定马上就能生效,有的时候他仅仅是缓存在RAM中,如果想让你的修改立即生效,则可以使用Environment.sync()方法来把数据同步到磁盘中去。 
e) 不同类型的数据的处理 
1. 你可以使用DatabaseEntry来绑定基本的JAVA数据类型,主要有String、Character、Boolean、Byte、Short、Integer、Long、Float、Double. 
使用示例一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package je.gettingStarted;
              import com.sleepycat.bind.EntryBinding;
              import com.sleepycat.bind.tuple.TupleBinding;
              import com.sleepycat.je.DatabaseEntry;
              ...
              try {
                  String aKey = "myLong";
                  DatabaseEntry theKey = new
                  DatabaseEntry(aKey.getBytes("UTF-8"));    
 
                  Long myLong = new Long(123456789l);
                  DatabaseEntry theData = new DatabaseEntry();
                  EntryBinding myBinding =        
                  TupleBinding.getPrimitiveBinding(Long.class);
                  myBinding.objectToEntry(myLong, theData);
                  myDatabase.put(null, theKey, theData);
              } catch (Exception e) {
                  // Exception handling goes here
              }

使用示例二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package je.gettingStarted;
       import com.sleepycat.bind.EntryBinding;
       import com.sleepycat.bind.tuple.TupleBinding;
       import com.sleepycat.je.Database;
       import com.sleepycat.je.DatabaseEntry;
       import com.sleepycat.je.LockMode;
       import com.sleepycat.je.OperationStatus;
       ...
       Database myDatabase = null;
       try {
           String aKey = "myLong";
           DatabaseEntry theKey = new 
              DatabaseEntry(aKey.getBytes("UTF-8"));
           DatabaseEntry theData = new DatabaseEntry();
           EntryBinding myBinding =        
              TupleBinding.getPrimitiveBinding(Long.class);
           OperationStatus retVal = myDatabase.get(null, theKey, theData, 
              LockMode.DEFAULT);
           String retKey = null;
           if (retVal == OperationStatus.SUCCESS) {
        Long theLong = (Long) myBinding.entryToObject(theData);
               retKey = new String(theKey.getData(), "UTF-8");
               System.out.println("For key: '" + retKey + "' found Long: '" + 
                            theLong + "'.");
           } else {
               System.out.println("No record found for key '" + retKey + "'.");
           }
       } catch (Exception e) {
           // Exception handling goes here
       }


From:http://cllovelf.blog.chinajavaworld.com/entry/282

分享到:
评论

相关推荐

    Berkeley DB Java Edition (JE)

    Berkeley DB Java Edition (JE) 官方7.5.11下载版本。 相关介绍 https://blog.csdn.net/hadues/article/details/80854288

    Berkeley DB Java Edition

    **Berkeley DB Java Edition**,简称BDBJE,是由Oracle公司开发的一款高度可移植的、基于文件系统的数据存储解决方案,特别适用于需要高效、可靠且无服务器的数据管理的应用场景。这款数据库系统采用B+树作为其核心...

    Berkeley DB Java Edition 5.0.73

    **Berkeley DB Java Edition 5.0.73** Berkeley DB Java Edition(简称BDB JE)是一款由Oracle公司开发的高性能、轻量级的NoSQL数据库系统。它以其高效能、可扩展性和可靠性在处理大规模数据存储时受到广泛欢迎,...

    Berkeley DB Java Edition学习报告

    Berkeley DB Java Edition (JE) 是一款开源的嵌入式数据库管理系统,由Sleepycat Software开发,现归Oracle公司所有。这款数据库系统以其键值(K/V)存储模型为特色,适用于需要高性能、可伸缩性及事务处理能力的应用...

    Berkeley DB Java Edition数据结构的研究与应用.pdf

    Berkeley DB Java Edition(JE)是一种为Java程序提供内嵌式、事务保护的数据库引擎,它继承了Berkeley DB家族的优点,包括快速、可靠和具备容错能力的数据管理特性。为了深入理解其数据存储结构,有必要对JE使用的B...

    Berkeley DB的java版本

    Berkeley DB Java Edition JE 是一个完全用JAVA写的 它适合于管理海量的 简单的数据 能够高效率的处理1到1百万条记录 制约JE数据库的往往是硬件系统 而不是JE本身 多线程支持 JE使用超时的方式来处理线程间的死琐...

    Berkeley DB Java Edition 4.0.92 开发包

    《Berkeley DB Java Edition 4.0.92 开发包详解》 Berkeley DB Java Edition(简称BDB JE)是Oracle公司推出的一款强大的、高度可定制的嵌入式数据库系统,尤其适用于Java应用程序。这款数据库引擎以其轻量级、高...

    Java嵌入式NoSQL数据库之Berkeley DB Java Edition

    **Java嵌入式NoSQL数据库之Berkeley DB Java Edition** Berkeley DB Java Edition(简称BDB JE)是一种高性能、轻量级的嵌入式数据库系统,由Oracle公司开发,广泛应用于需要快速数据存储和检索的应用场景。它并非...

    Berkeley DB Java Edition 4.1.10.zip

    Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。 多线程支持,JE使用超时的方式来处理...

    Berkeley DB Java Edition初步

    NULL 博文链接:https://xpenxpen.iteye.com/blog/2124921

    BerkeleyDB_java_jar包

    3. **示例和文档**:可能包含演示如何使用BerkeleyDB Java API的示例代码,以及详细说明如何配置、操作和管理数据库的文档。 4. **依赖库**:BerkeleyDB可能依赖于其他的Java库,这些库也可能包含在jar文件中或者...

    berkeley db java

    自己稍微封装了一下,可以当成简单的map来使用。

    嵌入式Berkeley DB Java版与Derby技术研究.pdf

    《嵌入式Berkeley DB Java版与Derby技术研究》一文主要探讨了两种典型的嵌入式数据库技术——Berkeley DB Java Edition和Apache Derby。嵌入式数据库在资源有限的环境中,如嵌入式系统,因其体积小、功能齐全、可...

    Java-Edition-BerkeleyDB-3.1.0.zip_BerkeleyDB

    在Java-Edition-BerkeleyDB-3.1.0版本中,它提供了高效、可靠的数据存储解决方案,尤其适合于对性能有极高要求的嵌入式应用或分布式系统。该数据库系统以其轻量级、无服务器模式以及出色的并发控制而闻名。 **1. ...

    Berkeley DB 读取样例

    总的来说,Berkeley DB Java Edition为Java开发者提供了一种快速、可靠且灵活的本地数据存储解决方案。通过上述步骤,我们可以创建并管理Berkeley DB数据库,实现数据的存取。然而,为了充分利用其功能,还需要深入...

    Berkeley_DB_Java_Edition.zip_海量 数据

    Berkeley DB Java Edition (JE)是一个完全用JAVA 写的,它适合于管理海量的,简单的 数据。 l 能够高效率的处理 1 到 1 百万条记录,制约 JE 数据库的往往是硬件系统,而不是 JE 本身。 多线程支持,JE 使用超时的...

Global site tag (gtag.js) - Google Analytics