关于如何彻底分离业务层和数据层,请达人指教!

时间:2021-08-05 14:47:58
我想达到的目的是:把数据访问层(这一层由专门的Team来做)完全独立出来,对于业务层来说是完全透明的,也就是说写业务层的程序员完全不需要知道数据库的表结构,他们只知道业务对象,他们不需要写任何的SQL.如果有很多项目,那所有项目的数据库访问层全部都由一个专门的Team来做,这样可以可以避免程序员乱下SQL导致的性能问题.
问题:没有头绪,不知道该如何实现.目前有几个项目全部采用spring的结构,但数据访问这一块都是由各个项目的程序员完成,很多人都不是很懂得下SQL,SQL的效率就更不用说了.

望专家/有经验的达人指点,先谢谢各位了.(问题解决了会多加些分给各位)

25 个解决方案

#1


大体明白什么意思.
建议,SQL语句写在配置文件里,任何访问数据库的SQL语句都从文件里读取,这样修改SQL简单些
写一个通用接口,用来对数据库的访问,任何需要访问数据库的地方只要实现这个接口就可以了
你可以扩展接口,建议对数据库的操作方法尽量写活,写成通用的.

数据访问层(这一层由专门的Team来做),这样专门的TEAM就可以专心开发数据访问层

个人建议,看对你有用不

#2


谢谢jcnll

其实现在我们的SQL已经是写在配置文件里面的了,而且它们也是分别由各个项目的开发人员自己写的,也就是说他们很清楚数据库结构,这样他们写的业务层里面还是可以看到数据库结构的影子,而我要想把业务层跟数据层彻底分开,写业务层的开发人员对数据库表结构全然不知,所以我不知道这样两个Team(业务开发Team和数据访问Team)要以什么样的方式(打个比方,数据访问Team提供给业务开发Team一个包,给他们调用,而这个包就可以产生或者通过配置文件读取到相应的SQL,而不是由业务开发程序员自己写)去配合,才能使得开发出来的软件做到我前面说的那样.

我主要是对业务层跟数据层之间的这个交互机制想不清楚,不知道这流程要怎么跑.
大家都来发发言,有什么好的观点都拿出来分享一下,再次感谢大家分享

#3


补充一下,数据访问这一层在完成数据访问的动作(一般情况是查询动作)之后需要对查询到的信息封装成对象实例,比如说customer,也就是我前面提到的写业务层的开发人员根本不知道什么表啊之类的,他们只知道类似customer之类的对象,实体.

#4


好像在描述的都是DAO层的功能。建议楼主去查看下吧。

就是楼补充的内容:
补充一下,数据访问这一层在完成数据访问的动作(一般情况是查询动作)之后需要对查询到的信息封装成对象实例,比如说customer,也就是我前面提到的写业务层的开发人员根本不知道什么表啊之类的,他们只知道类似customer之类的对象,实体

#5


DAO层也好还什么层也好,我就是想把数据访问这一层完全抽出来由一个专门的团队负责,而不是程序员从头写到尾,无论是数据访问层还是业务逻辑层都由他自己来完成

#6


jdbcTemplate 包装的不就是很好的吗,你可以把数据库的东西,都封到一个MAPPING里面...对于写业务的人直接搞用就行了

还有一各方法就是用HIBERNATE 真接生成BO,或DAO,这样,可以再分出来一层,做并行的开发了吧

#7


问题是我就是不想写业务层的程序员去搞数据访问层啊

#8


让写数据访问层的实现接口,在其中访问数据,返回业务对象,或业务对象list

业务局只要调用这个接口就可以了

#9


嗯,赞同9441的想法.
可是如果想写业务层的开发人员完全不知道数据库结构也不是一件很容易的事.我想在数据访问层还是应该有从数据库的表映射过来的对象吧,而且这种对象需要跟业务层的对象也有相应的对应关系之类的吧,还有就是那些一对多,多对多的关系要怎么做,类的结构应该怎样,希望大家能分享一下你们的宝贵经验和想法,谢谢!

#10


引用 9 楼 eyesdragon 的回复:
嗯,赞同9441的想法. 
可是如果想写业务层的开发人员完全不知道数据库结构也不是一件很容易的事.我想在数据访问层还是应该有从数据库的表映射过来的对象吧,而且这种对象需要跟业务层的对象也有相应的对应关系之类的吧,还有就是那些一对多,多对多的关系要怎么做,类的结构应该怎样,希望大家能分享一下你们的宝贵经验和想法,谢谢!


