back_recharge
wangyuan 2019-01-07 10:00:52 +08:00
parent e269a68bcc
commit a3297be91f
17 changed files with 710 additions and 3 deletions

View File

@ -13,6 +13,7 @@ repositories {
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.5.9.RELEASE")
}

View File

@ -0,0 +1,123 @@
package com.ljsd.common.mogodb;
import com.mongodb.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.List;
public class LjsdMongoTemplate {
private MongoTemplate mongoTemplate;
public LjsdMongoTemplate( MongoTemplate mongoTemplate ){
this.mongoTemplate = mongoTemplate;
}
public DBCollection getCollection(String collectionName){
return mongoTemplate.getCollection(collectionName);
}
public <T> void save(T obj) throws Exception {
MongoRoot root = (MongoRoot)obj;
mongoTemplate.save(obj,root.getCollection());
root.setBsave(true);
}
public <T> List<T> findAll(String collectionName, Class<T> clazz) throws Exception {
List<T> all = mongoTemplate.findAll(clazz, collectionName);
if(all!=null && !all.isEmpty()){
T t = all.get(0);
if(t.getClass().getSuperclass() == MongoRoot.class){
for(T t1 : all){
dynamicChangeTheMongoRoot(t1, (MongoRoot) t1);
}
}
}
return all;
}
public <T> T findById(String collectionName, String id, Class<T> clazz) throws Exception {
T result = mongoTemplate.findById(id, clazz, collectionName);
if(result.getClass().getSuperclass() == MongoRoot.class){
dynamicChangeTheMongoRoot(result,(MongoRoot) result);
}
return result;
}
public void chnage(Object obj){
Class<?> clazz = obj.getClass();
}
public boolean remove(String collectionName, Object id) throws Exception {
//TODO 正确性未知,未测试
DBCollection coll = mongoTemplate.getCollection(collectionName);
DBObject doc = coll.findOne(id);
if(doc == null){
return false;
}
coll.remove(doc);
return true;
}
public void updateValue(String collectionName, BasicDBObject searchQuery, BasicDBObject dbObject){
DBCollection coll = mongoTemplate.getCollection(collectionName);
coll.update(searchQuery, dbObject);
}
public void lastUpdate() throws Exception {
MongoUpdateCacheThreadLocal.update(this);
}
public int inc(String collectionName, String id, String key){
DBCollection collection = mongoTemplate.getCollection(collectionName);
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", id);
// 使用collection的find方法查找document
DBCursor cursor = collection.find(searchQuery);
// 循环输出结果
if (cursor.hasNext()) {
BasicDBObject update= new BasicDBObject().append("$inc",new BasicDBObject().append(key, 1));
DBObject query = cursor.next();
DBObject result = collection.findAndModify(query, update);
return Integer.valueOf(result.get(key).toString())+1;
} else {
searchQuery.put(key, 1);
collection.insert(searchQuery);
return 1;
}
}
public int inc(String key){
return inc("inc_c", "inc_k", key);
}
public Object convertToMongoType(Object obj){
return this.mongoTemplate.getConverter().convertToMongoType(obj);
}
public void dynamicChangeTheMongoRoot(Object obj,MongoRoot mongoRoot) throws Exception {
Class clazz = obj.getClass();
while (clazz != null && clazz != Object.class && clazz != MongoRoot.class) {
if(clazz == MongoBase.class){
Field root = clazz.getDeclaredField("_root");
root.setAccessible(true);
root.set(obj, new WeakReference<>(mongoRoot));
return;
}
Field[] declaredFields = clazz.getDeclaredFields();
for (Field tmpField : declaredFields){
Class<?> type = tmpField.getType();
if(!MongoBase.class.isAssignableFrom(type)){
continue;
}
tmpField.setAccessible(true);
dynamicChangeTheMongoRoot(tmpField.get(obj),mongoRoot);
}
clazz = clazz.getSuperclass();
}
}
}

View File

