最近在自学java,感觉和c++很像,只是不能自己管理内存,没有指针这个概念了(感觉很不爽,以前使用指针操作很方便),但是换来了不用担心内存泄漏的问题,了解到其jvm使用的是垃圾回收的方式管理内存,等以后我了解透彻在给大家分享我的看法吧。由于c++的基础,我在学习java的时候并没有像以前一样抱着语法书死啃,而是找了一本java在实际应用方面书籍,我想的是结合这语法书练习更贴近实际开发的代码,会在学习java上效率提升一点。在目前看来我的还是比较适应我的方法,并没有什么特别吃力的地方。(可能是大牛都给我封装好了)我选择的书方向是网络爬虫,这就要延伸到网络协议方面的知识,什么http,tcp、ip协议等等,这方面我以后和大家分享我的经验,今天的主要目的是java数据库的使用(在网络爬虫方面最简单的应用就是找到新的连接放在数据库里)。
由于我需要储存的信息是网络爬虫爬虫来的新连接,数据内容很简单,就是域名而已,但是数据量比较大,因此我选择的数据库是Berkeley DB的java版本,在官网上就能找到,在这里我就不贴出来了。下载出来的是。jar包,把它包含到你的包中就可以使用了。
首先在学习支出我们理清一下构建一个简单的建-值数据库的思路,首先我们要知道数据库的主要目的是为了保存大量的数据,并且不可能常驻在内存中,因此我们就需要在硬盘上创建对应数据库的文件,这其实就是实际的数据库的实例(逻辑上的实例是在内存当中),其次在使用数据库时,可能不会遇到完全不同的数据,这时就需要分开储存,就需要一个新的数据库,因此在一台计算机上可能出现多个数据库,因此为了方便管理,我们需要一个数据库环境来同一管理(在解决问题的先后上是先有数据库,后有环境,但是在实际的使用中,环境就像土壤,没有他数据库就无法创建),在以后就是数据库的基本操作,读,写,遍历,查找等等。
以下是我在阅读手册和网上大牛分享写的测试代码:
//这时简单数据库类的实现,我把手册上部分内容注释在相关的地方,是方便观看与学习,本人水平有限,欢迎交流
package BDB_je;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.CursorConfig;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockConflictException;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import myStringHelper.StringHelper;
public class mydatabase {
//数据库环境
private Environment myDbEnvironment = null;
//数据库配置
private DatabaseConfig dbConfig=null;
//数据库游标
// private Cursor myCursor = null;
//数据库对象
private Database myDatabase = null;
//数据库文件名
private String fileName = "";
//数据库名称
private String dbName = "";
public mydatabase(String fileName2, String dbName2) {
// TODO 自动生成的构造函数存根
this.fileName=fileName2;
this.dbName=dbName2;
}
public void openDatabase()
{
try{
printdebugMsg("打开数据库:"+dbName);
EnvironmentConfig envConfig= new EnvironmentConfig();
envConfig.setAllowCreate(true);
//true则表示当数据库环境不存在时候重新创建一个数据库环境,默认为false
envConfig.setTransactional(true);
//为true,则表示当前环境支持事务处理,默认为false,不支持事务处理。
envConfig.setReadOnly(false);
//以只读方式打开,默认为false.
envConfig.setTxnTimeout(10000,TimeUnit.MILLISECONDS);
envConfig.setLockTimeout(10000,TimeUnit.MILLISECONDS);
/*
* 其他配置 可以进行更改
EnvironmentMutableConfig envMutableConfig = new EnvironmentMutableConfig();
envMutableConfig.setCachePercent(50);//设置je的cache占用jvm 内存的百分比。
envMutableConfig.setCacheSize(123456);//设定缓存的大小为123456Bytes
envMutableConfig.setTxnNoSync(true);//设定事务提交时是否写更改的数据到磁盘,true不写磁盘。
envMutableConfig.setTxnWriteNoSync(false);//设定事务在提交时,是否写缓冲的log到磁盘。如果写磁盘会影响性能,不写会影响事务的安全。随机应变。
*
*EnvironmentMutableConfig是Environment的父类
*/
File file=new File(fileName);
if(!file.exists())
{
file.mkdir();
}
myDbEnvironment=new Environment(file,envConfig);
dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
dbConfig.setReadOnly(false);
//dbConfig.setSortedDuplicates(false);
/*
setBtreeComparator 设置用于B tree比较的比较器,通常是用来排序
setDuplicateComparator 设置用来比较一个key有两个不同值的时候的大小比较器。
setSortedDuplicates 设置一个key是否允许存储多个值,true代表允许,默认false.
setExclusiveCreate 以独占的方式打开,也就是说同一个时间只能有一实例打开这个database。
setReadOnly 以只读方式打开database,默认是false.
setTransactional 如果设置为true,则支持事务处理,默认是false,不支持事务。
*/
if(myDatabase==null)
{
myDatabase=myDbEnvironment.openDatabase(null, dbName, dbConfig);
}
printdebugMsg(dbName+"数据库中的数据个数"+myDatabase.count());
/*
* Database.getDatabaseName()
取得数据库的名称
如:String dbName = myDatabase.getDatabaseName();
Database.getEnvironment()
取得包含这个database的环境信息
如:Environment theEnv = myDatabase.getEnvironment();
Database.preload()
预先加载指定bytes的数据到RAM中。
如:myDatabase.preload(1048576l); // 1024*1024
Environment.getDatabaseNames()
返回当前环境下的数据库列表
Environment.removeDatabase()
删除当前环境中指定的数据库。
如:
String dbName = myDatabase.getDatabaseName();
myDatabase.close();
myDbEnv.removeDatabase(null, dbName);
Environment.renameDatabase()
给当前环境下的数据库改名
如:
String oldName = myDatabase.getDatabaseName();
String newName = new String(oldName + ".new", "UTF-8");
myDatabase.close();
myDbEnv.renameDatabase(null, oldName, newName);
Environment.truncateDatabase()
清空database内的所有数据,返回清空了多少条记录。
如:
Int numDiscarded= myEnv.truncate(null,
myDatabase.getDatabaseName(),true);
CheckMethods.PrintDebugMessage("一共删除了 " + numDiscarded +" 条记录 从数据库 " + myDatabase.getDatabaseName());
*/
}
catch(DatabaseException e)
{
printdebugMsg(e.getMessage());
}
}
//写键,值入数据库
public boolean writeToDatabase(String key,String value,boolean isOverwrite)
{
try {
DatabaseEntry theKey=new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
DatabaseEntry theData=new DatabaseEntry(value.getBytes("UTF-8"));
OperationStatus res = null;
Transaction txn = null;
try {
TransactionConfig txConfig = new TransactionConfig();
txConfig.setSerializableIsolation(true);
txn = myDbEnvironment.beginTransaction(null, txConfig);
if(isOverwrite)
{
res=myDatabase.put(txn, theKey, theData);
}
else
{
res=myDatabase.putNoOverwrite(txn, theKey, theData);
}
txn.commit();
if(res==OperationStatus.SUCCESS)
{
printdebugMsg("向数据库"+dbName+"中写入:"+"("+key+","+value+")");
return true;
}
else if(res==OperationStatus.KEYEXIST)
{
printdebugMsg("向数据库"+dbName+"中写入:"+"("+key+","+value+")"+"失败,已存在该值");
return false;
}
else
{
printdebugMsg("向数据库"+dbName+"中写入:"+"("+key+","+value+")"+"失败");
return false;
}
}
catch(LockConflictException lockConflict)
{
txn.abort();
printdebugMsg("向数据库" + dbName +"中写入:"+key+","+value+"出现lock异常");
printdebugMsg(lockConflict.getMessage());
printdebugMsg(lockConflict.getCause().toString());
printdebugMsg(lockConflict.getStackTrace().toString());
return false;
}
}
catch(Exception e){
printdebugMsg(e.getMessage());
return false;
}
}
//关闭当前数据库
public void closeDatabase()
{
if(myDatabase!=null)
{
myDatabase.close();
}
if(myDbEnvironment!=null)
{
printdebugMsg("关闭数据库"+dbName);
myDbEnvironment.cleanLog();
myDbEnvironment.close();
}
}
public boolean deleteFormDatabase(String key)
{
boolean success=false;
long sleepMillis = 0;
for(int i =0;i<3;i++)
{
if(sleepMillis!=0)
{
try
{
Thread.sleep(sleepMillis);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
sleepMillis=0;
}
Transaction txn=null;
try
{
TransactionConfig txConfig=new TransactionConfig ();
txConfig.setSerializableIsolation(true);
txn=myDbEnvironment.beginTransaction(null, txConfig);
DatabaseEntry theKey;
theKey =new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
OperationStatus res=myDatabase.delete(txn, theKey);
txn.commit();
if(res==OperationStatus.SUCCESS)
{
printdebugMsg("从数据库"+dbName+"中删除:"+key);
success=true;
return success;
}
else if(res== OperationStatus.KEYEMPTY)
{
printdebugMsg("没有从"+dbName+"中找到"+key+"无法删除");
}
else
{
printdebugMsg("没有从数据库中找到"+key+".无法删除");
}
return false;
}
catch(UnsupportedEncodingException e)
{
e.printStackTrace();
return false;
}
catch(LockConflictException lockConflict)
{
printdebugMsg("删除操作失败,出现Lockflict异常");
printdebugMsg(lockConflict.getMessage());
printdebugMsg(lockConflict.getCause().toString());
printdebugMsg(lockConflict.getStackTrace().toString());
sleepMillis=1000;
continue;
}
finally
{
if(!success)
{
if(txn!=null)
{
txn.abort();
}
}
}
}
return false;
}
public String readFromDatabase(String key)
{
try{
DatabaseEntry thekey =new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
DatabaseEntry thedata= new DatabaseEntry();
Transaction txn=null;
try {
TransactionConfig txConfig = new TransactionConfig();
txConfig.setSerializableIsolation(true);
txn = myDbEnvironment.beginTransaction(null, txConfig);
OperationStatus res = myDatabase.get(txn, thekey, thedata, LockMode.DEFAULT);
if(res==OperationStatus.SUCCESS)
{
byte[] retData=thedata.getData();
String foundData= new String(retData,"UTF-8");
printdebugMsg("从数据库"+dbName+"中读取:"+key+","+foundData);
return foundData;
}
else
{
printdebugMsg("没有发现这个建:"+key);
return " ";
}
}catch(LockConflictException lockConflict)
{
txn.abort();
printdebugMsg("从数据库"+dbName+"中读取:"+key+"出现错误");
printdebugMsg(lockConflict.getMessage());
printdebugMsg(lockConflict.getCause().toString());
printdebugMsg(lockConflict.getStackTrace().toString());
return " ";
}
}catch(UnsupportedEncodingException e)
{
e.printStackTrace();
return "";
}
}
public ArrayList<String> getEveryItem()
{
printdebugMsg("开始遍历数据库:"+dbName+"中的所有数据");
Cursor myCursor= null;
ArrayList<String> resultList =new ArrayList<String>();
Transaction txn =null;
try {
txn = this.myDbEnvironment.beginTransaction(null, null);
CursorConfig cc = new CursorConfig();
cc.setReadCommitted(true);
if(myCursor==null)
myCursor = myDatabase.openCursor(txn, cc);
DatabaseEntry foundKey = new DatabaseEntry();
DatabaseEntry foundData = new DatabaseEntry();
if(myCursor.getFirst(foundKey, foundData, LockMode.DEFAULT)== OperationStatus.SUCCESS)
{
String theKey = new String(foundKey.getData(), "UTF-8");
String theData = new String(foundData.getData(), "UTF-8");
resultList.add(theKey);
printdebugMsg("Key | Data : " + theKey + " | " + theData + "");
while (myCursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS)
{
theKey = new String(foundKey.getData(), "UTF-8");
theData = new String(foundData.getData(), "UTF-8");
resultList.add(theKey);
printdebugMsg("Key | Data : " + theKey + " | " + theData + "");
}
}
myCursor.close();
txn.commit();
return resultList;
}
catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
catch (Exception e)
{
printdebugMsg("getEveryItem处理出现异常");
printdebugMsg(e.getMessage().toString());
printdebugMsg(e.getCause().toString());
txn.abort();
if (myCursor != null)
{
myCursor.close();
}
return null;
}
}
public void printdebugMsg(String debugmsg) //打印数据库消息
{
System.out.println(debugmsg);
}
}
//这时测试类
package BDB_je;
public class demoDB {
public static void main(String args[])throws Exception
{
mydatabase myDb= new mydatabase(“123”,”123”);
myDb.openDatabase();
myDb.writeToDatabase(“阳浩”, “通信大神,c语言大神”, false);
myDb.writeToDatabase(“席浩州”, “嵌入式开发大牛”, true);
myDb.writeToDatabase(“刘于佳 “, “3d建模大神”, true);
myDb.writeToDatabase(“阳历”, “哲学大师”, true);
myDb.writeToDatabase(“袁天一”, “最菜的那个人,什么都不会”, true);
myDb.readFromDatabase("阳历");
myDb.getEveryItem();
myDb.closeDatabase();
}
}
“`
执行结果如下:
希望能对您有一点帮助