可以将Spring DAO合并到服务层吗?

时间:2016-07-25 05:47:38

标签: java spring web-applications dao mybatis

我正在使用spring framework和mybatis开发一个Web应用程序。

在大多数情况下(至少对我来说),DAO的方法非常简短:

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

基本上,我需要在DAO中为每个查询编写一个方法(例如getUser(String userId)),该查询将被转发到正在使用它的服务对象。这对我来说似乎是不必要的。

我的同事正试图让事情变得简单。他像这样写了CommonDao

@Repository
public class CommonDao {
    @Autowired
    private SqlSessionTemplate sqlSession;

    public Object insert(String queryId, Object params) {
        return sqlSession.insert(queryId, params);
    }

    public Object update(String queryId, Object params) {
        return sqlSession.update(queryId, params);
    }

    public Object delete(String queryId, Object params) {
        return sqlSession.delete(queryId, params);
    }

    public Object selectOne(String queryId) {
        return sqlSession.selectOne(queryId);
    }

    public Object selectOne(String queryId, Object params) {
        return sqlSession.selectOne(queryId, params);
    }
}

因此我们可以在以下服务中使用这些方法:

@Service
public class CrudService {
    ...
    @Autowired
    private CommonDao commonDao;
    ...

    public UserDto selectUser(Integer userId) {
        ...
        UserDto userDto = (UserDto) commonDao.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
        ...
    }
}

我有点喜欢这个approch,因为它使代码更简单。但我不确定这是一个很好的关注点。

2 个答案:

答案 0 :(得分:1)

要避免样板代码并同时保持类型安全并让服务层免受DAO实施细节的影响,请使用spring-mybatis MapperScannerConfigurer

在这种情况下,您可以使用类型安全的映射器替换您的DAO。

相当于你的DAO

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
  public User getUser(String userId) {
    return (User)getSqlSession().selectOne(
        "org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

将成为此映射器类

package org.mybatis.spring.sample.mapper;

interface UserMapper {
  User getUser(String userId);
}

如果您将其重命名为UserDao,则根本无需更改服务。服务仅取决于声明的映射器接口。

请注意,您需要定义此接口以确保类型安全,并定义服务的依赖关系。

当然,您需要配置spring-mybatis,以便它根据代码中定义的映射器接口生成映射器实现。这很简单,many options如何做到这一点。

答案 1 :(得分:0)

嗯,你在苦苦挣扎,在MyBatis中是正常的。

你的同事向你指出了某个方向......但CommonDao在这个形状中的真正价值是什么?对我来说这不是很有用。你仍然需要几乎相同数量的代码 - 而且你还需要进行大量的渲染。

正如@Rom Konoval所说,有MapperScannerConfigurer可以生成映射器实现 - 这样你就不会编写冗余实现并且具有类型安全的好处 - 类型转换仍然会发生但是对你隐藏。你可以尝试一下 这是GitHub上的sample usage

或者,您可以自己创建DAO实现(如您所做)或直接在服务中使用SqlSessionTemplate。由你决定。只需保持代码库尽可能小,并遵循常识。