[MongoDB] Java异步操作Mongo示例
一、问题描述
笔记。
二、版本说明
以下为本次示例相关环境的说明:
1、数据库
MongoDB server version: 4.2.10
2、JDK版本
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
3、依赖
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>4.2.2</version>
</dependency>
三、相关代码
参考:QuickStart和QuickTour。
1、ObservableSubscriber.java和ConsumerSubscriber.java
这两个类照搬了QuickTour中的实现。
// ObservableSubscriber.java
public class ObservableSubscriber<T> implements Subscriber<T> {
// private final List<T> received; // 不作暂存
private final List<RuntimeException> errors;
private final CountDownLatch latch;
private volatile Subscription subscription;
private volatile boolean completed;
/**
* Construct an instance
*/
public ObservableSubscriber() {
// this.received = new ArrayList<>();
this.errors = new ArrayList<>();
this.latch = new CountDownLatch(1);
}
@Override
public void onSubscribe(final Subscription s) {
subscription = s;
}
@Override
public void onNext(final T t) {
// received.add(t);
}
@Override
public void onError(final Throwable t) {
if (t instanceof RuntimeException) {
errors.add((RuntimeException) t);
} else {
errors.add(new RuntimeException("Unexpected exception", t));
}
onComplete();
}
@Override
public void onComplete() {
completed = true;
latch.countDown();
}
/**
* Gets the subscription
*
* @return the subscription
*/
public Subscription getSubscription() {
return subscription;
}
/**
* Get error from subscription
*
* @return the error, which may be null
*/
public RuntimeException getError() {
if (errors.size() > 0) {
return errors.get(0);
}
return null;
}
/**
* Await completion or error
*
* @return this
*/
public ObservableSubscriber<T> await() {
return await(60, TimeUnit.SECONDS);
}
/**
* Await completion or error
*
* @param timeout how long to wait
* @param unit the time unit
* @return this
*/
public ObservableSubscriber<T> await(final long timeout, final TimeUnit unit) {
subscription.request(Integer.MAX_VALUE);
try {
if (!latch.await(timeout, unit)) {
throw new MongoTimeoutException("Publisher onComplete timed out");
}
} catch (InterruptedException e) {
throw new MongoInterruptedException("Interrupted waiting for observeration", e);
}
if (!errors.isEmpty()) {
throw errors.get(0);
}
return this;
}
}
// ConsumerSubscriber.java
public class ConsumerSubscriber<T> extends ObservableSubscriber<T> {
private final Consumer<T> consumer;
public ConsumerSubscriber(final Consumer<T> consumer) {
this.consumer = consumer;
}
@Override
public void onNext(T t) {
super.onNext(t);
this.consumer.accept(t);
}
}
2、调用程序ReactiveStreamDemo.java
// ReactiveStreamDemo.java
public class ReactiveStreamDemo {
public static void main(String[] args) {
long start = System.currentTimeMillis();
MongoClient client = MongoClients.create("mongodb://gavin:123456@192.168.0.100/crawlers");
MongoDatabase database = client.getDatabase("crawlers");
MongoCollection<FootballTeam> collection = database.getCollection("fb_team_details", FootballTeam.class);
// 实体类自动映射
CodecRegistry registry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(
PojoCodecProvider.builder().automatic(true).build()
)
);
collection = collection.withCodecRegistry(registry);
FindPublisher<FootballTeam> findPublisher = collection.find(FootballTeam.class).limit(2);
AtomicInteger count = new AtomicInteger(0);
ObservableSubscriber<FootballTeam> subscriber = new ConsumerSubscriber<>(document -> {
count.addAndGet(1);
System.out.println(document);
});
findPublisher.subscribe(subscriber);
// 等待任务结束
subscriber.await(30 * 60, TimeUnit.SECONDS);
long end = System.currentTimeMillis();
System.out.printf("\ncount: %d, time: %f seconds\n", count.get(), (end - start) / 1000.0);
}
}
输出结果:
FootballTeam{id=604f7af6a0eaf9ea4bfb2445, info=FootballTeamInfo{id='null', name_cn='布莱克本', name_en='Blackburn Rovers', league='英冠', city='兰开郡', players='29'}, players=[FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='特里布尔', number='19', position='中场', age='28', height='181', weight='72', birthday='1993-03-09', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='埃利奥特', number='16', position='前锋', age='17', height='170', weight='64', birthday='2003-04-04', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='贝里斯', number='22', position='后卫', age='19', height='188', weight='82', birthday='2002-01-30', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='科里.伊文斯', number='29', position='中场', age='30', height='180', weight='70', birthday='1990-07-30', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='托马斯·卡明斯基', number='1', position='守门员', age='28', height='190', weight='70', birthday='1992-10-23', habit_foot='左右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='艾恩斯利·皮尔斯', number='13', position='守门员', age='22', height='185', weight='0', birthday='1998-04-23', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='斯科特·沃顿', number='28', position='后卫', age='23', height='182', weight='0', birthday='1997-10-03', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='阿亚拉', number='5', position='后卫', age='30', height='190', weight='84', birthday='1990-11-07', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='唐宁', number='6', position='中场', age='36', height='180', weight='0', birthday='1984-07-22', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='道格拉斯', number='15', position='后卫', age='31', height='176', weight='64', birthday='1989-09-04', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='约翰逊', number='4', position='中场', age='33', height='178', weight='0', birthday='1987-04-28', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='达拉赫·勒尼汉', number='26', position='后卫', age='26', height='187', weight='76', birthday='1994-03-16', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='Amari'i Bell', number='17', position='后卫', age='26', height='180', weight='0', birthday='1994-05-05', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='瑞恩·尼亚姆贝', number='2', position='后卫', age='23', height='183', weight='76', birthday='1997-12-04', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='刘易斯·特拉维斯', number='27', position='中场', age='23', height='183', weight='0', birthday='1997-10-16', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='积及·迪云樸', number='18', position='中场', age='22', height='177', weight='0', birthday='1998-12-28', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='祖·罗斯韦尔', number='8', position='中场', age='26', height='185', weight='77', birthday='1995-01-11', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='本内特', number='31', position='中场', age='32', height='179', weight='69', birthday='1988-12-18', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='达克', number='23', position='中场', age='27', height='175', weight='71', birthday='1993-12-31', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='阿姆斯特朗', number='7', position='前锋', age='24', height='173', weight='69', birthday='1997-02-10', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='本·布雷顿', number='20', position='前锋', age='21', height='183', weight='75', birthday='1999-04-18', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='贾拉德-布兰斯韦特', number='30', position='后卫', age='18', height='195', weight='0', birthday='2002-06-27', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='安东尼斯·斯特吉亚基斯', number='41', position='守门员', age='21', height='196', weight='0', birthday='1999-03-16', habit_foot='左右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='乔丹·伊斯特姆', number='45', position='守门员', age='19', height='181', weight='0', birthday='2001-09-08', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='巴克利', number='21', position='中场', age='21', height='173', weight='0', birthday='1999-10-13', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='乔·兰金', number='24', position='后卫', age='21', height='183', weight='0', birthday='1999-07-26', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='刘易斯·霍尔特比', number='10', position='中场', age='30', height='176', weight='0', birthday='1990-09-18', habit_foot='左脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='提尔希斯多兰', number='39', position='前锋', age='19', height='170', weight='0', birthday='2001-12-28', habit_foot='右脚'}, FootballPlayer{id='null', team_id='36', team_name='布莱克本', name='山姆·加拉格尔', number='9', position='前锋', age='25', height='193', weight='0', birthday='1995-09-15', habit_foot='右脚'}], trainer=[FootballTrainer{id='null', name='Tony Mowbray', position='主教练'}]}
FootballTeam{id=604f7af6a0eaf9ea4bfb2447, info=FootballTeamInfo{id='null', name_cn='卢顿', name_en='Luton Town', league='英冠', city='', players='32'}, players=[FootballPlayer{id='null', team_id='135', team_name='卢顿', name='布里', number='26', position='后卫', age='23', height='178', weight='74', birthday='1997-12-11', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='加洛维', number='23', position='后卫', age='24', height='186', weight='0', birthday='1996-03-17', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='迪尤斯伯里-哈尔', number='22', position='中场', age='22', height='178', weight='0', birthday='1998-09-06', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='因斯', number='39', position='前锋', age='29', height='178', weight='0', birthday='1992-01-30', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='西蒙·斯拉格', number='12', position='守门员', age='27', height='191', weight='84', birthday='1993-03-17', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='汤姆·洛克', number='15', position='后卫', age='26', height='184', weight='75', birthday='1994-12-03', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='乔·莫雷尔', number='28', position='中场', age='24', height='185', weight='81', birthday='1997-01-03', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='詹姆斯·科林斯', number='19', position='前锋', age='30', height='188', weight='86', birthday='1990-12-01', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='迪昂·佩雷拉', number='30', position='前锋', age='21', height='175', weight='0', birthday='1999-03-25', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='阿德巴约', number='29', position='前锋', age='23', height='193', weight='0', birthday='1998-01-07', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='谢', number='1', position='守门员', age='29', height='188', weight='76', birthday='1991-06-16', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='索尼·布拉德利', number='5', position='后卫', age='29', height='193', weight='90', birthday='1991-09-13', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='格伦雷', number='16', position='中场', age='26', height='184', weight='73', birthday='1994-09-03', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='丹.波茨', number='3', position='后卫', age='26', height='173', weight='0', birthday='1994-04-13', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='马蒂.皮尔森', number='6', position='后卫', age='27', height='190', weight='72', birthday='1993-08-03', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='Pelly-Ruddock Mpanzu', number='17', position='中场', age='26', height='175', weight='0', birthday='1994-03-22', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='伯里', number='8', position='中场', age='28', height='177', weight='72', birthday='1992-07-12', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='卡泽格·卢阿卢阿', number='25', position='前锋', age='30', height='180', weight='76', birthday='1990-12-10', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='科尔尼克', number='7', position='前锋', age='25', height='180', weight='84', birthday='1995-04-09', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='希尔顿', number='9', position='前锋', age='32', height='183', weight='71', birthday='1989-02-25', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='乔治·蒙库尔', number='14', position='中场', age='27', height='175', weight='64', birthday='1993-08-18', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='克拉克', number='18', position='前锋', age='27', height='183', weight='73', birthday='1993-09-22', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='山姆·诺姆比', number='27', position='前锋', age='22', height='180', weight='0', birthday='1998-10-22', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='E.凯恩', number='32', position='中场', age='30', height='168', weight='84', birthday='1990-07-10', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='卡尔·奈史密斯', number='24', position='前锋', age='29', height='186', weight='78', birthday='1992-02-18', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='顿尼克利夫', number='4', position='中场', age='28', height='183', weight='0', birthday='1992-12-30', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='TQ Addy', number='-', position='前锋', age='19', height='0', weight='0', birthday='2002-02-01', habit_foot=''}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='Tiernan Parker', number='31', position='守门员', age='19', height='185', weight='0', birthday='2001-08-04', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='马丁·克拉尼', number='2', position='后卫', age='34', height='183', weight='0', birthday='1986-09-26', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='科里黑豹', number='35', position='后卫', age='20', height='186', weight='0', birthday='2000-10-19', habit_foot='左脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='杰克·佩克', number='34', position='中场', age='21', height='180', weight='0', birthday='2000-01-09', habit_foot='右脚'}, FootballPlayer{id='null', team_id='135', team_name='卢顿', name='Jack Chambers', number='-', position='中场', age='20', height='173', weight='0', birthday='2000-07-12', habit_foot=''}], trainer=[FootballTrainer{id='null', name='Nathan Jones', position='主教练'}]}
count: 2, time: 2.831000 seconds
参考:
1、QuickStart;
2、QuickTour。