首页 > 数据库 >sql是不是可以写在service层?虽然service是业务层

sql是不是可以写在service层?虽然service是业务层

时间:2024-04-10 10:12:23浏览次数:32  
标签:UserDao service Dao 是不是 查询 sql 方法

我记得我曾经学javaweb的时候,也是被这个问题困惑过大半年,service层到底要不要出现sql或者Hibernate的hql语句?
我曾经有和你一样的困惑,比如有一个UserDao的接口,假如我想查询User,根据Id查询可能UserDao就需要设置一个findUserById(Integer id)这样的方法,根据用户名查询就是findUserByName(String name),根据邮箱查询就是findUserByEmail(String email),可能我还需要一个模糊查询,根据用户名模糊查询findUserByNameLike(String NameLike)等等,如果我的查询条件很多,我很有可能会在UserDao里面设置很多个不同的方法!可能会导致这个UserDao的小方法泛滥的多!我当时就想,能不能UserDao里面只设置一个find方法,然后sql语句和参数都由service传入,那么这样,UserDao岂不是非常清爽简洁啦?比如findUserByQuerySql(String querySql,Object... params),service业务层负责传入sql查询语句和参数,UserDao执行通用的findUserByQuerySql就行了。
我想,听完上面我说的这段,你一定泪流满面想和我握爪,就像找到了战友一般是不是!!

不幸的是,这种方案很快就被我当时的老大否定了!!
采用这种所谓通用Dao从service接收参数的方法在大型团队中会有以下几个严重问题!
1,假如你在多个地方中调用了这个通用的findUserByQuerySql(String querySql,Object... params),很有可能你的sql语句会在service中重复,举个例子,假如你在多个地方需要通过用户名模糊查询用户,那么,每个地方,你都需要准备完全一样的querySql(参数可能不同)。也就是说,你的service层的代码会重复!你就会在多个地方复制同一段代码,如果哪一天模糊查询的方式改变了,你需要把所有涉及到此查询条件的sql语句都给找出来一个一个来改变!!在大项目中是不可想象的!(Dao模式中是把sql封装到dao的方法中,那么,相当于只要调用这个dao方法就复用了方法里面的sql)。


2,涉及到多人合作问题,你可能现在是一个人做项目,感受不到,如果项目很大,是多个人合作,你的这个通用的UserDao被多个程序员调用了,假如,我为了一个很复杂的查询,光思考sql结构都思考了老半天(不要以为sql查询就是简单的select from,我曾经见过单条100行以上的sql查询语句!),嗯,我花了大概30分钟搞定了一条复杂的sql查询,另外一个程序员恰好也需要这个功能了,这个时候,他可能也会在那里想同样的一条sql查询啊!!结果他想了2个小时才搞定,你说浪费不浪费???这还不算什么,很有可能你们对于同一个查询写出来的sql语句是不一致的!!甚至有些人写的是正确的,有些人写的是有bug的,那么,极有可能出现你们两个人对于同一个查询不一致的情况发生!这都还不算事,最恐怖的就是,如果涉及到的查询由于业务原因发生变化了,那么,每一个人都去代码中捉虫子去吧!!结果再来一次每一个人都一套自己的sql,这种糟糕的局面会像滚雪球一样,越来越严重。(采用Dao模式,只需要一个sql高手把同一个查询的sql封装到dao的方法中,所有需要此功能的只需要调用此dao的该方法就行了)。

你的本意是想让UserDao更简单点,最好只有一个通用的查询方法,出发点是好的,但是,我希望你明白一点,不是东西越少就越好,就像java程序一样,本质上都是从main方法进去,main方法出来,我把全部代码放在一个main方法,弄他个30万行,有没有问题?依我说,没问题,jvm不会拒绝的,一样执行。这样整个程序只有一个方法呢,是不是越简单越好呢?可实际情况是一个大型项目中,所有类的总和都会有上千甚至上万个,大家各司其职,把业务拆分到单元中,说的专业点,就是面向对象三大特性之一的封装了。