@ -0,0 +1,85 @@
package com.ljsd.common.mogodb;
import org.springframework.data.annotation.Transient;
import java.lang.ref.WeakReference;
//使用下划线是为了在json转换时能转为正确的值
public abstract class MongoBase {
@Transient
private WeakReference<MongoRoot> _root;
private String mongoKey; //该级对应的mongodb的key
@Transient
private boolean _save;
public void init(MongoRoot root, String mongoKey, boolean _save) {
this._root = new WeakReference<>(root);
this.mongoKey = mongoKey;
this._save = _save;
}
public void init(MongoRoot root, String mongoKey) {
this._root = new WeakReference<>(root);
this.mongoKey = mongoKey;
this._save = true;
}
public void updateString(String fieldName, Object value) throws Exception {
MongoRoot mongoRoot = getMongoRoot();
if (mongoRoot == null) return;
MongoUpdateCacheThreadLocal.addUpdateRequest(this, mongoRoot.getMyMongoDBPool(), mongoRoot.getCollection(), mongoRoot.getId(),
mongoKey + "." + fieldName, value);
}
public void updateString(String fieldName, MongoBase value) throws Exception {
MongoRoot mongoRoot = getMongoRoot();
if (mongoRoot == null) return;
MongoUpdateCacheThreadLocal.addUpdateRequest(value, mongoRoot.getMyMongoDBPool(), mongoRoot.getCollection(), mongoRoot.getId(),
mongoKey + "." + fieldName, value);
}
public void removeString(String key) {
MongoRoot mongoRoot = getMongoRoot();
if (mongoRoot == null) return;
MongoUpdateCacheThreadLocal.removeRequest(this, mongoRoot.getMyMongoDBPool(), mongoRoot.getCollection(), mongoRoot.getId(),
mongoKey + "." + key);
}
private MongoRoot getMongoRoot() {
if (_root == null) {
return null;
}
MongoRoot mongoRoot = _root.get();
if (mongoRoot == null) {
return null;
}
if (_save) {
return null;
}
return mongoRoot;
}
public String getMongoKey() {
return mongoKey;
}
public void setMongoKey(String mongoKey) {
this.mongoKey = mongoKey;
}
public MongoRoot getRoot() {
return this._root.get();
}
public void setRoot(MongoRoot root) {
this._root = new WeakReference<>(root);
}
public void set_save(boolean _save) {
this._save = _save;
}
}

View File

@ -0,0 +1,79 @@
package com.ljsd.common.mogodb;
import com.mongodb.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import java.net.UnknownHostException;
@Configuration
public class MongoConfig {
// 注入配置实体
@Autowired
private MongoSettingsProperties mongoSettingsProperties;
@Bean
@ConfigurationProperties(
prefix = "mongodb.options")
MongoSettingsProperties mongoSettingsProperties() {
return new MongoSettingsProperties();
}
@Value("${spring.data.mongodb.uri}")
private String MONGO_URI;
// 覆盖默认的MongoDbFactory
@Bean
MongoDbFactory mongoDbFactory() {
//客户端配置(连接数、副本集群验证)
MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
builder.connectionsPerHost(mongoSettingsProperties.getConnectionsPerHost());
builder.minConnectionsPerHost(mongoSettingsProperties.getMinConnectionsPerHost());
builder.maxWaitTime(mongoSettingsProperties.getMaxWaitTime());
builder.socketTimeout(mongoSettingsProperties.getSocketTimeout());
MongoClientURI mongoClientURI = new MongoClientURI(MONGO_URI,builder);
MongoDbFactory mongoDbFactory = null;
try {
mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
} catch (UnknownHostException e) {
e.printStackTrace();
}
return mongoDbFactory;
}
@Bean
public MongoMappingContext mongoMappingContext() {
MongoMappingContext mappingContext = new MongoMappingContext();
return mappingContext;
}
@Bean //使用自定义的typeMapper去除写入mongodb时的“_class”字段
public MappingMongoConverter mappingMongoConverter1() throws Exception {
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.mongoDbFactory());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return converter;
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(this.mongoDbFactory(), this.mappingMongoConverter1());
}
@Bean
public LjsdMongoTemplate ljsdMongoTemplate() throws Exception {
return new LjsdMongoTemplate(this.mongoTemplate());
}
}

View File

@ -0,0 +1,13 @@
package com.ljsd.common.mogodb;
import com.ljsd.common.mogodb.test.pojo.PlayerForTest;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent;
public class MongoListen extends AbstractMongoEventListener<PlayerForTest> {
@Override
public void onAfterLoad(AfterLoadEvent<PlayerForTest> event) {
super.onAfterLoad(event);
}
}

View File

