java – 如何避免在Service类中重复DAO方法? @Transactional注释DAO和服务类 – 这是可以接受的做法...

栏目: Java · 发布时间: 6年前

内容简介:翻译自:https://stackoverflow.com/questions/16147144/how-to-avoid-repeatig-dao-methods-in-service-classes-transactional-annotated-d

我知道最佳做法是同时使用服务层和dao层,并在服务级别添加@Transactional注释.但在我的情况下,这意味着我的大多数服务类都是为了重复DAO方法而创建的……这非常令人恼火.

例如.

public interface FooDAO {
 public List<FooVO> list(int cathegoryId);
 public List<FooVO> list(int cathegoryId, int ownerId);
}

@Service
@Transactional
public class FooService {
   protected @Autowired FooDAO dao;
   public List<FooVO> list(int cathegoryId) { 
      dao.list(cathegoryId); 
   }
   public List<FooVO> list(int cathegoryId, int authorId) { 
      dao.list(cathegoryId, authorId) 
   }
}

这有多笨?

在大多数情况下,我真的不需要花哨的服务方法,因为通常这是一个例如.导管描述和与导管相匹配的实体列表.这就是为什么我在寻找简化的解决方案.像使用泛型以避免重复DAO一样辉煌:D http://www.javablog.fr/javahibernate-dont-repeat-the-dao-with-a-genericdao.html

我找到了答案.其中我读过

Where does the @Transactional annotation belong?

但还是没有找到我的答案.

所以我想知道用@Transactional注释DAO方法真是个坏主意.受到 http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/#apistrategy 的启发,我找到了解决方案.

如果:

>我只有一个服务类(确实需要)并使用@Transactional注释其方法

>对于所有其他(简单)情况:我使用@Transactional(propagation = Propagation.MANDATORY)注释DAO方法,使用@Transactional注释我的控制器方法(propagation = Propagation.REQUIRES_NEW)

**更新1 **

它看起来像这样:

public interface FooDAO {
 @Transactional(propagation = Propagation.MANDATORY, readOnly=true)
 public List<FooVO> list(int cathegoryId);
 ...
}

@Service
public class FooService {
   protected @Autowired FooDAO dao;

   @Transactional // propagation REQUIRED
   public List<FooVO> magic(FooVO fooVO) { 
      //do sth complicated here ;)
   }
   // We do not repeat DAO methods in the Service class. 
   // No wrapping methods here !!!
}

@Controller
public class FooMagicController {
    protected @Autowired  FooService fooService;
    ...
        fooService.magic(fooVO);
    ...
}
@Controller
public class FooController {
    protected @Autowired  FooDAO dao; //DAO wired directly in the Controller class !!!

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @RequestMapping(".....")
    public String listFoo(Model model,...) throws Exception {
        model.addAttribute("list", dao.list(13) );
        return "xyz";
    }
}

在每种情况下,DAO使用“上方”管理的会话.

这是非常糟糕的主意吗?有没有更好的方法来实现我的需求?

我不会说这是一个坏主意,因为它取决于您选择设计应用程序的情况.

如果你觉得,你不需要任何服务类(即API的类比纯DAO API更多),那么我觉得最好避免使用服务类,只使用直接自动连接到控制器的DAO实现.

但是如果你需要做一些额外的逻辑并希望将它作为API公开,那么你可以编写服务类,它将实现该自定义逻辑以及这些DAO方法的包装函数(如上所述).这将使代码更清晰,因为您只需要将服务类连接到控制器,同时您可以通过使用服务类中的包装API来进行DAO调用.

如果您只为自定义API保留服务类,而没有DAO的任何包装API,那么如果您需要进行任何数据访问调用,您还需要将DAO连接到控制器类中.因此,在这种情况下,您将有效地连接服务类和控制器类中的DAO.

更新1

以下是其中一个示例项目的Controller和Service类

调节器

public class HomePageController  {


@Autowired
private VideoService videoService;

    //Controller method
@RequestMapping(value = "/tag/mostviewed")
public @ResponseBody
Map<String, List<Video>> showMostViewedVideosForTag (){
            //service api
             videoService.getMostViewedVideo(curatorTagName)
       }

}

服务类

@Service(value = "videoService")
@Transactional(readOnly = true)
public class VideoServiceImpl implements VideoService {

@Autowired
private VideoDAO videoDAO;

@Autowired
private TagDAO tagDAO;

 // WRAPPER API FOR THE DAO

@Override
public List<Video> getMostViewedVideo(String tagName)  {
    return videoDAO.getMostViewedVideo(tagName);
}


 // A non wrapper API which does some business logic
@Override
@Transactional
public void assignTagsToVideo(String videoId, String userId, String... tags)  {

        for (String tag : tags) {
            if (tagHeritageDAO.getTagHeritage(tag, videoId, userId) == null) {
                Tag tagObj = tagDAO.getTag(tag);
                if (tagObj != null) {
                    //some logic here to add tags to video
                }
            }
        }

    videoDAO.update(video);
}
}

如您所见,唯一的服务是在控制器类中连接的,并且dao连接到服务类.这就是我所说的混合模式.抱歉,如果我困惑你.

翻译自:https://stackoverflow.com/questions/16147144/how-to-avoid-repeatig-dao-methods-in-service-classes-transactional-annotated-d


以上所述就是小编给大家介绍的《java – 如何避免在Service类中重复DAO方法? @Transactional注释DAO和服务类 – 这是可以接受的做法...》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网络空间导论

网络空间导论

李良荣、方师师 / 复旦大学出版社 / 2018-6-1 / 38

在互联网蓬勃发展的今天,新闻传播学科该往何处去?在长达半个多世纪的深入研究后,李良荣教授及其团队给出了答案:从“小新闻”走向“大传播”,并撰写了这本开创性的教材:《网络空间导论》。 在本书中,互联网被定义为“空间”——持续演进的数字化现实。为了深刻把握网络空间的内涵,本书提供了六个维度的观察:技术应用、组织架构、政治经济、媒介文化、网络素养、安全治理,并以大胆且富有建设性的观点重新定义了新闻......一起来看看 《网络空间导论》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器