V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  yuanxiaosong  ›  全部回复第 1 页 / 共 2 页
回复总数  39
1  2  
1 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist
问题 1:在保证一个 dao 对应一个表(仅限增删改)的前提下,这个确实有很大的争论点,没有一个固定的答案,它可以叫 UserDept ,也可以 DeptUser ,但是在我看来,理论上只有一个存在,除非你底层用双向链表来维护(有两个数据库表),你用 User 打头,那么你潜意识就认为这个关联关系应该由 UserManager 来维护,反之亦然。
继续问题 1:首先确定,Service 只和 Manager 打交道,类似于事件驱动,Service 会通知每一个 Manager ,我现在要删除一个部门了,真正的执行人是 Manager ,如果关联关系是 DeptManager 维护,那么它会删除 dept 表和 dept_user ,UserManager 说关联关系不是我维护的,我直接 return ,不做任何操作,反之亦然,删除这个工作并不是 service 来完成,真正的删除是在 UserManager 和 DeptManager 中,为什么只调用某个 manager 是我们很明确其他 manager 没有和部门发生关系而已。
继续问题 1:我们目前使用一个原则来确认代码在那一层:是否抛出业务异常和 Manager 中一个方法只能对应一个动作(增/删/改)

问题 2:来个简单粗暴的,直接调用 dao 的都在 manager 中,功能权限校验/参数校验/返回结果裁剪都在 controller 中,其他的都扔在 service 中就可以了,不要过多纠结,这个没有统一标准,写的多了自然就有经验了。
2 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist 比较有争议的是这种情况,UserDao/DeptDao/UserDeptDao ,UserDao 和 UserDeptDao 肯定是直接被 UserManager 引用,现在有个需求,在部门下有人的情况下,可以直接删除部门,删除部门后,需要将部门下的人员与部门关系解除,很多人就会这样写:
class DeptManager{
void deleteDept(id){
deptDao.deleteById(id);
userDeptDao.deleteByDeptId(id);
}
}
实际上我们做法是这种;
class DeptService{
void deleteDept(id){
deptManager.deleteById(id);
userManger.deleteUserDeptByDeptId(id);
}
}
由上层去协调,如果还有业务逻辑掺杂在里面,我们还有更上层的应用层去协调:
class DeptApplication {
void deleteDept(id){
deptService.deleteById(id);
userService.deleteUserDeptByDeptId(id);
}
}
2 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist 理论上一个 dao 不会被两个 manager 调用,这个就要从上层设计来说了,领域驱动设计(DDD)应该有了解吧,我们完整的领域对象应该包括了(属性+业务方法),大概是长这个样子:
class User {
Long id;
String name;

void saveUser(){
// so something
userDao.saveUser();
userDeptDao.saveUserDept();
}
}
后来我们觉得应该职责分离,属性和方法分开,就变成了下面这种:
class User{
Long id;
String name;
}
class UserService extends User {
void saveUser(){
// so something
userDao.saveUser();
userDeptDao.saveUserDept();
}
}
再后来我们觉得方法还可以继续拆,分为业务方法和非业务方法:
class UserManager extends User {
void saveUser(){
userDao.saveUser();
userDeptDao.saveUserDept();
}
}
class UserService extends UserManager {
void saveUser(){
// so something
userManager.saveUser();
}
}
看出来没有,我们所有的操作其实都围绕着 User 这个模型在工作,如果你有 UserAManager 和 UserBManager ,这两个都调用 UserDao 可以,但是你一个 DeptManager 调用 UserDao ,那就要考虑一下是不是你的模型设计有问题了?
2 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist 理论上一个 dao 不会被两个 manager 调用,这个就要从上层设计来说了,领域驱动设计(DDD)应该有了解吧,我们完整的领域对象应该包括了(属性+业务方法),大概是长这个样子:
class User {

}
2 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist 举个例子,现在我要做一个员工管理功能,员工信息是一个大表单,用户基本信息:姓名,账号……,用户其他信息:任职部门(多个),岗位(多个),紧急联系人(多个),工作经历(多个)……,因为要支持任意关联属性实时搜索,所以一般都是 1 个主表+n 个关联表,大概有 UserDao/UserDeptDao/UserPositionDao/UserContactDao/UserEmployHistoryDao ,每次保存/修改都要调用这么多 dao ,还有就是如果是更新,还需要更新缓存,更新 es ,那么我有一个 UserManager.saveUser(UserDTO user),这个方法再调用 5 个 dao ,修改缓存/es ,上层的 service 方法就简单了,userManager.saveUser(user)即可,service 能够专注于处理业务逻辑,不关心数据存储,manager 关心数据存储,不关心业务逻辑,如果业务小体现不出来,像我们最多的一个主表对了 20 多个关联表,es ,redis ,es 都有,拆分了效果就很明显了。
2 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist 我这个 id 专门用来注册互联网用的,没有任何地方留有邮箱的。

