【发布时间】:2021-11-21 05:26:24
【问题描述】:
我有一个本地 MongoDB 数据库,其中包含一个包含玩家数据的集合,负责该集合的类是 PlayersDataDB。
我还有一个自定义类 MyDocument,它扩展了 org.bson.Document,它包含一些自定义方法,如 getColoredString(String key) 和一个自定义 getEmbedded(String path, boolean create),它从像 "subDoc1.subDoc2" 这样的字符串中查找嵌入并创建它是否丢失和如果create==true
我想做什么:我想在每次编辑 MyDocument 时保存到数据库中,所以每次我使用 put()、append()、remove() 时.
例如,如果一个名为“root”的基础文档
我得到嵌入的“doc1.doc2”并输入一个字符串“test:yes”,我希望它上升到根文档(代码中名为parent)并将其保存到集合和密钥中,通过在构造函数中。
我的问题:但是现在,当我测试它时,它在终端中显示“正在保存”,但是当我查看数据库时没有任何变化。
这个例子创建了文档,它们出现在数据库中:
new PlayersDataDB(uuid).getDocument().getEmbedded("doc1.doc2", true ).put("t1","yes" );
但是当我重用它时:
new PlayersDataDB(uuid).getDocument().getEmbedded("doc1.doc2", true ).put("test","yes" );
“doc1”和“doc2”子文档已经存在,它显示在终端“putting test -> yes”和“saving”但数据库中没有出现
注意:此代码用于 Minecraft 插件,其中每个玩家都有 1 个唯一的 UUID,因此数据库为每个玩家有 1 个唯一的文档
PlayersDataDB 类,负责这个集合:
public static final MongoCollection<Document> players = MongoDB.getDB()
.getCollection( "playersData" );
public final Document uuidDocument;
private MyDocument document;
public PlayersDataDB( UUID uuid ) {
uuidDocument = new Document( "uuid", "player's uuid" );
Document foundDoc = players.find( uuidDocument ).first();
if( foundDoc == null ) {
this.document = new MyDocument( players, uuidDocument )
.append( "uuid", player.getUniqueId().toString() )
.append( "nickname", "MyName" )
.append( "group", "default" )
.append( "lastTimeSeen", "Is online" );
} else { // as i can't cast Document to MyDocument, i use putall() to copy all data
this.document = new MyDocument( players, uuidDocument );
this.document.putAll( foundDoc );
}
}
public MyDocument getDocument() {
return document;
}
这里是 MyDocument 类:
问题出在我的自定义getEmbedded(String, boolean) 中,也可能在save() 中
import com.mongodb.client.MongoCollection;
import org.bson.Document;
import java.util.Map;
public class MyDocument extends Document {
private MongoCollection<Document> collectionOfCurrentDoc;
private Document keyWhereSave;
private MyDocument parent;
// either the document is the root, it's the one i need to save
public MyDocument( MongoCollection<Document> col, Document keyWhereSave ) {
super();
collectionOfCurrentDoc = col;
this.keyWhereSave = keyWhereSave;
}
// or it's a sub document, so it have a parent
public MyDocument( MyDocument parent ) {
super( key, value );
this.parent = parent;
}
public String getColoredString( String key ) {
String res = super.getString( key );
if( res != null )
res = "colored " + res;
//using other classes here so i put this for example
return res;
}
public String getColoredString( String path, String key ) {
MyDocument embedded = getEmbedded( path, false );
if( embedded != null )
return embedded.getColoredString( key );
return null;
}
public MyDocument getEmbedded( String path, boolean createIfMissing ) {
MyDocument value = this;
for( String key : path.split( "\\." ) ) {
Document foundDoc = value.get( key, Document.class );
MyDocument nextEmbedded = new MyDocument( value );
if( foundDoc == null ) {
System.out.println( "%s embedded don't exist".formatted( key ) );
if( createIfMissing ) {
System.out.println( "creating embedded %s".formatted( key ) );
value.put( key, nextEmbedded );
} else
return null;
} else {
System.out.println( "embedded already exist" );
nextEmbedded.putAll( foundDoc );
}
System.out.println( "-".repeat( 20 ) );
value = nextEmbedded;
}
return value;
}
public void save() {
MyDocument docToSave = this;
while( docToSave.parent != null ) {
System.out.println( "found parent" );
docToSave = docToSave.parent;
}
System.out.println( "saving " );
docToSave.collectionOfCurrentDoc.replaceOne( docToSave.keyWhereSave, docToSave );
}
@Override
public Object put( String key, Object value ) {
System.out.println( "putting %s -> %s".formatted( key, value ) );
Object res = super.put( key, value );
save();
return res;
}
@Override
public Object remove( Object key ) {
Object res = super.remove( key ); ;
save();
return res;
}
public MyDocument append( String key, Object value ) {
super.append( key, value );
save();
return this;
}
}
【问题讨论】: