服务层与春季应用程序中的DB Tecnology绑定
-
08-10-2019 - |
题
我的问题是:您的服务层是否限于您使用的TECNOLOGY?
例如,如果您使用Hibernate,则将某些仅是Hibernate功能的HQL-Queries或Criteria-Queries放入服务层中,或者您可以简单地调用DAO(DAO具有Hibernate的实现,也许是JDBC实现等。)?
我很难为我的软件构建有效的分层体系结构。
编辑这是一项简单的服务...我认为这是一项服务...不属于我使用的Tecnlogy(Hibernate)
@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
}
对不起,这堵文字,也许对我希望的其他人有用,我朝着正确的方向前进?我的服务层需要接口吗?所有旋转分层吗?我也需要一个控制层吗?
谢谢。
解决方案
我的建议:
对于较大的项目,请使用基于接口的专用DAO层。不要让您的服务层了解有关基础持续技术的任何信息。使用Hibernate / JPA / JDBC / JDO /仅在DAO层中的任何内容。
对于较小的项目,可能只有一个服务层(特别是考虑到两个都冬眠的事实 Session
和JPA EntityManager
开箱即用的大多数标准的DAO行为。
基本的经验法则:如果您要进行技术更改,请确保您只需要更改应用程序的一层
更新: 这是示例dao接口。您的服务层仅对此接口进行编码,并且实现将执行会话 / 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;
}
其他提示
DAO是任何数据库特定查询的地方 - 在您的情况下,JDBC或Hibernate。
该服务层旨在为演示文稿或其他人等消费者提供API。没有理由用数据库细节污染服务层。您的服务层可能具有很好的业务逻辑,但不应意识到基础DB实施IMO