一下是一个DB4O的操作DAO。
作为DB4O在WEB项目中的操作,如果每次调用接口NEW一个对象去取得查询文件的时候,系统会报错,表示所读的DB文件已经被锁住了。查看了网上的一些解决方式。最后自己实现,解决了问题。
解决方法。在WEB容器启动的时候,新建一个监听器
WebListener.java
package common.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import common.util.db4o.LogMessageDao;
public class WebListener implements ServletContextListener {
LogMessageDao logdao;
private static final ThreadLocal local = new ThreadLocal();
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
public void contextInitialized(ServletContextEvent event) {
String path =event.getServletContext().getRealPath("/log/log.db");
logdao = logdao.getInstance(path);
//local.set(logdao);
event.getServletContext().setAttribute("LogDao", logdao);
//在监听器中将要用到查DB文件的DAO类放入到ServletContext中
// TODO Auto-generated method stub
}
}
然后在我们用用的时候,在一个JSP页面的用法,从ServletContext中拿出来。
LogMessageDao logdao = (LogMessageDao)config.getServletContext().getAttribute("LogDao");
System.out.println("logdao:"+logdao);
List<LogMessage> list= logdao.getAllMessage();
for(int i=0;i<list.size();i++)
{
LogMessage lg = (LogMessage)list.get(i);
%>
<log>
<perid><%=lg.getPerID() %></perid>
<remoteip><%=lg.getRemoteIP() %></remoteip>
<date><%=lg.getDate() %></date>
</log>
<%
}
//这样就不会造成文件被锁住了。
下面是DAO的JAVA文件
package common.util.db4o;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.config.Configuration;
import com.db4o.io.CachedIoAdapter;
import com.db4o.io.RandomAccessFileAdapter;
import com.db4o.query.Constraint;
import com.db4o.query.Query;
public class LogMessageDao {
private static LogMessageDao messageDao = null;
private Configuration configuration = null;
private ObjectContainer db = null;
private String path;
private LogMessageDao(String path) {
configuration = Db4o.newConfiguration();
// configuration.io(new RandomAccessFileAdapter());
configuration.io(new CachedIoAdapter(new RandomAccessFileAdapter()));
configuration.optimizeNativeQueries(true);
configuration.objectClass(LogMessage.class).objectField("perID").indexed(true);
configuration.objectClass(LogMessage.class).objectField("remoteIP").indexed(true);
configuration.objectClass(LogMessage.class).objectField("date").indexed(true);
this.path = path;
openDB4O(path);
}
/**
* 获取实例
* @param path
* @return
*/
public static LogMessageDao getInstance(String path) {
if (messageDao == null) {
messageDao = new LogMessageDao(path);
}
return messageDao;
}
public List<LogMessage> getHistory(String to, String beginDate, String endDate,int msgType) {
List<LogMessage> msgList = null;
Query query = db.query();
query.constrain(LogMessage.class);
Constraint constr = query.descend("from").constrain(to);
query.descend("date").constrain(beginDate).greater().equal();
query.descend("date").constrain(endDate).smaller().equal();
if(msgType == 0){ //msgType=0 表示查询普通聊天记录
query.descend("to").constrain(to).or(constr);
} else if(msgType == 1){ //msgType=1 表示查询群聊天记录
query.descend("from").constrain(to);
}
query.descend("date_time").orderAscending();
ObjectSet result = query.execute();
msgList = (result == null) ? new ArrayList<LogMessage>() : result;
return msgList;
}
/**
* 查询外部IM的历史记录
* @param to 查询对象
* @param me 查询人的jid
* @param con 当前xmpp连接实例
* @param beginDate 查询的开始日期
* @param endDate 查询的结束日期
* @return
*/
public List<LogMessage> getImHistory(String to, String me, String con, String beginDate, String endDate) {
List<LogMessage> msgList;
Query query = db.query();
query.constrain(LogMessage.class);
Constraint constr1 = query.descend("from").constrain(me);
Constraint constr2 = query.descend("from").constrain(to);
Constraint constr3 = query.descend("to").constrain(con).and(constr2);
query.descend("date").constrain(beginDate).greater().equal();
query.descend("date").constrain(endDate).smaller().equal();
query.descend("to").constrain(to).and(constr1).or(constr3);
query.descend("date_time").orderAscending();
ObjectSet result = query.execute();
msgList = (result == null) ? new ArrayList() : result;
return msgList;
}
/**
* 获取一个群最后一个消息的收发时间
* @param room
* @return
*/
public long getLastMsgDate(String room){
Query query = db.query();
query.constrain(LogMessage.class);
query.descend("from").constrain(room);
query.descend("date_time").orderDescending();
ObjectSet<LogMessage> result = query.execute();
long date_time = (result != null && result.size() > 0) ? result.get(0).getDate_time() : 0;
return date_time;
}
/**
* 保存一条消息到数据库
* @param msg
*/
public void saveMsg(LogMessage msg) {
if (db.ext().isClosed()) {
openDB4O(path);
}
db.store(msg);
db.commit();
}
/**
* 打开Db4o数据库
* @param path
*/
public void openDB4O(String path) {
File tempFile = new File(path);
String tempStr = tempFile.getAbsolutePath();
int index = tempStr.lastIndexOf(File.separatorChar);
if (index > 0) {
String path2 = tempStr.substring(0, tempStr.lastIndexOf(File.separatorChar));
File file = new File(path2);
if (!file.exists()) {
file.mkdirs();
}
}
db = Db4o.openFile(configuration, path);
}
public void closeDB4O() {
db.close();
}
public List<LogMessage> getAllMessage()
{
List<LogMessage> mymessage=null;
Query query = this.db.query();
query.constrain(LogMessage.class);
ObjectSet objset = query.execute();
mymessage = objset;
return mymessage;
}
public void save(String path,String perID,String remoteIP)
{
if (db.ext().isClosed()) {
openDB4O(path);
}
java.util.Date date = new java.util.Date();
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String strDate = df.format(date); //当天日期
LogMessage lm = new LogMessage();
lm.setPerID(perID);
lm.setRemoteIP(remoteIP);
lm.setDate(strDate);
db.store(lm);
db.commit();
}
public static void main(String[] args) {
// }
}