@ -0,0 +1,51 @@
package com.ljsd.common.mogodb;
import org.springframework.data.annotation.Transient;
//使用下划线是为了在json转换时能转为正确的值
public abstract class MongoRoot {
@Transient
private boolean _bsave; //是否已经保存到了数据库
@Transient
private LjsdMongoTemplate _ljsdMongoTemplate; //对应的mongodb连接池
private String id; //如果是mongodb的根则需要设置id
public MongoRoot() {
}
public MongoRoot(String id) {
this.id = id;
}
public String getId() {
return id;
}
public int _getIntId() {
return Integer.valueOf(id);
}
public void setId(String id) {
this.id = id;
}
public abstract String getCollection();
public LjsdMongoTemplate getMyMongoDBPool() {
return _ljsdMongoTemplate;
}
public boolean isBsave() {
return _bsave;
}
public void setBsave(boolean bsave) {
this._bsave = bsave;
}
public void setMyMongoDBPool(LjsdMongoTemplate _ljsdMongoTemplate) {
this._ljsdMongoTemplate = _ljsdMongoTemplate;
}
}

View File

@ -0,0 +1,14 @@
/*package com.ljsd.common.mogodb;
import com.ljsd.common.mogodb.test.pojo.PlayerForTest;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.mongodb.core.mapping.Document;
@ReadingConverter
public class MongoRootConverter implements Converter<Document, PlayerForTest> {
@Override
public PlayerForTest convert(Document source) {
System.out.println("123");
return null;
}
}*/

View File

@ -0,0 +1,72 @@
package com.ljsd.common.mogodb;
import org.springframework.stereotype.Component;
@Component
public class MongoSettingsProperties {
private int maxWaitTime;
private int connectTimeout;
private int socketTimeout;
private int threadsAllowedToBlockForConnectionMultiplier;
private int connectionsPerHost;
private int minConnectionsPerHost;
private int maxConnectionIdleTime;
public int getMaxWaitTime() {
return maxWaitTime;
}
public void setMaxWaitTime(int maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}
public int getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public int getSocketTimeout() {
return socketTimeout;
}
public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
}
public int getThreadsAllowedToBlockForConnectionMultiplier() {
return threadsAllowedToBlockForConnectionMultiplier;
}
public void setThreadsAllowedToBlockForConnectionMultiplier(int threadsAllowedToBlockForConnectionMultiplier) {
this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
}
public int getConnectionsPerHost() {
return connectionsPerHost;
}
public void setConnectionsPerHost(int connectionsPerHost) {
this.connectionsPerHost = connectionsPerHost;
}
public int getMinConnectionsPerHost() {
return minConnectionsPerHost;
}
public void setMinConnectionsPerHost(int minConnectionsPerHost) {
this.minConnectionsPerHost = minConnectionsPerHost;
}
public int getMaxConnectionIdleTime() {
return maxConnectionIdleTime;
}
public void setMaxConnectionIdleTime(int maxConnectionIdleTime) {
this.maxConnectionIdleTime = maxConnectionIdleTime;
}
}

View File

@ -0,0 +1,71 @@
package com.ljsd.common.mogodb;
import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.mongodb.BasicDBObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MongoUpdateCache {
class UpdateRequest {
MongoBase mongoBase;
String fullKey;
Object value;
int opCode;
UpdateRequest(String fullKey, Object value, int opCode, MongoBase mongoBase) {
this.fullKey = fullKey;
this.value = value;
this.opCode = opCode;
this.mongoBase = mongoBase;
}
}
//key:String, collection + ":" + id
private final Map<String, List<UpdateRequest>> requestMap = new HashMap<>();
protected void addUpdateRequest(MongoBase mongoBase, String collection, String id, String fullKey, Object value, int opCode) {
String key = collection + ":" + id;
List<UpdateRequest> listRequest = requestMap.get(key);
if (listRequest == null) {
listRequest = new ArrayList<UpdateRequest>();
requestMap.put(key, listRequest);
}
UpdateRequest request = new UpdateRequest(fullKey, value, opCode, mongoBase);
listRequest.add(request);
}
protected void update(LjsdMongoTemplate ljsdMongoTemplate) throws IllegalAccessException {
BasicDBObject searchQuery = new BasicDBObject();
for (Map.Entry<String, List<UpdateRequest>> entry : requestMap.entrySet()) {
String[] strs = entry.getKey().split(":");
String collection = strs[0];
String id = strs[1];
searchQuery.put("_id", id);
BasicDBObject valueDBObj = new BasicDBObject();
BasicDBObject dbobj = new BasicDBObject();
BasicDBObject removedbobj = new BasicDBObject();
for (UpdateRequest request : entry.getValue()) {
if (request.opCode == 2) {
removedbobj.append(request.fullKey, request.value);
continue;
}
valueDBObj.append(request.fullKey, ljsdMongoTemplate.convertToMongoType(request.value));
request.mongoBase.set_save(false);
}
dbobj.append("$set", valueDBObj);
if (!removedbobj.isEmpty()) {
dbobj.append("$unset", removedbobj);
}
ljsdMongoTemplate.updateValue(collection, searchQuery, dbobj);
}
requestMap.clear();
}
}

