MongoDB:使用Spring数据添加计数器

在我的博客应用程序中,您可以查看任何用户的个人资料,例如,我的个人资料页面将为http://www.jiwhiz.com/profile/user1,“user1”是我在系统中的用户ID。 在MongoDB中,每个文档对象都会有一个唯一的标识符,通常我们将其存储为String,因此我有一个BaseEntity类:

@Document
@SuppressWarnings('serial')
public abstract class BaseEntity implements Serializable {@Idprivate String id;
…
}

但是系统生成的ID通常很长,我想在UserAccount类中生成自己的userId:

@Document(collection = 'UserAccount')
public class UserAccount extends BaseEntity implements SocialUserDetails {@Indexedprivate String userId;private UserRoleType[] roles;private String email;private String displayName;private String imageUrl;private String webSite;
...
}

生成的userId非常简单,只是带有序列号的'user',例如,我是第一个用户,因此我的userId是'User1',下一个已注册的用户将是'User2',依此类推。 MongoDB的序列号生成器,为我提供唯一的序列号。 该操作将返回当前序列号,并增加数据库中的序列号。 在MongoDB中,命令findAndModify自动修改并返回单个文档。 因此,我们可以使用此命令来查询序列号并通过$ inc函数对其进行增加。

首先,我们创建一个Counter类来存储用于不同目的的序列号,例如userId:

@SuppressWarnings('serial')
@Document(collection = 'Counter')
public class Counter extends BaseEntity{private String name;private long sequence;...
}

由于我们将以特殊方式使用计数器,因此无需存储库。 我只是使用以下方法创建CounterService来返回下一个用户ID:

public interface CounterService {long getNextUserIdSequence();
}

该实现将使用findAndModify来获取下一个序列:

