spring-data-mongodb兩種實現方式對比
之前介紹過springboot和mongodb整合,使用了spring-data-mongodb,因為springboot註解和自動化配置,我們少了很多配置,這裡介紹spring整合mongodb,使用的仍然是spring-data-mongodb,這裡需要配置一個spring-mongo.xml的配置檔案。
spring-data-mongodb其實有兩種實現方式,一種是直接繼承MongoRepository
介面,dao層的實現,預設提供了CRUD的各種方法,幾乎不用編寫任何程式碼。另一種是通過MongoTemplate
來操作資料庫,這樣需要自定義dao層介面,預設沒有任何介面可以使用,但是MongoTemplate提供了操作資料庫的各種CRUD介面,因此,dao層介面需要我們再次封裝一次。
兩種方式均需要配置
mongo:client
,mongo:db-factory
,mongoTemplate類
。這裡只整合spring+mongodb,因此構建的工程相對簡單:
maven工程pom.xml配置檔案:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope >test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.0.10.RELEASE</version>
</dependency>
<dependency>
<groupId >org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
實體定義:
BaseEntity
package com.xxx.springmongo.entity;
import java.util.Date;
import org.springframework.data.annotation.Id;
public class BaseEntity {
@Id
protected String id;
protected Date createDate;
protected Date modifyDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
User
package com.xxx.springmongo.entity;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="xx_user")
public class User extends BaseEntity{
private String username;
private String password;
private String mobile;
@DBRef
private Role role;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public void setRole(Role role) {
this.role = role;
}
public Role getRole() {
return role;
}
@Override
public String toString() {
return "{\"id\":"+id+",\"username\":"+username+",\"password\":"+
password+",\"mobile\""+mobile+",\"role\":"+role+"}";
}
}
Role
package com.xxx.springmongo.entity;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="xx_role")
public class Role extends BaseEntity{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "{\"id\":"+id+",\"name\":"+name+"}";
}
}
實體之間的關係,使用者(User),角色(Role)均繼承BaseEntity,另外使用者有一個角色的引用。通過註解@DBRef
來指定他們在資料庫中的關係。
配置檔案
mongo.properties
mongo.host=127.0.0.1
mongo.port=27017
mongo.db=springmongo
spring-mongo.xml 核心配置(需要引入spring-mongo.xsd)
<context:property-placeholder location="classpath:mongo.properties"/>
<context:component-scan base-package="com.xxx.springmongo">
</context:component-scan>
<mongo:mongo-client id="mongo-client" host="${mongo.host}"
port="${mongo.port}">
<mongo:client-options/>
</mongo:mongo-client>
<mongo:repositories base-package="com.xxx.springmongo.dao"/>
<mongo:db-factory dbname="${mongo.db}" mongo-ref="mongo-client"/>
<bean id="mongoTemplate"
class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
第一種實現方式:dao層介面繼承MongoRepository
UserDao
package com.xxx.springmongo.dao;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import com.xxx.springmongo.entity.Role;
import com.xxx.springmongo.entity.User;
public interface UserDao extends MongoRepository<User, String>{
public User findByRole(Role role);
@Query(value="{'role.$id': ?0 }")
public User findByRoleId(ObjectId id);
}
RoleDao
package com.xxx.springmongo.dao;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.xxx.springmongo.entity.Role;
public interface RoleDao extends MongoRepository<Role, String>{
}
預設情況下,我們只是定義了dao層的使用者介面和角色介面,並沒有實現相關方法。UserDao中為了實現通過關聯角色查詢使用者,增加了兩個介面。
服務層介面:
RoleService
package com.xxx.springmongo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import com.xxx.springmongo.dao.RoleDao;
import com.xxx.springmongo.entity.Role;
@Service
public class RoleService {
@Autowired
private RoleDao roleDao;
public Role save(Role role) {
return roleDao.save(role);
}
public Role findById(String id) {
return roleDao.findById(id).get();
}
public Role findByName(String name) {
Role role = new Role();
role.setName(name);
ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("name", match->match.contains());
Example<Role> example = Example.of(role, matcher);
return roleDao.findOne(example).get();
}
}
UserService
package com.xxx.springmongo.service;
import java.util.List;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xxx.springmongo.dao.UserDao;
import com.xxx.springmongo.entity.Role;
import com.xxx.springmongo.entity.User;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User save(User user) {
return userDao.save(user);
}
public User findById(String id) {
return userDao.findById(id).get();
}
public List<User> findAll(){
return userDao.findAll();
}
public User findByRole(Role role) {
return userDao.findByRoleId(new ObjectId(role.getId()));
}
}
測試類:
AppTest
package com.xxx.springmongo;
import java.util.Date;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xxx.springmongo.entity.Role;
import com.xxx.springmongo.entity.User;
import com.xxx.springmongo.service.RoleService;
import com.xxx.springmongo.service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring-mongo.xml")
public class AppTest {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Test
public void save() {
Role role = new Role();
role.setName("superadmin");
role.setCreateDate(new Date());
role.setModifyDate(new Date());
Role save = roleService.save(role);
Assert.assertEquals("superadmin", save.getName());
}
@Test
public void query() {
Role role = roleService.findByName("admin");
System.out.println(role);
//Assert.assertEquals("admin", role.getName());
User user = new User();
user.setCreateDate(new Date());
user.setUsername("admin");
user.setPassword("admin");
user.setMobile("15011186302");
user.setModifyDate(new Date());
user.setRole(role);
User tmp = userService.save(user);
Assert.assertEquals("admin", tmp.getUsername());
}
@Test
public void query1() {
Role role = roleService.findByName("admin");
User tmp = userService.findByRole(role);
System.out.println(tmp);
Assert.assertEquals("admin", tmp.getUsername());
}
}
以上測試用例只寫了新增角色,新增使用者,按照角色名查詢角色,按照角色查詢使用者。其中按照角色查詢使用者是一個關聯查詢,在MongoRepository
的實現方式中有兩種實現:
- 第一種是和普通的按照屬性查詢的方式實現。
- 第二種是稍微有一點改變,就是模擬在mongo-shell下通過關聯屬性role欄位的$id來查詢
> db.xx_user.find({"role.$id":new ObjectId("5bdfbbc2e6c87e4f147f7fab")})
{ "_id" : ObjectId("5bdfed63e6c87e569c9f8865"),
"username" : "admin",
"password" : "admin",
"mobile" : "15011186302",
"role" : DBRef("xx_role",
ObjectId("5bdfbbc2e6c87e4f147f7fab")),
"createDate" : ISODate("2018-11-05T07:12:35.739Z"),
"modifyDate" : ISODate("2018-11-05T07:12:35.739Z"),
"_class" : "com.xxx.springmongo.entity.User" }
>
第二種實現方式:通過MongoTemplate來操作資料庫
IBaseDao定義一個基礎介面
package com.xxx.springmongo.mongo.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Page;
public interface IBaseDao<T> {
void save(T entity);
void update(T entity);
void delete(Serializable... ids);
T find(Serializable id);
List<T> findAll();
List<T> findAll(String order);
List<T> findByProp(String propName,Object value);
List<T> findByProp(String propName,Object value,String order);
List<T> findByProps(String[] propName,Object[] values);
List<T> findByProps(String[] propName,Object[] values,String order);
T uniqueByProp(String propName,Object value);
T uniqueByProps(String[] propName,Object[] values);
int countByCondition(String[] params,Object[] values);
}
UserDao
package com.xxx.springmongo.mongo.dao;
import com.xxx.springmongo.entity.User;
public interface UserDao extends IBaseDao<User>{
}
BaseDaoImpl
package com.xxx.springmongo.mongo.dao.impl;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
相關推薦
spring-data-mongodb兩種實現方式對比
之前介紹過springboot和mongodb整合,使用了spring-data-mongodb,因為springboot註解和自動化配置,我們少了很多配置,這裡介紹spring整合mongodb,使用的仍然是spring-data-mongodb,這裡需要配置一個spring-mo
spring ----> aop的兩種實現方式
select imp ack exe readv expr gpo for public 實現1:基於xml
1 package com.rr.spring3.interf; //接口
2
3 public interface SayHello {
4
5
spring中AOP的兩種實現方式
1.方法一:註解實現
介面類
public interface User {
public void work();
}
具體實現類
public class IUser implements User {
public void work() {
Spring 詳解(二)------- AOP關鍵概念以及兩種實現方式
目錄
1. AOP 關鍵詞
2. AOP 的作用
3. AOP 的通知型別
4. 基於 xml 的配置方式
5. 基於註解的配置方式
6. 切面的優先順序
7. 重用切點表示式
8. 兩種方式的比較(摘自 spring 官方文件)
1. AOP 關鍵詞
Spring 詳解(二)------- AOP概念以及兩種實現方式
target:目標類,需要被代理的類。例如:ArithmeticCalculator Joinpoint(連線點):所謂連線點是指那些可能被攔截到的方法。例如:所有的方法 PointCut 切入點:已經被增強的連線點。例如:add() advice:通知/增強,增強
Spring Boot2 系列教程(十六)定時任務的兩種實現方式
在 Spring + SpringMVC 環境中,一般來說,要實現定時任務,我們有兩中方案,一種是使用 Spring 自帶的定時任務處理器 @Scheduled 註解,另一種就是使用第三方框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具備這兩個 Spring
曹工說Spring Boot原始碼(14)-- AspectJ的Load-Time-Weaving的兩種實現方式細細講解,以及怎麼和Spring Instrumentation整合
寫在前面的話
相關背景及資源:
曹工說Spring Boot原始碼(1)-- Bean Definition到底是什麼,附spring思維導圖分享
曹工說Spring Boot原始碼(2)-- Bean Definition到底是什麼,咱們對著介面,逐個方法講解
曹工說Spring Boot原始碼(3)--
[轉]Web APi之認證(Authentication)兩種實現方式【二】(十三)
用戶數 ted das 客戶 元素 基礎 目標 開始 net 本文轉自:http://www.cnblogs.com/CreateMyself/p/4857799.html
前言
上一節我們詳細講解了認證及其基本信息,這一節我們通過兩種不同方式來實現認證,並且分析如
多線程兩種實現方式的區別
http [] tick 避免 main 單繼承 style 區別 tar 請解釋Thread類與Runnable接口實現多線程的區別?(請解釋多線程兩種實現方式的區別?)
1. Thread類時Runnable接口的子類,使用Runnable接口實現多線程可以避免單繼承局
JPA 派生標識符的兩種實現方式
string column public tid man pri one embed page 方法一:@Entity@IdClass(ModuleId.class)public class Module { @Id private Integer index;
14、Fibonacci的兩種實現方式
等於 cheng pos art log ref clas gpo tar 斐波納契數列,又稱黃金分割數列,指的是這樣一個數列:1、1、2、3、5、8、13、21、……在數學上,斐波納契數列以如下被以遞歸的方法定義:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n&
Web APi之認證(Authentication)兩種實現方式【二】(十三)
基於web 推薦 zed {0} scheme sage https 函數 ges 原文:Web APi之認證(Authentication)兩種實現方式【二】(十三)前言
上一節我們詳細講解了認證及其基本信息,這一節我們通過兩種不同方式來實現認證,並且分析如何合理的利用
spring AOP的兩種配置方式
can 之前 top () 就是 記錄 string -s 服務
連接點(JoinPoint) ,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個方法的前、後(兩者都有也行),或拋出異常是時都可以是連接點,spring只支持方法連接點。其
Ajax的兩種實現方式
enc () != 部分 pen clas servlet 瀏覽器 pop
//ajax的jquery實現
function aclick(){//alert("測
圖形驗證碼的兩種實現方式
ava 輸入 urn color deb rect lac prev 後臺 情形一:圖形驗證碼跟短信驗證碼一起,只需要將後臺提供的動態鏈接填到(id="img")的src中即可生成動態驗證碼。
然後,在需要請求接口的地方,只需把(id="imgCode")中用戶輸入的信息通
前端路由的兩種實現方式
color 前端路由 his 頁面 無刷新 原理 range window 使用 什麽是路由?
路由是根據不同的 url 地址展示不同的內容或頁面
早期的路由都是後端直接根據 url 來 reload 頁面實現的,即後端控制路由。
後來頁面越來越復雜,服務器壓力越來越大,隨
題目24-多線程兩種實現方式
類重寫 直接 解決方案 做的 子類 是否為空 缺點 多線程同步 弊端 1、多線程兩種實現方式
(1)繼承Thread
定義類繼承Thread
重寫run方法
把新線程要做的事寫在run方法中
創建線程對象
開啟新線程, 內部會自動執行run方法(2)實現Runnable
線程的兩種實現方式
class args new pub nds runnable implement ide start 線程的兩種實現方式
(1)繼承Thread類``
/**
* 繼承Thread類
*
*/
public class PayThread extends T
iOS活動倒計時的兩種實現方式
ofo orm ren 年-月 ats omd string 分享 截圖 代碼地址如下:<br>http://www.demodashi.com/demo/11076.html
在做些活動界面或者限時驗證碼時, 經常會使用一些倒計時突出展現.
現提供兩種方
Brute-Force模式匹配演算法兩種實現方式
1.
public static int indexOf(String mainStr,String subString,int start) {
if((mainStr.length()<subString.length()) || mainStr==null || subStr