针对你这种情况,我们一般是这样写:listOrders(OrderQuery query, QueryType queryType),queryType 有两个值,实时查询/非实时查询,分别对应数据库/es ,manager 内部又有两个 私有 方法:listOrdersByDB ,listOrdersByES ,根据用户传入的 queryType 转调两个方法,这样就把业务屏蔽掉了,像你这种在方法命名上带业务,如果后期再来 N 角色,是不是要写 N 个方法?
5 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
@chaleaochexist
mq 和 controller 平级,我们认为接收 mq 也是一种外部调用方式,可能开始我们写一个 controller 来接收请求,后来解耦了,直接在 mq 中新增一个接收消息就行了,service 不用做任何变更,甚至可以支持一部分请求调用 controller ,另一部分请求发送 mq 消息。

dao 和 client 是平级,和你理解的差不多,可以简单理解 client 就是一个通过 http 通信的 db 数据库,调用接口获取一条数据和从数据库获取一条数据从上层来看没有区别;

manager 只要是用来屏蔽数据存储层的实现的,可能我们数据来源有 db/redis/es/client ,比如我获取用户,manager 中先从 redis 中获取,如果 redis 中没有,再从 mysql 中获取,然后再存储到 redis ,最后再返回给 service ;再举个例子,我们一般是一个主表和 n 个关联表,每个表对应一个 dao ,我们比较大的业务对象要产生几十个关联表,会在 manager 中合并成一个 save 方法。service 能够专注于业务逻辑处理。
@EventListener(ContextRefreshedEvent.class)
home -> home
icloud -> home
microsoft -> home
cn -> home
work -> work
chatgpt -> us
gfw -> proxy
final -> proxy
按照苹果的尿性,应该是周三凌晨发布,中文页面上也写的是 9 月 27 日。
FULL JOIN + RAND()
两年前买了,两年内出现了以下问题:1. 续航打 5 折,2. 右耳经常无法充电,3. 麦克风经常失灵,4. 无法唤醒 siri ,去了售后,耳机和电池仓直接换新了。
你接触过的最大的表是多少行?

我一般不会直接问,会问下面的问题:

你负责的系统上数据量最大的是哪个模块?
该模块有多少用户,每天多少并发,每天产生多少数据,系统运行了多久,总共产生了多少数据,最大的是哪个业务表?
该表上有多少字段,每个字段类型,为什么这么设计,每行数据占用空间多少,整个表占用磁盘空间多少,
有多少个索引,索引占用磁盘空间多少,
再给个查询,能命中哪个索引,type 级别是哪个?
新提个需求,无法命中现有索引,请设计一个新的索引来解决,要求级别必须达到 range ?

结果我这样面试了几次后,领导就换别人当面试官了。
277 天前
回复了 kachu673 创建的主题 Java Spring 开发,流程冗余
看看我司的分层模型:
filter -> controller -> application -> service -> manager -> dao

filter:统一身份认证,公共参数处理,日志等;
controller:对前端参数验证转换,mq 接收,新旧接口兼容,新旧参数兼容,响应结果按业务裁剪,有些接口 5 年没变过,业务都改了几轮了,调用那些老接口依旧不会报错;
application:采用 ddd 模型后跨领域调用,mq 发送;
service:领域内部业务,一般不互相调用,这里写纯粹的业务,最多就是调用 manager 获取数据或者操作数据,经常都是几百行的;
manager:缓存,领域对象转多个关联表,调用远程服务,切换数据源,比如开始走数据库搜索,后期走 es 搜索,我记得我们最复杂的操作一次要修改接近 50 张表,不在这里的话,service 早疯了;
dao:mysql ,es ,远程调用都在这一层;
企业级开发就这么多层,上了微服务后会按照服务拆分,不要搞形式主义,看看每一层你有没有需求,没有需求可以直接砍掉,还有就是这个和 Spring 没啥关系,纯粹是设计的问题,个人开发就可以一层梭哈就行了。
286 天前
回复了 shenjiahuan 创建的主题 iPhone 原来 iPhone 维修后可以补买 Apple Care+
我的 11pm 首发买的,马上 4 年了,充电次数 1000+,每天不玩游戏,不看视频,要充电两次才能坚持到晚上睡觉,结果电池健康度还有 84%,严重怀疑苹果是有黑科技,唯一的原因是还没过保,打了 400 ,去了店里,都说电池没问题。
288 天前
回复了 acbot 创建的主题 macOS 苹果系统远程桌面的问题
试试 remote desktop manager 呢?
https://icp.chinaz.com/www.disktool.cn

蜀 ICP 备 16032123 号-1
网站域名:
disktool.cn

https://icp.chinaz.com/www.aomeikeji.com
蜀 ICP 备 16032123 号-3
网站域名:
aomeikeji.com

看备案号是同一家公司的备案。
2023-04-28 20:59:05 +08:00
回复了 rcocco 创建的主题 Java Spring Boot 各种配置的官方手册从哪里查?
另一种方法,打开 spring-boot-autoconfigure 这个依赖包,找到具体的包“package org.springframework.boot.autoconfigure.data.redis”,你会发现有个前缀“@ConfigurationProperties(prefix = "spring.redis")”,用“spring.redis”去对应文档里面查就好了。
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2244 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 29ms · UTC 03:03 · PVG 11:03 · LAX 20:03 · JFK 23:03
Developed with CodeLauncher
♥ Do have faith in what you're doing.