public class CounterServiceImpl implements CounterService {public static final String USER_ID_SEQUENCE_NAME = 'user_id';private final MongoTemplate mongoTemplate;@Injectpublic CounterServiceImpl(MongoTemplate mongoTemplate){this.mongoTemplate = mongoTemplate;}@Overridepublic long getNextUserIdSequence() {return increaseCounter(USER_ID_SEQUENCE_NAME);}private long increaseCounter(String counterName){Query query = new Query(Criteria.where('name').is(counterName));Update update = new Update().inc('sequence', 1);Counter counter = mongoTemplate.findAndModify(query, update, Counter.class); // return old Counter objectreturn counter.getSequence();}
}

使用这种方法,您可以根据需要添加任意数量的序列,只需为其命名即可。 例如,您可以记录对您的网站的访问,因此可以添加一个类似logVisit()的方法,该方法increaseCounter()使用诸如“ visit_num”之类的名称来调用私有方法logVisit() 。 在此示例中,我们不将Spring Data Repository用于Counter文档,而是直接使用MongoTemplate 。 从我的MongoConfig类扩展了AbstractMongoConfiguration ,该类暴露了MongoTemplate bean,我们可以轻松地将MongoTemplate注入其他配置bean中,例如CounterService

@Configuration
class MainAppConfig {
...@Beanpublic CounterService counterService(MongoTemplate mongoTemplate) {return new CounterServiceImpl(mongoTemplate);}
...
}

在任何环境中开始运行您的应用之前,您必须首先设置一个Counter文档。 只需在MongoDB Shell中键入以下脚本:

db.Counter.insert({ 'name' : 'user_id', sequence : 1})

好的,这些是准备用户ID序列生成器的步骤。 但是,当我们要将新用户添加到系统中时,如何使用它呢? 现在变得非常容易。 我们将具有一个AccountService ,它具有createUserAccount方法,用于在用户首次登录时创建一个新的UserAccount

public interface AccountService extends SocialUserDetailsService, UserDetailsService, UserIdExtractor {UserAccount findByUserId(String userId);List<UserAccount> getAllUsers();List<UserSocialConnection> getConnectionsByUserId(String userId);UserAccount createUserAccount(ConnectionData data);
}

在我们的实现类AccountServiceImpl ,我们可以使用CounterService ,请参见下面的突出显示的代码:

public class AccountServiceImpl implements AccountService {private final UserAccountRepository accountRepository;private final UserSocialConnectionRepository userSocialConnectionRepository;private final CounterService counterService;@Injectpublic AccountServiceImpl(UserAccountRepository accountRepository, UserSocialConnectionRepository userSocialConnectionRepository, CounterService counterService) {this.accountRepository = accountRepository;this.userSocialConnectionRepository = userSocialConnectionRepository;this.counterService = counterService;}@Overridepublic UserAccount findByUserId(String userId) {return accountRepository.findByUserId(userId);}@Overridepublic List<UserAccount> getAllUsers() {return accountRepository.findAll();}@Overridepublic List<UserSocialConnection> getConnectionsByUserId(String userId){return this.userSocialConnectionRepository.findByUserId(userId);}@Overridepublic UserAccount createUserAccount(ConnectionData data) {UserAccount account = new UserAccount();account.setUserId('user' + this.counterService.getNextUserIdSequence());account.setDisplayName(data.getDisplayName());account.setImageUrl(data.getImageUrl());account.setRoles(new UserRoleType[] { UserRoleType.ROLE_USER });this.accountRepository.save(account);return account;}@Overridepublic SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException, DataAccessException {UserAccount account = findByUserId(userId);if (account == null) {throw new UsernameNotFoundException('Cannot find user by userId ' + userId);}return account;}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {return loadUserByUserId(username);}@Overridepublic String extractUserId(Authentication authentication) {if (authentication instanceof SocialAuthenticationToken) {SocialAuthenticationToken token = (SocialAuthenticationToken) authentication;if (token.getPrincipal() instanceof SocialUserDetails) {return ((SocialUserDetails) token.getPrincipal()).getUserId();}}return null;}}

Java配置代码将它们结合在一起以用于AccountService:

@Configuration
class MainAppConfig {
...@Beanpublic AccountService accountService(MongoTemplate mongoTemplate, UserAccountRepository accountRepository,UserSocialConnectionRepository userSocialConnectionRepository) {AccountServiceImpl service = new AccountServiceImpl(accountRepository, userSocialConnectionRepository,counterService(mongoTemplate));return service;}
...
}

我们什么时候调用AccountService.createUserAccount() ? 在用户首次尝试登录时,系统找不到现有的UserAccount ,因此将调用插入MongoUsersConnectionRepositoryConnectionSignUp bean。 (有关其他与Spring社交相关的代码,请参阅我的上一篇文章 。)因此ConnectionSignUp会将ConnectionData传递给AccountService.createUserAccount()

public class AutoConnectionSignUp implements ConnectionSignUp{private final AccountService accountService;@Injectpublic AutoConnectionSignUp(AccountService accountService){this.accountService = accountService;}public String execute(Connection<?> connection) {ConnectionData data = connection.createData();UserAccount account = this.accountService.createUserAccount(data);return account.getUserId();}
}

我对Spring Data MongoDB的经验非常积极。 它在提供基本的CRUD功能以及丰富的查询功能方面非常强大,并且您无需编写任何实现代码。 如果必须使用MongoDB的特殊命令,则MongoTemplate足够灵活,可以满足您的要求。

参考: MongoDB:在Jiwhiz博客上从我们的JCG合作伙伴 Yuan Ji 添加一个CounterWithSpring数据 。

翻译自: https://www.javacodegeeks.com/2013/03/mongodb-add-a-counter-with-spring-data.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2+node+mysql demo总结

1.App.vue中&#xff1a; 2.在main.js中的new vueRouter里设置mode:history或者hash &#xff1b;设置{path:/,redirect:home}默认进入的路径&#xff1b;设置linkActiveClass改变路由激活时的class名&#xff1b;也定义全局基本样式和全局过滤器等&#xff0c;例如&#xff1a…

常见文本样式及标签

本文设计到常见对文档的处理样式&#xff0c;和块&#xff0c;行标签的特点。 没用什么重要内容&#xff0c;只是自己的一些知识点的回忆&#xff0c;对以前知识的一个梳理过程&#xff0c;望某懒虫加油&#xff01;&#xff01;&#xff01; <!DOCTYPE html> <html l…

寻找内存泄漏:一个案例研究

一周前&#xff0c;我被要求修复一个有内存泄漏问题的webapp。 考虑到过去两年左右的时间里我已经看到并修复了数百个泄漏&#xff0c;我想这有多难。 但是事实证明这是一个挑战。 12小时后&#xff0c;我发现该应用程序中不少于5个漏洞&#xff0c;并设法修复了其中4个漏洞。…

matlab中求积函数,MATLAB软件及高斯勒让德求积公式MATLAB软件及高斯勒让德求积公式.doc...

MATLAB软件及高斯勒让德求积公式MATLAB软件及高斯勒让德求积公式数 值 分 析 课 程 实 验 报 告2012—2013学年度 第二学期系别&#xff1a;数学与计算机科学学院实验课程数值分析班 级10级数学与应用数学2班学 号05姓 名杜宁峰指导教师陈耀庚实验题目学习编写高斯-勒让德计算程…

[HNOI2015] 落忆枫音

题目描述 「恒逸&#xff0c;你相信灵魂的存在吗&#xff1f;」 郭恒逸和姚枫茜漫步在枫音乡的街道上。望着漫天飞舞的红枫&#xff0c;枫茜突然问出这样一个问题。 「相信吧。不然我们是什么&#xff0c;一团肉吗&#xff1f;要不是有灵魂......我们也不可能再见到你姐姐吧。」…

border,padding,margin盒模型理解

安静的敲着键盘&#xff0c;已势不可挡的姿势逼近php&#xff0c;我想我是一个幸福的人&#xff0c;未来不可期&#xff0c;做好现在&#xff0c;偶尔写着自己能看懂的API,慢慢悠悠的回味一下前端基础知识。 本文盒模型理解。 <!DOCTYPE html> <html lang"en&qu…

我的Java自定义线程池执行器

ThreadPoolExecutor是Java并发api添加的一项功能&#xff0c;可以有效地维护和重用线程&#xff0c;因此我们的程序不必担心创建和销毁线程&#xff0c;而将精力放在核心功能上。 我创建了一个自定义线程池执行程序&#xff0c;以更好地了解线程池执行程序的工作方式。 功能性…

php中mysqlstat函数,PHP函数mysql_stat介绍

&#xfeff;定义和用法mysql_stat() 函数返回 MySQL 服务器的当前系统状态。如果成功&#xff0c;则该函数返回状态。如果失败&#xff0c;则返回 false。语法mysql_stat(connection)提示和注释注释&#xff1a;mysql_stat() 目前只返回 uptime、threads、queries、open table…

全选、全部选、反选、提交

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </head> <body><form><input type"checkbox" name"items" value"足球"&…

Java中的模板方法设计模式

模板方法模式是一种行为设计模式&#xff0c;它为算法提供了基础方法&#xff0c;称为模板方法&#xff0c;该方法将其某些步骤推迟到子类中&#xff0c;因此算法结构相同&#xff0c;但某些步骤可以由子类根据上下文重新定义。 模板是指预设格式&#xff0c;例如HTML模板&…

android adb源码分析(1)

ADB是Android debug bridge的缩写&#xff0c;它使用PC机可以通过USB或网络与android设备通讯。 adb的源码位于system/core/adb目录下&#xff0c;先来看下编译脚本Android.mk&#xff1a; [plain] view plaincopy# Copyright 2005 The Android Open Source Project # # Andr…

matlab二次二阶距,用Matlab改进一次二阶矩法程序.doc

用Matlab编的计算结构可靠指标的改进一次二阶矩法程序(验算点法)题目&#xff1a;编制改进一次二阶矩法计算可靠指标的程序&#xff0c;并给出算例&#xff0c;要求提供源程序选取的算例为&#xff1a;zg(x,y)x*y-1140&#xff0c;其中x,y服从正态分布&#xff0c;μx38,Vx0.1,…

winform中的数据绑定

1. 简单的数据绑定 例1 using (SqlConnection conn new SqlConnection(ConfigurationManager.ConnectionStrings["connStr"].ToString())) { SqlDataAdapter sda new SqlDataAdapter("Select * From T_Class Where F_TypeProduct order by F_RootID,F_Order…

jQuery数据表和Java集成

jQuery DataTables是一个开放源代码插件&#xff0c;用于在浏览器中创建表。 它具有许多功能&#xff0c;例如排序&#xff0c;服务器端处理&#xff0c; JQUERY UI主题滚动。 该插件的下载链接&#xff1a; http://www.datatables.net/download/ 在本演示中&#xff0c;我…

CSS 属性 - 伪类和伪元素的区别

伪元素和伪类之所以这么容易混淆&#xff0c;是因为他们的效果类似而且写法相仿&#xff0c;但实际上 css3 为了区分两者&#xff0c;已经明确规定了伪类用一个冒号来表示&#xff0c;而伪元素则用两个冒号来表示。 :Pseudo-classes ::Pseudo-elements 但因为兼容性的问题&…

class-感知机Perception

1 感知机模型1.1 模型定义2 感知机学习策略2.1 数据的线性可分性2.2 学习策略3 学习算法3.1 算法原始形式3.2 收敛性3 学习算法的对偶形式1 感知机模型 感知机perceptron是二类分类问题的线性分类模型&#xff0c;输入为实例的特征向量&#xff0c;输出为实例的类别&#xff08…

图片资源 php,php URL图片资源传参生成对应尺寸图片

最近项目中需要上传大图&#xff0c;然后不同设备请求不同大小的图片&#xff0c;之前有用过一个通过URL参数来获取不同大小的图片的接口感觉设计方式请不错&#xff0c;于是就百度看看类似是如何实现的&#xff0c;找了几天找个两个功能类似的记录下。1、图片服务器 imagemagi…

Java中的方法调用有多昂贵

我们都去过那儿。 在查看设计不良的代码的同时&#xff0c;听听作者对人们永远不应该牺牲性能而不是设计的解释。 而且&#xff0c;您不能说服作者摆脱其500行方法&#xff0c;因为链接方法调用会破坏性能。 好吧&#xff0c;这可能在1996年左右是正确的。 但是自那时以来&…

UVa-116 Unidirectional TSP 单向旅行商

题目 https://vjudge.net/problem/uva-116 分析 设d[i][j]为从(i,j)到最后一列的最小开销&#xff0c;则d[i][j]a[i][j]max(d[i1][j1],d[i-1][j1]) 参考数字三角形,用逆推的方法,先确定最后一列d[i][n-1]a[i][n-1],再确定n-2列,此时d[i][n-2] a[i][n-2]min(d[i][n-1],d[i-1][n…

1.HTML

HTML简介 hyper text markup language 即超文本标记语言。 超文本: 就是指页面内可以包含图片、链接&#xff0c;甚至音乐、程序等非文字元素。 标准模板 <!DOCTYPE html> <html lang"en"><head> <meta charset"U…