用领域驱动设计实现分页和排序
Implementing Paging and Sorting with Domain Driven Design
这是关于我在域驱动设计中实现分页和排序的解决方案,目的是不污染域模型和存储库契约,
REST 请求的基础 class
public class AbstractQueryRequest {
...
private int startIndex;
private int offset;
...
}
用于检索查询元数据并将其存储在 ThreadLocal 容器中的拦截器
public class QueryInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
...
QueryMetaData.instance().setPageMetaData(/*Create and set the pageable*/);
}
}
查询元数据的容器
public class QueryMetaData {
private static final ThreadLocal<QueryMetaData> instance = new ThreadLocal<>() {
protected QueryMetaData initialValue() {
return new QueryMetaData();
}
};
public static QueryMetaData instance() {
return instance.get();
}
private ThreadLocal<Pageable> pageMetadata = new ThreadLocal<>();
public void setPageMetaData(Pageable pageable) {
pageMetadata.set(pageable);
}
public Pageable getPageMetaData() {
return pageMetadata.get();
}
//clear threadlocal
}
我打算在存储库中检索此 ThreadLocal 值,如果可用,请将其用于对数据存储的查询。
我希望这可能不是一个非常肮脏的解决方案,但想知道是否有更好的广泛使用的模式。
不要使用您的解决方案。它非常复杂,很难调试和维护。如果您开始使用异步方法,它甚至无法工作。
我不明白为什么您的存储库方法中不能有 sorting/paging 属性?如果您想要一个更简洁的解决方案,您可以创建一个包含排序和分页设置的新对象。
当您想要获取数据时,通常会通过您的应用程序服务来完成。那些可以在将结果转换为 DTO 之前直接使用您的存储库。
然后你得到类似的东西:
public class YourAppService
{
public YourAppService(ISomeRepository repos)
{
}
public IList<UserDto> ListUsers(string sortColumn = "", bool ascending = true, int pageNumber = 1, pageSize = 30)
{
var querySettings = new QuerySettings(sortcolumn, ascending, pageNumber, pageSize);
var users = _repos.FindAll(querySettings);
return ConvertToDto(users);
}
}
您可以在此处阅读我的文章中有关排序和分页的更多信息:
http://blog.gauffin.org/2013/01/11/repository-pattern-done-right/
这是关于我在域驱动设计中实现分页和排序的解决方案,目的是不污染域模型和存储库契约,
REST 请求的基础 class
public class AbstractQueryRequest {
...
private int startIndex;
private int offset;
...
}
用于检索查询元数据并将其存储在 ThreadLocal 容器中的拦截器
public class QueryInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
...
QueryMetaData.instance().setPageMetaData(/*Create and set the pageable*/);
}
}
查询元数据的容器
public class QueryMetaData {
private static final ThreadLocal<QueryMetaData> instance = new ThreadLocal<>() {
protected QueryMetaData initialValue() {
return new QueryMetaData();
}
};
public static QueryMetaData instance() {
return instance.get();
}
private ThreadLocal<Pageable> pageMetadata = new ThreadLocal<>();
public void setPageMetaData(Pageable pageable) {
pageMetadata.set(pageable);
}
public Pageable getPageMetaData() {
return pageMetadata.get();
}
//clear threadlocal
}
我打算在存储库中检索此 ThreadLocal 值,如果可用,请将其用于对数据存储的查询。
我希望这可能不是一个非常肮脏的解决方案,但想知道是否有更好的广泛使用的模式。
不要使用您的解决方案。它非常复杂,很难调试和维护。如果您开始使用异步方法,它甚至无法工作。
我不明白为什么您的存储库方法中不能有 sorting/paging 属性?如果您想要一个更简洁的解决方案,您可以创建一个包含排序和分页设置的新对象。
当您想要获取数据时,通常会通过您的应用程序服务来完成。那些可以在将结果转换为 DTO 之前直接使用您的存储库。
然后你得到类似的东西:
public class YourAppService
{
public YourAppService(ISomeRepository repos)
{
}
public IList<UserDto> ListUsers(string sortColumn = "", bool ascending = true, int pageNumber = 1, pageSize = 30)
{
var querySettings = new QuerySettings(sortcolumn, ascending, pageNumber, pageSize);
var users = _repos.FindAll(querySettings);
return ConvertToDto(users);
}
}
您可以在此处阅读我的文章中有关排序和分页的更多信息: http://blog.gauffin.org/2013/01/11/repository-pattern-done-right/