叫DAO层也好叫数据访问层也好,这个都是已经在项目中用了很多年的东西。javaeye上有大篇大篇的文章在描述这个东西。

对于抽象出DAO层来解耦已经有了很多资料,为何楼主不去搜索下再来问贴呢?

#12


JAVA交流与学习群:45609427  
挑战技术,超越自我!!

#13


使用hibernate的命名查询
<sql-query name="myquery">
  //关联返回的结果和实体类
  <return alias="a" class="AAAAA">
  //定义命名SQL查询的语句
  select {a.*} from xxxx  a where a.x......
<sql-query>

在操作时:
list l = session.getNamedQuery("myquery").list();
 

#14


定义好层与层之间的接口,就行了呀,
面向对象是接口编程,不是实现类编程!

#15


是否可以这样考虑:

首先确定业务层与集成层(就是你说的数据访问层)的接口。定义这些接口,并将其交给集成层开发。对于业务层来讲可以使用工厂方法来创建DAO,接口和DAO的映射可以写到XML文件中,可以使用JFIG这个开源工具。

很容易!

#16


引用 14 楼 Chariszou 的回复:
定义好层与层之间的接口,就行了呀, 
面向对象是接口编程,不是实现类编程!

#17


建议使用Hibernate吧,可以分离出数据访问层,按你描叙的要求用Hibernate是比较合适的。
如果要进一步解耦合,定义层间借口,适用一些设计模式,是可以做到的。
另外,业务层完全不知道表结构是可以的,但是无论怎么分离,很多字段的含义还是必须知道的,个人觉得。

#18


其实你开始是懂业务的人要懂怎么把业务转化为SQL方式
现在你又想懂SQL的人怎么应用到业务中。
我不知道MVC设计模式的M层,是你说的数据层还是数据层和业务层的统称,首先,你为数据层和业务层用接口定义连接(用sprint)也行,在数据层,实现所有业务的所有方法(每个业务定义一个对象,每个对象的业务方法参数都不要SQL语句,而是ID(更新,单个查询),或者是空(查询所有),数据操作随便你用JDBC,ODBC,HIBERNATE),业务层调用模型层,只需要调用对应接口方法就行了

#19


DAO。。。

#20


建议: 采用模型驱动设计,这样的话你将模型设计出来,业务层的人员直接对模型进行操作,根本不需要理解数据如何保存如何获取,他只需要提出,我需要这样的数据即可,这采用接口实现分离来做

#21


其实你面临的问题就是我的问题,我们公司做的东西主要是收广播,广播的消息你可以看做是数据库来的,如此推理,我们也不知道数据库的结构!

这其实不是问题,你真想做成完全独立只能用Map来包装,因为你无法确定你的前期业务就分析的合理.针对业务层,你提供的仅仅是一个接口。需要添加业务就添加接口,数据库团队则负责实现这个接口返回List或者Map,插入数据也是List或者Map丢进接口!
除此之外,数据库团队还应该提供一套详尽的Map结构文档.接口文档.

业务层可以再次通过map,list封装出pojo.这个时候抽象已经成型.
但是我觉得没有这个必要,因为如果不涉及到业务永远无法清楚的知道你需要哪些数据,这些都不是前期能完完全全分析出来的。所以你可能更多的时间在更新文档,更新接口,更新map结构
所以还是一个稳定高扩展的框架比较好.都参与到基于实现的框架设计开发中,把所有的sql配置活了就很好了.

#22


这类问题,常用的解决方法是采用门面模式来封装和屏蔽。
欢迎到我的博客来讨论:   http://expert.blog.51cto.com

#23


这类问题,常用的解决方法是采用门面模式来封装和屏蔽。 
欢迎到我的博客来讨论:   http://expert.blog.51cto.com

#24


分层开发,用接口提供支持,用junit的mock进行单元测试

action---service(接口)---service实现类---dao(接口)---dao实现类

action中用mock模拟service的实现类

service中也用mock模拟dao的实现类

这样可以做到所有层分离,但是引入了mock的额外代码,不过为了保证每个层的分离与各层的方法好使,也是值得的

#25