View File

@ -0,0 +1,37 @@
package com.ljsd.common.mogodb;
import java.util.HashMap;
import java.util.Map;
public class MongoUpdateCacheThreadLocal {
private final static ThreadLocal<Map<LjsdMongoTemplate, MongoUpdateCache>> mongoUpdateCacheThreadLocal = new ThreadLocal<>();
private static MongoUpdateCache getMongoUpdateCache(LjsdMongoTemplate ljsdMongoTemplate) {
Map<LjsdMongoTemplate, MongoUpdateCache> mongoUpdateCacheMap = mongoUpdateCacheThreadLocal.get();
if (mongoUpdateCacheMap == null) {
mongoUpdateCacheMap = new HashMap<LjsdMongoTemplate, MongoUpdateCache>();
mongoUpdateCacheThreadLocal.set(mongoUpdateCacheMap);
}
MongoUpdateCache mongoUpdateCache = mongoUpdateCacheMap.get(ljsdMongoTemplate);
if (mongoUpdateCache == null) {
mongoUpdateCache = new MongoUpdateCache();
mongoUpdateCacheMap.put(ljsdMongoTemplate, mongoUpdateCache);
}
return mongoUpdateCache;
}
protected static void addUpdateRequest(MongoBase mongoBase, LjsdMongoTemplate ljsdMongoTemplate, String collection, String id, String fullKey, Object value) {
MongoUpdateCache mongoUpdateCache = getMongoUpdateCache(ljsdMongoTemplate);
mongoUpdateCache.addUpdateRequest(mongoBase, collection, id, fullKey, value, 1);
}
protected static void removeRequest(MongoBase mongoBase, LjsdMongoTemplate ljsdMongoTemplate, String collection, String id, String fullKey) {
MongoUpdateCache mongoUpdateCache = getMongoUpdateCache(ljsdMongoTemplate);
mongoUpdateCache.addUpdateRequest(mongoBase, collection, id, fullKey, "", 2);
}
protected static void update(LjsdMongoTemplate ljsdMongoTemplate) throws IllegalAccessException {
MongoUpdateCache mongoUpdateCache = getMongoUpdateCache(ljsdMongoTemplate);
mongoUpdateCache.update(ljsdMongoTemplate);
}
}

View File

