服务层在spring应用程序中绑定到DB技术

时间:2010-11-11 09:27:51

标签: java hibernate spring service-layer

我的问题是:您的服务层是否与您使用的技术绑定?

例如,如果你使用hibernate,你可以在你的服务层添加一些hql-queries或criteria-queries,它们只是hibernate特性,或者你只是调用DAO(而dao有hibernate实现,也许是jdbc实现等等。) ?

为我的软件构建一个高效的分层架构我遇到了一些麻烦。

修改 这是一个简单的服务...我认为这是一项服务......没有限制tecnlogy我使用(休眠)

@Repository
public class PersonHibernateDAO implements PersonDAO {

    @Autowired
    SessionFactory sessionFactory;

    ... dao crud operations(implementation of PersonDAO interface) using sessionfactory ...

    //and some hibernate features methods
    public Person findByCriteria(Criterion criterion){
        // code
    }
}

@Service
public class PersonService {

    @Autowired
    private PersonDAO personDao;

    @Autowired
    private AccessDAO accessDao;

    @Transactional
    public boolean hasPermission(String username, String accessCode){
        Person p=personDao.findByUsername(username);
        Access a=accessDao.findByCode(accessCode);
        ... etc ...
    }
}

这是一个使用Dao实现的服务

@Service
public class PersonService {

    @Autowired
    private PersonDAO personDao;

    @Autowired
    private AccessDAO accessDao;

    @Transactional
    public boolean hasPermission(String username, String password){
        Person p=((PersonHibernateDao)personDao).findByCriteria(Restrictions.eq("username", username);
        ... etc ...
    }
}

这两种方法是对的吗?


EDIT2

所以,总结一下我的理解:

// BASE DAO INTERFACE
public interface DAOInterface<EntityClass, IDType extends Serializable> {
    EntityClass get(IDType id);
    EntityClass findById(IDType id);
    EntityClass save(EntityClass entity);
    EntityClass update(EntityClass entity);
    void delete(EntityClass entity);
}

// AN HIBERNATE IMPLEMENTATION
public abstract class HibernateDAO<EntityClass, IDType extends Serializable> implements DAOInterface<EntityClass, IDType> {

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory){
        this.sessionFactory=sessionFactory;
    }

    public void getSessionFactory(){
        return this.sessionFactory;
    }

    // Implements all DAOInterface method using sessionFactory

}

// PERSON DAO INTERFACE
public interface PersonDAO extends DAOInterface<Person, Long>{

    Person findByName(String name, String surname);
    List<Person> getInAgeRange(int year1, int year2);
}

// PERSON HIBERNATE DAO IMPLEMENTATION
public PersonHDAO extends HibernateDAO<Person, Long> implements PersonDAO{

    // Implements the methods of PersonDAO interface using sessionFactory
}

@Service
public class PersonService {

    //spring inject the correct DAO by its xml config(in this case PersonHDAO
    @Autowired
    private PersonDAO personDAO; 

    // spring manage the transaction
    @Transactional
    public List<Person> getInAgeRange(int year1, int year2){
        return personDAO.getInAgeRange(year1, year2);
    }

}

// NOW... HOW USE IT
//let's assume i have a button, pressing it a table will be populated with all persons in age range
private void actionPerfom(ActionEvent e){
    List<Person> list=personService.getInAgeRange(age1Spinner.getValue(), age2Spinner.getValue());
    //Load a table with list
}

对不起这面墙的文字,也许对我希望的其他人有用,我会朝着正确的方向前进? 我的服务层需要一个接口? 所有核心都是分层的吗?我也需要一个控制层吗?

感谢。

2 个答案:

答案 0 :(得分:2)

我的建议:

对于大型项目,使用基于接口的专用DAO层。不要让您的服务层了解底层持久性技术。使用Hibernate / JPA / JDBC / JDO /只在DAO层中的任何内容。

对于较小的项目,可以仅使用服务层(特别是考虑到Hibernate Session和JPA EntityManager开箱即用的大多数标准DAO行为。

基本经验法则:如果您正在进行技术更改,请确保您只需要更改应用程序的一个层

更新:这是一个示例DAO界面。您的服务层将只针对此接口进行编码,并且实现将执行session / entityManager / jdbc调用,而不需要知道服务层。

public interface CustomerDao extends CommonDao<Customer>{
    Customer getCustomerByEmail(String emailAddress);
    List<Customer> getCustomersWithinAgeRange(int lowerBound, int upperBound);
}

密钥:在您的服务层中,指定基于接口的依赖关系,即

private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao){
    this.customerDao = customerDao;
}

而不是

// this is horrible, it ties the service layer to implementation
// details of the dao layer
private HibernateCustomerDaoImpl customerDao;
public void setCustomerDao(HibernateCustomerDaoImpl customerDao){
    this.customerDao = customerDao;
}

答案 1 :(得分:1)

DAO是任何特定于数据库的查询的地方 - 在您的情况下是JDBC或Hibernate。

服务层旨在向消费者提供API,例如Presentation层或其他。没有理由用数据库细节污染服务层。您的服务层可能具有良好的业务逻辑,但它不应该知道基础数据库实现IMO