javascript
MongoDB:使用Spring数据添加计数器
在我的博客應用程序中,您可以查看任何用戶的個人資料,例如,我的個人資料頁面將為http://www.jiwhiz.com/profile/user1,“user1”是我在系統中的用戶ID。 在MongoDB中,每個文檔對象都會有一個唯一的標識符,通常我們將其存儲為String,因此我有一個BaseEntity類:
但是系統生成的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 ,因此將調用插入MongoUsersConnectionRepository的ConnectionSignUp 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
總結
以上是生活随笔為你收集整理的MongoDB:使用Spring数据添加计数器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 域名和备案(域名备案吧)
- 下一篇: 使用Spring Data Redis进