@ -0,0 +1,72 @@
package com.ljsd.common.mogodb.test;
import com.ljsd.common.mogodb.LjsdMongoTemplate;
import com.ljsd.common.mogodb.test.pojo.BaseInfoForTest;
import com.ljsd.common.mogodb.test.pojo.PlayerForTest;
import com.mongodb.MongoClientURI;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import java.net.UnknownHostException;
public class TestMongo {
private static LjsdMongoTemplate ljsdMongoTemplate;
public static void main(String[] args) {
try {
ljsdMongoTemplate = getLjsdMongoTemplate();
PlayerForTest.init(ljsdMongoTemplate);
//save();
PlayerForTest one = findOne();
update(one);
System.out.println();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void update(PlayerForTest playerForTest) throws Exception {
BaseInfoForTest baseInfoForTest = playerForTest.getBaseInfoForTest();
baseInfoForTest.setName("222222522");
ljsdMongoTemplate.lastUpdate();
}
public static PlayerForTest findOne() throws Exception {
return ljsdMongoTemplate.findById(PlayerForTest.getCollectionName(),"1",PlayerForTest.class);
}
public static void save() throws Exception {
BaseInfoForTest baseInfoForTest = new BaseInfoForTest();
baseInfoForTest.setAge(10);
baseInfoForTest.setName("test");
PlayerForTest playerForTest = new PlayerForTest(1,baseInfoForTest);
ljsdMongoTemplate.save(playerForTest);
System.out.println(ljsdMongoTemplate);
}
public static LjsdMongoTemplate getLjsdMongoTemplate() throws UnknownHostException {
SimpleMongoDbFactory simpleMongoDbFactory = new SimpleMongoDbFactory(new MongoClientURI("mongodb://60.1.1.14:27017/ysj_20215999999"));
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(simpleMongoDbFactory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
// MongoTemplate mongoTemplate = new MongoTemplate(simpleMongoDbFactory, converter);
/* MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
mongoMapping.setCustomConversions(customConversions()); // tell mongodb to use the custom converters
mongoMapping.afterPropertiesSet();*/
return new LjsdMongoTemplate(new MongoTemplate(simpleMongoDbFactory, converter));
}
/* private static CustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
converterList.add(new MongoRootConverter());
return new CustomConversions(converterList);
}*/
}

View File

@ -0,0 +1,44 @@
package com.ljsd.common.mogodb.test.pojo;
import com.ljsd.common.mogodb.MongoBase;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class BaseInfoForTest extends MongoBase {
private String name;
private int age;
private Map<String,String> otherInfoMsg = new ConcurrentHashMap<>();
public BaseInfoForTest(){
}
public String getName() {
return name;
}
public void setName(String name) throws Exception {
updateString("name", name);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
updateString("age", name);
this.age = age;
}
public Map<String, String> getOtherInfoMsg() {
return otherInfoMsg;
}
public void setOtherInfoMsg(Map<String, String> otherInfoMsg) throws Exception {
updateString("otherInfoMsg", name);
this.otherInfoMsg = otherInfoMsg;
}
}

View File

@ -0,0 +1,45 @@
package com.ljsd.common.mogodb.test.pojo;
import com.ljsd.common.mogodb.LjsdMongoTemplate;
import com.ljsd.common.mogodb.MongoRoot;
public class PlayerForTest extends MongoRoot {
private final static String _COLLECTION_NAME = "play_test";
private BaseInfoForTest baseInfoForTest;
private static LjsdMongoTemplate _ljsdMongoTemplate;
public static void init( LjsdMongoTemplate ljsdMongoTemplate){
_ljsdMongoTemplate = ljsdMongoTemplate;
}
public PlayerForTest(int playerId,BaseInfoForTest baseInfoForTest){
setId(String.valueOf(playerId));
this.baseInfoForTest = baseInfoForTest;
baseInfoForTest.init(this,"baseInfoForTest",false);
}
public PlayerForTest(){
setMyMongoDBPool(_ljsdMongoTemplate);
this.baseInfoForTest = new BaseInfoForTest();
baseInfoForTest.init(this,"baseInfoForTest",false);
}
public BaseInfoForTest getBaseInfoForTest() {
return baseInfoForTest;
}
public void setBaseInfoForTest(BaseInfoForTest baseInfoForTest) {
this.baseInfoForTest = baseInfoForTest;
}
public static String getCollectionName() {
return _COLLECTION_NAME;
}
@Override
public String getCollection() {
return _COLLECTION_NAME;
}
}

View File

@ -18,11 +18,11 @@ dependencies {
compile project(":netty")
compile project(":hotfix")
compile project(":common")
compile("org.javassist:javassist:3.18.2-GA")
compile("org.springframework.boot:spring-boot:1.5.9.RELEASE")
compile("org.springframework.boot:spring-boot-starter-test:1.5.9.RELEASE")
compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.5.9.RELEASE")
compile("org.springframework.boot:spring-boot-starter-data-redis:1.5.9.RELEASE")
compile("io.netty:netty-all:4.0.21.Final")
compile("com.google.protobuf:protobuf-java:2.5.0")

View File

@ -1,4 +1,4 @@
package com.ljsd.jieling;
package com.ljsd;
import com.ljsd.jieling.handler.BaseHandler;
import com.ljsd.jieling.logic.STableManager;

View File

@ -2,7 +2,7 @@ package com.ljsd.jieling.network.server;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
import com.ljsd.jieling.GameApplication;
import com.ljsd.GameApplication;
import com.ljsd.jieling.handler.BaseHandler;
import com.ljsd.jieling.netty.cocdex.PacketNetData;
import com.ljsd.jieling.netty.handler.GameMessageHandler;