你的思路很好,是典型的分层开发。
这样做的好处是:
    每一层开发人员的技术要求简单了,只需要关注自己做的,比如表示层只关心struts,业务只关心业务对象,持久层只关心sql.
   每个层单独开发,错误减少,代码质量提高。一个人设计的错误是固定的,多个人设计的错误就会交叉,会不容易控制。且一个人做,熟悉程度高,容易解决问题。
   问题是:
   联合调试增加了难度,要多个小组配合,容易出问题。
   开发人员未必接受,因为大家都想能接触多点技术,可以提高自己的水平,这样的思想所有的人都有,如果只是简单地做,容易出现反感,无聊的心态。
   这些在我以前的项目中就遇到, 

#1


大体明白什么意思.
建议,SQL语句写在配置文件里,任何访问数据库的SQL语句都从文件里读取,这样修改SQL简单些
写一个通用接口,用来对数据库的访问,任何需要访问数据库的地方只要实现这个接口就可以了
你可以扩展接口,建议对数据库的操作方法尽量写活,写成通用的.

数据访问层(这一层由专门的Team来做),这样专门的TEAM就可以专心开发数据访问层

个人建议,看对你有用不

#2


谢谢jcnll

其实现在我们的SQL已经是写在配置文件里面的了,而且它们也是分别由各个项目的开发人员自己写的,也就是说他们很清楚数据库结构,这样他们写的业务层里面还是可以看到数据库结构的影子,而我要想把业务层跟数据层彻底分开,写业务层的开发人员对数据库表结构全然不知,所以我不知道这样两个Team(业务开发Team和数据访问Team)要以什么样的方式(打个比方,数据访问Team提供给业务开发Team一个包,给他们调用,而这个包就可以产生或者通过配置文件读取到相应的SQL,而不是由业务开发程序员自己写)去配合,才能使得开发出来的软件做到我前面说的那样.

我主要是对业务层跟数据层之间的这个交互机制想不清楚,不知道这流程要怎么跑.
大家都来发发言,有什么好的观点都拿出来分享一下,再次感谢大家分享

#3


补充一下,数据访问这一层在完成数据访问的动作(一般情况是查询动作)之后需要对查询到的信息封装成对象实例,比如说customer,也就是我前面提到的写业务层的开发人员根本不知道什么表啊之类的,他们只知道类似customer之类的对象,实体.

#4


好像在描述的都是DAO层的功能。建议楼主去查看下吧。

就是楼补充的内容:
补充一下,数据访问这一层在完成数据访问的动作(一般情况是查询动作)之后需要对查询到的信息封装成对象实例,比如说customer,也就是我前面提到的写业务层的开发人员根本不知道什么表啊之类的,他们只知道类似customer之类的对象,实体

#5


DAO层也好还什么层也好,我就是想把数据访问这一层完全抽出来由一个专门的团队负责,而不是程序员从头写到尾,无论是数据访问层还是业务逻辑层都由他自己来完成

#6


jdbcTemplate 包装的不就是很好的吗,你可以把数据库的东西,都封到一个MAPPING里面...对于写业务的人直接搞用就行了

还有一各方法就是用HIBERNATE 真接生成BO,或DAO,这样,可以再分出来一层,做并行的开发了吧

#7


问题是我就是不想写业务层的程序员去搞数据访问层啊

#8


让写数据访问层的实现接口,在其中访问数据,返回业务对象,或业务对象list

业务局只要调用这个接口就可以了

#9


嗯,赞同9441的想法.
可是如果想写业务层的开发人员完全不知道数据库结构也不是一件很容易的事.我想在数据访问层还是应该有从数据库的表映射过来的对象吧,而且这种对象需要跟业务层的对象也有相应的对应关系之类的吧,还有就是那些一对多,多对多的关系要怎么做,类的结构应该怎样,希望大家能分享一下你们的宝贵经验和想法,谢谢!

#10


引用 9 楼 eyesdragon 的回复:
嗯,赞同9441的想法. 
可是如果想写业务层的开发人员完全不知道数据库结构也不是一件很容易的事.我想在数据访问层还是应该有从数据库的表映射过来的对象吧,而且这种对象需要跟业务层的对象也有相应的对应关系之类的吧,还有就是那些一对多,多对多的关系要怎么做,类的结构应该怎样,希望大家能分享一下你们的宝贵经验和想法,谢谢!


叫DAO层也好叫数据访问层也好,这个都是已经在项目中用了很多年的东西。javaeye上有大篇大篇的文章在描述这个东西。

对于抽象出DAO层来解耦已经有了很多资料,为何楼主不去搜索下再来问贴呢?

#11


#12


JAVA交流与学习群:45609427  
挑战技术,超越自我!!

#13


