接着上一篇博文,我再补充一下:
在js中收集到用户行为数据之后呢,我们要在后台对数据进行处理,怎么处理?在实际项目中我分两条路走:
一、直接写入mongodb,随着电商网站规模越来越大,访问量越来越高,这种非关系型数据库可以有效地化解高并发的问题
二、做日志处理(后台数据-----redis-----logstash-----elasticsearch------kibana)
在这篇文章中,我们先来探讨写DB。
两种方式,一、利用java mongodb api;二、利用log4j
方式一mongodb提供了很友好的java api
我们先来看看:
package com.founder.ec.util;
import java.net.SocketException;
import java.net.UnknownHostException;
import com.founder.ec.entity.BehaviorUser;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
/**
* 实现MongoDB的CRUD操作
*
* @author 五味子
* @version 2014/04/04
*/
public class MongOpera {
private static DB db;
private static DBCollection users;
private static Mongo mg;
@SuppressWarnings("deprecation")
public static DBCollection init() {
try {
try {
mg = DBManager.inits("192.168.2.87", 27017, 300);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 获取temp DB;如果默认没有创建,mongodb会自动创建
db = mg.getDB("test");
// 获取users DBCollection;如果默认没有创建,mongodb会自动创建
users = db.getCollection("testdb");
return users;
}
/**//**
* 销毁mongo对象
* @param
* @return
*//*
public static void destory() {
if (mg != null)
mg.close();
mg = null;
db = null;
users = null;
System.gc();//内存垃圾回收
}
*//**
* 打印查询结果
* @param o
* @return
*//*
public static void print(Object o) {
System.out.println(o);
}
*//**
* 查询所有数据
* @param
* @return
*//*
private static void queryAll() {
print("查询users的所有数据:");
// db游标
DBCursor cur = users.find();
while (cur.hasNext()) {
print(cur.next());
}
}*/
/**
* 添加数据
* @param Synchronized
* @param
* @return
*/
public static void add(BehaviorUser behaviorUser) {
// 先查询所有数据
//queryAll();
//print("count: " + users.count());
DBObject user = new BasicDBObject();
user.put("sessionId", behaviorUser.getSessionId());
user.put("uuid", 24);
user.put("memberId", behaviorUser.getMemberId());
user.put("refPage", behaviorUser.getRefPage());
user.put("firstPage", behaviorUser.getFirstPage());
user.put("initTime", behaviorUser.getInitTime());
user.put("orderId", behaviorUser.getOrderId());
user.put("currentTime", behaviorUser.getCurrentTime());
user.put("currentURL", behaviorUser.getCurrentPage());
users = init();
users.save(user);//保存,getN()获取影响行数
/*List list1 = new ArrayList();
List<DBObject> list2 = null;
list1.add(user);
if (list1.size()>=30) {
list2 = new ArrayList();
Synchronized{
list2.addAll(list1);
list1.clear();
}
new Thread().start();
new Thread(
try{
users.insert(list2);
}catch(ApplicationException e){
}
).start();
}*/
//print(users.save(user).getN());
/*// 扩展字段,随意添加字段,不影响现有数据
user.put("sex", "男");
print(users.save(user).getN());
// 添加多条数据,传递Array对象
print(users.insert(user, new BasicDBObject("name", "tom")).getN());
// 添加List集合
List<DBObject> list = new ArrayList<DBObject>();
list.add(user);
DBObject user2 = new BasicDBObject("name", "lucy");
user.put("age", 22);
list.add(user2);
// 添加List集合
print(users.insert(list).getN());
// 查询下数据,看看是否添加成功
print("count: " + users.count());
queryAll();*/
}
/* *//**
* 移除数据
* @param
* @return
*//*
public static void remove() {
queryAll();
print("删除id = 4de73f7acd812d61b4626a77:"
+ users.remove(
new BasicDBObject("_id", new ObjectId(
"4de73f7acd812d61b4626a77"))).getN());
print("remove age >= 24: "
+ users.remove(
new BasicDBObject("age", new BasicDBObject("$gte", 24)))
.getN());
}
*//**
* 修改数据
* @param
* @return
*//*
public static void modify() {
print("修改:"
+ users.update(
new BasicDBObject("_id", new ObjectId(
"4dde25d06be7c53ffbd70906")),
new BasicDBObject("age", 99)).getN());
print("修改:"
+ users.update(
new BasicDBObject("_id", new ObjectId(
"4dde2b06feb038463ff09042")),
new BasicDBObject("age", 121), true,// 如果数据库不存在,是否添加
false// 多条修改
).getN());
print("修改:"
+ users.update(new BasicDBObject("name", "haha"),
new BasicDBObject("name", "dingding"), true,// 如果数据库不存在,是否添加
true// false只修改第一天,true如果有多条就不修改
).getN());
// 当数据库不存在就不修改、不添加数据,当多条数据就不修改
// print("修改多条:" + coll.updateMulti(new BasicDBObject("_id", new
// ObjectId("4dde23616be7c19df07db42c")), new BasicDBObject("name",
// "199")));
}
*//**
* 条件查询
* @param
* @return
*//*
public static void query() {
// 查询所有
// queryAll();
// 查询id = 4de73f7acd812d61b4626a77
print("find id = 4de73f7acd812d61b4626a77: "
+ users.find(
new BasicDBObject("_id", new ObjectId(
"4de73f7acd812d61b4626a77"))).toArray());
// 查询age = 24
print("find age = 24: "
+ users.find(new BasicDBObject("age", 24)).toArray());
// 查询age >= 24
print("find age >= 24: "
+ users.find(
new BasicDBObject("age", new BasicDBObject("$gte", 24)))
.toArray());
print("find age <= 24: "
+ users.find(
new BasicDBObject("age", new BasicDBObject("$lte", 24)))
.toArray());
print("查询age!=25:"
+ users.find(
new BasicDBObject("age", new BasicDBObject("$ne", 25)))
.toArray());
print("查询age in 25/26/27:"
+ users.find(
new BasicDBObject("age", new BasicDBObject(
QueryOperators.IN, new int[] { 25, 26, 27 })))
.toArray());
print("查询age not in 25/26/27:"
+ users.find(
new BasicDBObject("age", new BasicDBObject(
QueryOperators.NIN, new int[] { 25, 26, 27 })))
.toArray());
print("查询age exists 排序:"
+ users.find(
new BasicDBObject("age", new BasicDBObject(
QueryOperators.EXISTS, true))).toArray());
print("只查询age属性:"
+ users.find(null, new BasicDBObject("age", true)).toArray());
// 只查询一条数据,多条去第一条
print("findOne: " + users.findOne());
print("findOne: " + users.findOne(new BasicDBObject("age", 26)));
print("findOne: "
+ users.findOne(new BasicDBObject("age", 26),
new BasicDBObject("name", true)));
// 查询修改、删除
print("findAndRemove 查询age=25的数据,并且删除: "
+ users.findAndRemove(new BasicDBObject("age", 25)));
// 查询age=26的数据,并且修改name的值为Abc
print("findAndModify: "
+ users.findAndModify(new BasicDBObject("age", 26),
new BasicDBObject("name", "Abc")));
print("findAndModify: "
+ users.findAndModify(new BasicDBObject("age", 28), // 查询age=28的数据
new BasicDBObject("name", true), // 查询name属性
new BasicDBObject("age", true), // 按照age排序
false, // 是否删除,true表示删除
new BasicDBObject("name", "Abc"), // 修改的值,将name修改成Abc
true, true));
queryAll();
}
*//**
* mongoDB不支持联合查询、子查询,这需要我们自己在程序中完成。将查询的结果集在Java查询中进行需要的过滤即可。
* @param
* @return
*//*
public static void testOthers() {
DBObject user = new BasicDBObject();
user.put("name", "hoojo");
user.put("age", 24);
// JSON 对象转换
print("serialize: " + JSON.serialize(user));
// 反序列化
print("parse: " + JSON.parse("{ \"name\" : \"hoojo\" , \"age\" : 24}"));
print("判断temp Collection是否存在: " + db.collectionExists("temp"));
// 如果不存在就创建
if (!db.collectionExists("temp")) {
DBObject options = new BasicDBObject();
options.put("size", 20);
options.put("capped", 20);
options.put("max", 20);
print(db.createCollection("account", options));
}
// 设置db为只读
db.setReadOnly(true);
// 只读不能写入数据
db.getCollection("test").save(user);
}*/
}
以上代码,CRUD好像都有了!但是有个问题需要指出,mongodb有默认的连接池,只不过默认连接数为10,我们如果有特别需要,可以自建连接池
package com.founder.ec.util;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
/**
* mongodb连接池
* @author 五味子
* @version 2014/04/04
*/
public class DBManager{
private static Mongo mongo; //mongodb数据库操作对象
/**
*
* @param ip ip地址
* @param port 端口号
* @param poolSize 连接数
* @return Mongo操作对象
* @throws java.net.UnknownHostException 找不到主机异常
*/
public static Mongo inits(final String ip, int port, int poolSize) throws java.net.UnknownHostException,java.net.SocketException {
try{
System.setProperty("MONGO.POOLSIZE", String.valueOf(poolSize));
if (mongo == null) {
mongo = new Mongo(ip, port);
MongoOptions options = mongo.getMongoOptions();
//每个主机的连接数
options.connectionsPerHost = poolSize;
//这个控制是否在一个连接时,系统会自动重试
options.autoConnectRetry = true;
//最大等待连接的线程阻塞时间
options.maxWaitTime = 5000;
//socket超时。0是默认和无限
options.socketTimeout = 2000;
//连接超时的毫秒。0是默认和无限
options.connectTimeout = 15000;
//线程队列数,它以上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误。
options.threadsAllowedToBlockForConnectionMultiplier = 4;
}
}catch(Exception e){
e.getMessage();
}
return mongo;
}
}
方式二:log4j
这种方式比较简单,只不过只能作为添加数据用
在log4j.propertites文件中:
log4j.rootLogger=debug, stdout, R, MongoDB
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-d{MM-dd HH:mm:ss.SSS} %-5p - [%c{1}.%t] %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=D:/data/Sample.log
log4j.appender.R.MaxFileSize=1000KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-d{MM-dd HH:mm:ss.SSS} %-5p - [%c{1}.%t] %m%n
#log4j.appender.MongoDB=org.log4mongo.MongoDbAppender
#log4j.appender.MongoDB.databaseName=test
#log4j.appender.MongoDB.collectionName=testdb
#log4j.appender.MongoDB.hostname=192.168.2.86
#log4j.appender.MongoDB.port=27017
注意打上#的几段代码,应该不要解释吧!
什么?你看不懂属性文件,那你还是先补补属性文件再来看吧!
想进一步了解Mongodb,请阅读超详细的中文指南:
http://download.youkuaiyun.com/detail/u013339851/7120473