背景:与AJAX跨域问题的产生一样,系统里新增的即时聊天模块,关于聊天内容,是要保存历史记录的。因为即时聊天的特性,数据的保存和获取,需要即时的显示,采用传统关系型数据库,在用户过多的情况下可能就有性能问题了。所以转而考虑非关系型数据库。
在了解了NoSql的类型和特点后。研究的重点放在了MongoDB和Redis这两种数据库上。在易用性上,MongoDB会好一些。MongoDB提供了比较好的查询功能。比较适合聊天模块的应用。所以最终采用的方式是MongoDB。
对应传统关系型数据库。DB-->TABLE-->COLOUM。MongoDB中的层级结构是DB-->COLLECTION-->JSON数据(其实就是KEY--VALUE)
JAVA应用MongoDB:管理类
import java.net.UnknownHostException; import com.mongodb.DB; import com.mongodb.Mongo; import com.mongodb.MongoException; import com.mongodb.MongoOptions; import com.troila.core.utils.PropertiesUtils; public class MongoManager { private final static String HOST = "xx.xx.xx.xx";// IP private final static int PORT = 27017;// 端口 private final static int POOLSIZE = 1000;// 连接数量 private final static int BLOCKSIZE = 1000; // 等待队列长度 private static Mongo mongo = null; private MongoManager() { } static { initDBPrompties(); } public static DB getDB(String dbName) { return mongo.getDB(dbName); } /** * 初始化连接池 */ private static void initDBPrompties() { // 其他参数根据实际情况进行添加 try { mongo = new Mongo(HOST, PORT); MongoOptions opt = mongo.getMongoOptions(); opt.connectionsPerHost = POOLSIZE; opt.threadsAllowedToBlockForConnectionMultiplier = BLOCKSIZE; opt.maxWaitTime = 5000; opt.autoConnectRetry = true; opt.socketKeepAlive=true; opt.socketTimeout = 2000; opt.connectTimeout = 15000; } catch (UnknownHostException e) { } catch (MongoException e) { } } }
插入举例
public void insertOneChat(String from_uid, String to_uid, String text, String sendTime) { DB db = MongoManager.getDB(DB_NAME); DBCollection chatTable = db.getCollection(CHAT_TABLE); db.requestStart(); // 事务开始 try { // 写信息 DBObject newChat = new BasicDBObject(); HashMap mp = new HashMap(); mp.put(FROM_UID, from_uid); mp.put(TO_UID, to_uid); mp.put(CONTENT, text); mp.put(SEND_TIME, sendTime); System.out.println(mp); newChat.put(FROM_UID, from_uid); newChat.put(TO_UID, to_uid); newChat.put(CONTENT, text); newChat.put(SEND_TIME, sendTime); System.out.println(newChat); chatTable.insert(newChat); // 写未读标记 // if(!this.hasNewMessage(to_uid, from_uid)){ saveUnreadInfo(from_uid,to_uid); // } } catch (Exception e) { e.printStackTrace(); } finally { // 事务结束 db.requestDone(); } }
查询举例
public List queryChatMessageOneOnOne(String from_uid ,String to_uid) { DB db = MongoManager.getDB(DB_NAME); DBCollection table = db.getCollection(CHAT_TABLE); // 更新为已读(清理提醒表中与自己相关的信息) removeUnreadTable(from_uid ,to_uid); // 查询已读 DBObject in_data = new BasicDBObject("$in",new Object[] { to_uid, from_uid }); DBObject query = new BasicDBObject(); query.put(FROM_UID, in_data); query.put(TO_UID, in_data); DBCursor cur = table.find(query); List<Map> list = new ArrayList<Map>(); try { while (cur.hasNext()) { DBObject obj = cur.next(); Map map = new HashMap(); map.put("from_uid", obj.get(FROM_UID)); map.put("to_uid", obj.get(TO_UID)); map.put("content", obj.get(CONTENT)); map.put("send_time", obj.get(SEND_TIME)); map.put("msg_type", "1"); list.add(map); } } finally { cur.close(); } return list; }
删除举例
public void removeUnreadTable(String from_uid, String to_uid) { DB db = MongoManager.getDB(DB_NAME); DBCollection table = db.getCollection(REMIND_TABLE); DBObject deleteQuery = new BasicDBObject(); deleteQuery.put(FROM_UID, from_uid); deleteQuery.put(TO_UID, to_uid); table.remove(deleteQuery); }
修改举例
@Override public void updateUnread(DBObject mongoObj) { // TODO Auto-generated method stub DB db = MongoManager.getDB(DB_NAME); DBCollection invite = db.getCollection(INVITE_TABLE); db.requestStart(); try { DBObject uptObj = mongoObj; DBObject oldObj = invite.findOne(mongoObj); uptObj.removeField(IS_READED); uptObj.put(IS_READED, "1"); invite.update(oldObj, uptObj); }catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ db.requestDone(); } }
除了增删改查之外。
值得一提的是upsert:是一种先查询如果查到记录就更新,查不到记录就增加的记录的数据处理方式。
扫描二维码关注公众号,回复:
1144565 查看本文章
另外一个要说的是修改操作的时候除了修改某个KEY的VALUE之外,这个KEY也是可以修改的。