Chr*_*ong 79 java spring mongodb spring-data spring-data-mongodb
我需要编写一个应用程序,我可以使用spring-data和mongodb进行复杂的查询.我一直在使用MongoRepository开始,但在复杂的查询中苦苦寻找示例或实际理解语法.
我在谈论这样的查询:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
Run Code Online (Sandbox Code Playgroud)
或者使用基于JSON的查询,我尝试通过反复试验,因为我没有正确的语法.即使在阅读了mongodb文档(由于语法错误而导致的非工作示例).
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
@Query("'$or':[{'firstName':{'$regex':?0,'$options':'i'}},{'lastName':{'$regex':?0,'$options':'i'}}]")
List<User> findByEmailOrFirstnameOrLastnameLike(String searchText);
}
Run Code Online (Sandbox Code Playgroud)
阅读完所有文档后,似乎mongoTemplate记录得更好MongoRepository.我指的是以下文档:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
你能告诉我什么更方便,更强大吗?mongoTemplate还是MongoRepository?两者是否同样成熟,或者其中一个缺少比另一个更多的功能?
Oli*_*ohm 121
"方便"和"强大使用"在某种程度上是相互矛盾的.存储库比模板更方便,但后者当然可以让您对执行的内容进行更细粒度的控制.
由于存储库编程模型可用于多个Spring Data模块,因此您可以在Spring Data MongoDB 参考文档的常规部分中找到更深入的文档.
TL; DR
我们通常建议采用以下方法:
MongoTemplate.细节
对于您的示例,这将看起来像这样:
为自定义代码定义接口:
interface CustomUserRepository {
List<User> yourCustomMethod();
}
Run Code Online (Sandbox Code Playgroud)为此类添加实现并遵循命名约定以确保我们可以找到该类.
class UserRepositoryImpl implements CustomUserRepository {
private final MongoOperations operations;
@Autowired
public UserRepositoryImpl(MongoOperations operations) {
Assert.notNull(operations, "MongoOperations must not be null!");
this.operations = operations;
}
public List<User> yourCustomMethod() {
// custom implementation here
}
}
Run Code Online (Sandbox Code Playgroud)现在让您的基础存储库接口扩展自定义存储库接口,基础结构将自动使用您的自定义实现:
interface UserRepository extends CrudRepository<User, Long>, CustomUserRepository {
}
Run Code Online (Sandbox Code Playgroud)这样你基本上就可以做出选择:易于申报的UserRepository所有内容,手动实现的所有内容都会进入CustomUserRepository.此处记录了自定义选项.
ram*_*hpa 20
这个答案可能有点延迟,但我建议避免整个存储库路由.你得到的实践方法很少,具有很大的实用价值.为了使它工作,你会遇到Java配置废话,你可以花费数天和数周的时间在文档中没有太多帮助.
相反,请使用该MongoTemplate路线并创建自己的数据访问层,这样您就可以摆脱Spring程序员面临的配置噩梦.MongoTemplate对于那些能够灵活地构建自己的类和交互的工程师来说,它真的是一个救星,因为它具有很大的灵活性.结构可以是这样的:
MongoClientFactory将在应用程序级别运行并为您提供MongoClient对象的类.您可以将其实现为Singleton或使用Enum Singleton(这是线程安全的)wal*_*len 10
FWIW,关于多线程环境中的更新:
MongoTemplate提供外的开箱updateFirst,updateMulti,findAndModify,upsert...方法,它允许你在一个单一的操作修改文档。Update这些方法使用的对象还允许您仅定位相关字段。MongoRepository只给你基本的find,insert,save,delete运营,包含所有字段的POJO其工作。这迫使您要么分几个步骤find来更新文档(要更新的文档,然后从返回的POJO中修改相关字段,然后再进行修改save),或者使用手动定义自己的更新查询@Query。在多线程环境中(例如,具有多个REST端点的Java后端),单方法更新是行之有效的方法,以减少两次并发更新覆盖彼此更改的机会。
示例:给定这样的文档:{ _id: "ID1", field1: "a string", field2: 10.0 }并且两个不同的线程同时更新它...
有了MongoTemplate它看起来像这样:
THREAD_001 THREAD_002
| |
|update(query("ID1"), Update().set("field1", "another string")) |update(query("ID1"), Update().inc("field2", 5))
| |
| |
Run Code Online (Sandbox Code Playgroud)
文件的最终状态始终是{ _id: "ID1", field1: "another string", field2: 15.0 }因为每个线程仅访问DB一次,并且仅更改了指定字段。
相同的情况MongoRepository如下所示:
THREAD_001 THREAD_002
| |
|pojo = findById("ID1") |pojo = findById("ID1")
|pojo.setField1("another string") /* field2 still 10.0 */ |pojo.setField2(pojo.getField2()+5) /* field1 still "a string" */
|save(pojo) |save(pojo)
| |
| |
Run Code Online (Sandbox Code Playgroud)
最终文档是{ _id: "ID1", field1: "another string", field2: 10.0 }或{ _id: "ID1", field1: "a string", field2: 15.0 }取决于哪个save操作首先命中数据库。
因此,我想这MongoTemplate是一个更好的选择,除非您有一个非常详细的POJO模型或MongoRepository出于某种原因需要自定义查询功能。
| 归档时间: |
|
| 查看次数: |
57492 次 |
| 最近记录: |