Dao是数据访问对象,一个业务逻辑不仅仅是访问数据,应该说,数据是业务逻辑的一个底层支撑,举个例子,把你的日常生活看作你的业务的话,那么,一日三餐饭就相当于是你的业务活动的支撑了!我们在论坛交流的目的不是为了把问题文章存到数据库中好玩,而是为了和其他人交流,实现论坛的商业或非商业需求,存到数据库的唯一理由是为了持久化,好让你明天登录还能看到你的帖子,或者其他人能够发现你的帖子!持久化本身并非是商业活动意义上的业务逻辑,他只是为了能够提供更好更智能的商业业务而设置的一个基础设施,否则,一个发了帖子第二天就看不到的论坛,谁会去用呢?
可能对于业务逻辑的概念你还是很迷糊,我再举个例子,假如现在有一个网站系统,“每天首次登录就会送10个分,重复登录不送分,发一个帖子送50个分,如果帖子被置为精华,送1000个分,如果用户捣乱犯规,一次扣500个积分,犯规三次或积分小于0,锁定用户”,注意我用引号引起来的部分,这是一个论坛逻辑,这就是一个论坛经营过程中的业务规则,这些东西都需要在service层中去实现的!只不过Dao层,对于上述业务提供了数据持久底层支撑。如果有一个神存在,它可以监控所有的数据并记在脑子里,我们就可以不需要数据库了,需要什么业务就去找神询问就行了。这个时候我们的Dao可能就变成GodBrain(神的脑子)这样一个对象呢,获取用户积分就是GodBrain.getUserPointsByUid(Integer uid)。

 


回到你的问题本身,把sql写到service层是不行的(如果有程序员反驳我的观点,我只能说,你做的项目太小了,或者根据就是一些纯忽悠的辣鸡项目,你根本不知道什么是大型项目的有价值的项目了),那么怎么控制Dao层中太多的小方法呢?
我觉得可以这样做,还是以UserDao为例子,我们还是设置很多个小的琐碎的查询方法,比如UserDao.findUserByName(String name),UserDao.findUserByNameLike(String nameLike),同时我们在UserDao中设置一个通用的private的私有find(querySql)方法,findUserByName这样的方法不做具体的查询工作,而只是根据用户传递进来的name啊nameLike等参数生成sql语句,生成sql语句后调用Dao中的private的find方法,这个find方法是一个通用的方法!
通过上面的解决方法,可以将Dao中的重复代码降低到最小。


你能够在这里发这样的帖子说明你是一个爱思考的人,慢慢学吧,不要轻信菜鸟同事的说法,或者大部分人的看法,多读点书,特别是那些被大家公认的好书,说句不客气的,程序员之间的差异比人和猴子之间的差异还大,所以网络上一些人告诉你的很有可能是错误的。


解决问题还是看实际需求,耦合不耦合也是看实际需求的,我很不喜欢一些人一上来就否定这个,说这个辣鸡,那个辣鸡,举个例子,你自己开个杂货铺,你有必要成立采购部,销售部,财务部吗?你有必要采用MBA的管理方式吗?显然是不需要的,但是你要是开个大企业,你就需要了,因为大企业涉及到的也无太大,人员太多,业务越复杂,就越应该拆分,越应该把一个整体软件组件化,采用分布式子系统等,否则业务错综复杂,以至于单个项目超出了人脑子能够理解的极限,无论是维护还是可理解性上都是极其困难的。分而治之就是分层思想的一个体现,也是将复杂性包裹在一个组件中不让他扩散到外部。Dao接管了整个数据库部分,如果你们公司有人很懂sql的话,他们完全可以封装一整套Dao,作为业务开发人员,你连sql都是看不到的,你只需要使用它们提供的Dao的api就行了。这样,你在做业务的时候,你的业务中不会包含任何的数据库逻辑,因为所有的数据库逻辑都被围困在Dao中而不会扩散到外部,这样,复杂性就被管理起来了,就被征服了。
很多网友说,jsp一样能干,不分层也能干,是的,这是可以的,但是这仅限于小型项目或者试验项目。如果你想成长的更快,真的在软件业有成绩,一定要把分而治之这种思想理解到一个底朝天,分布式系统,集群,SOA,消息中间件MQ等,这些东西的思想都是想通的,不要因为一个人告诉你jsp也能干你就裹足不前了。
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/y_dzaichirou/article/details/53673528