使用hibernate的命名查询
<sql-query name="myquery">
  //关联返回的结果和实体类
  <return alias="a" class="AAAAA">
  //定义命名SQL查询的语句
  select {a.*} from xxxx  a where a.x......
<sql-query>

在操作时:
list l = session.getNamedQuery("myquery").list();
 

#14


定义好层与层之间的接口,就行了呀,
面向对象是接口编程,不是实现类编程!

#15


是否可以这样考虑:

首先确定业务层与集成层(就是你说的数据访问层)的接口。定义这些接口,并将其交给集成层开发。对于业务层来讲可以使用工厂方法来创建DAO,接口和DAO的映射可以写到XML文件中,可以使用JFIG这个开源工具。

很容易!

#16


引用 14 楼 Chariszou 的回复:
定义好层与层之间的接口,就行了呀, 
面向对象是接口编程,不是实现类编程!

#17


建议使用Hibernate吧,可以分离出数据访问层,按你描叙的要求用Hibernate是比较合适的。
如果要进一步解耦合,定义层间借口,适用一些设计模式,是可以做到的。
另外,业务层完全不知道表结构是可以的,但是无论怎么分离,很多字段的含义还是必须知道的,个人觉得。

#18


其实你开始是懂业务的人要懂怎么把业务转化为SQL方式
现在你又想懂SQL的人怎么应用到业务中。
我不知道MVC设计模式的M层,是你说的数据层还是数据层和业务层的统称,首先,你为数据层和业务层用接口定义连接(用sprint)也行,在数据层,实现所有业务的所有方法(每个业务定义一个对象,每个对象的业务方法参数都不要SQL语句,而是ID(更新,单个查询),或者是空(查询所有),数据操作随便你用JDBC,ODBC,HIBERNATE),业务层调用模型层,只需要调用对应接口方法就行了

#19


DAO。。。

#20


建议: 采用模型驱动设计,这样的话你将模型设计出来,业务层的人员直接对模型进行操作,根本不需要理解数据如何保存如何获取,他只需要提出,我需要这样的数据即可,这采用接口实现分离来做

#21


其实你面临的问题就是我的问题,我们公司做的东西主要是收广播,广播的消息你可以看做是数据库来的,如此推理,我们也不知道数据库的结构!

这其实不是问题,你真想做成完全独立只能用Map来包装,因为你无法确定你的前期业务就分析的合理.针对业务层,你提供的仅仅是一个接口。需要添加业务就添加接口,数据库团队则负责实现这个接口返回List或者Map,插入数据也是List或者Map丢进接口!
除此之外,数据库团队还应该提供一套详尽的Map结构文档.接口文档.

业务层可以再次通过map,list封装出pojo.这个时候抽象已经成型.
但是我觉得没有这个必要,因为如果不涉及到业务永远无法清楚的知道你需要哪些数据,这些都不是前期能完完全全分析出来的。所以你可能更多的时间在更新文档,更新接口,更新map结构
所以还是一个稳定高扩展的框架比较好.都参与到基于实现的框架设计开发中,把所有的sql配置活了就很好了.

#22


这类问题,常用的解决方法是采用门面模式来封装和屏蔽。
欢迎到我的博客来讨论:   http://expert.blog.51cto.com

#23


这类问题,常用的解决方法是采用门面模式来封装和屏蔽。 
欢迎到我的博客来讨论:   http://expert.blog.51cto.com

#24


分层开发,用接口提供支持,用junit的mock进行单元测试

action---service(接口)---service实现类---dao(接口)---dao实现类

action中用mock模拟service的实现类

service中也用mock模拟dao的实现类

这样可以做到所有层分离,但是引入了mock的额外代码,不过为了保证每个层的分离与各层的方法好使,也是值得的

#25


你的思路很好,是典型的分层开发。
这样做的好处是:
    每一层开发人员的技术要求简单了,只需要关注自己做的,比如表示层只关心struts,业务只关心业务对象,持久层只关心sql.
   每个层单独开发,错误减少,代码质量提高。一个人设计的错误是固定的,多个人设计的错误就会交叉,会不容易控制。且一个人做,熟悉程度高,容易解决问题。
   问题是:
   联合调试增加了难度,要多个小组配合,容易出问题。
   开发人员未必接受,因为大家都想能接触多点技术,可以提高自己的水平,这样的思想所有的人都有,如果只是简单地做,容易出现反感,无聊的心态。
   这些在我以前的项目中就遇到,