标签:UserDao,service,Dao,是不是,查询,sql,方法
From: https://www.cnblogs.com/chinasoft/p/18125425

相关文章

  • 强制转换视图某个字段为某个类型的sql
    selectcast(`a`.`status`ASSIGNEDINTEGER)AS`status`,`a`.`TAGNAME`AS`TAGNAME`from(selecttruncate(`v_mes_snapshots`.`numbervalue`,0)AS`status`,`v_mes_snapshots`.`TAGNAME`AS`TAGNAME`from`mysql`.`v_mes_snapshots`where......
  • (二)PostgreSQL常用的配置文件
    PostgreSQL常用的配置文件1postgresql.conf参数文件postgresql.conf是PostgreSQL数据库的主要配置文件,用于控制数据库实例的行为和特性,一般在$PGDATA目录下。这个文件包括了众多的配置选项,比如内存使用限制、连接设置、日志记录规则等。根据系统资源和应用需求对这些......
  • MySQL基础操作
    目录一、用户管理1、创建用户2、查看用户3、删除用户4、修改密码二、权限管理1、赋予权限2、查看权限3、收回权限三、复制表结构和数据四、数据库操作1、创建数据库2、查看该数据库基本信息3、删除数据库4、查看MySQL中所有的数据库5、将数据库的字符集修改为gbk6、查看当前使用的......
  • mysql中将where条件中过滤掉的group by分组后查询无数据的行进行补0
    背景mysql经常会用到groupBy来进行分组查询,但也经常会遇到一个问题,就是当有where条件时,被where条件过滤的数据不显示了。例如我有一组数据:我想查询创建时间大于某一范围的spu的分组下的sku的数量正常的sql查出的话,假如不存在相关记录SELECTproduct_id,count(*)countF......
  • 2-2、dockerfile之php-fpm,mysql
    dockerfile之php-fpm#cddocker-training/php-fpm/#lsDockerfilenginx_nginx.confsupervisor_nginx.confnginx_default.confphp_www.confsupervisor_php-fpm.conf各文件解释:nginx_nginx.conf替换默认的nginx.conf文件nginx_default.conf替换默......
  • 数据库sql入门
    目录前言:一、什么是sql1、定义2、类型二、什么是数据库三、数据库的增删改1、查询数据库  2、创建数据库 3、删除数据库4、选择进入数据库5、创建表6、查看表的信息7、查看数据表列表8、删除数据表9、修改数据库表名 10、修改字符集11、写入内容12、增......
  • [20240409]为什么一条sql语句在实例2执行要慢的分析.txt
    [20240409]为什么一条sql语句在实例2执行要慢的分析.txt--//生产系统遇到一个奇怪现象,一条sql语句在实例2要比实例1慢很多,展开分析看看.1.环境:[email protected]:9014/ywdb>@ver1PORT_STRING                   VERSION       BANNER---------------......
  • MySQL的基础操作(二)
    目录一.数据库约束1.主键约束(PrimaryKey)2.唯一约束(Unique)3.外键约束(ForeignKey):4.检查约束(Check)5.默认约束(Default)二.聚合查询1.简单聚合函数2.GROUPBY子句3.HAVING子句三.联合查询1.内连接2.左连接3.右连接4.子查询5.合并查询一.数据库......
  • MySQL的基础操作
    目录一.数据库的操作1.显示当前的数据库2.创建数据库3.删除数据库4.选择数据库补充:二.表的基础操作1.常用数据类型:2.查看表结构3.创建表4.删除表三.表的增删改查1.新增(Create)2.查询(Retrieve)3.修改(Update)4.删除(Delete)一.数据库的操作1.显示当前的数据库......
  • MYSQL五个常见的聚合函数
    学生表DDLCREATETABLE`student`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'学号',`createDate`datetimeDEFAULTNULL,`userName`varchar(20)DEFAULTNULL,`pwd`varchar(36)DEFAULTNULL,`phone`varchar(11)DEFAULTNULL,`age`tinyi......