my question is: Are your service layer bound to tecnology you use?
For example, if you using hibernate, you put into your service layer some hql-queries or criteria-queries that are only hibernate features or you call simply DAO(and dao has hibernate implementation, and maybe jdbc implementation etc..) ?
I have some trouble to build an efficent layered architecture for my software.
EDIT This is a simple service...i think it's a service... without bound to tecnlogy i using (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 ...
}
}
And this is a service with use Dao implementation
@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 ...
}
}
Wich of these two approach is ri开发者_C百科ght?
EDIT2
So, to summarize what I understood:
// 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
}
Sorry for this wall of text, maybe can be useful for others i hope, im go in the right direction? My service layer need an interface? Is all corectly layered? I need a control layer too?
Thanks.
My suggestion:
for larger projects, use a dedicated, interface based DAO layer. Don't let your service layer know anything about the underlying persistence technology. Use Hibernate / JPA / JDBC / JDO / whatever only in the DAO layer.
for smaller projects it may be okay to have a service layer only (especially given the fact that both Hibernate Session
and JPA EntityManager
expose most standard DAO behavior out of the box.
Basic rule of thumb: if you're making a technology change, make sure you only need to change one layer of your application
Update: here's a sample DAO interface. Your service layer would only code against this interface, and the implementation would do the session / entityManager / jdbc calls without the service layer needing to know.
public interface CustomerDao extends CommonDao<Customer>{
Customer getCustomerByEmail(String emailAddress);
List<Customer> getCustomersWithinAgeRange(int lowerBound, int upperBound);
}
The key: in your service layer, specify your dependencies interface-based, i.e.
private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao){
this.customerDao = customerDao;
}
instead of
// 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;
}
The DAO is the place for any database specific querying - JDBC or Hibernate in your case.
The service tier is meant for offering an API to consumers like a Presentation tier or others. There would be no reason to pollute the service tier with database specifics. Your service tier might have business logic which is fine, but it should not be aware of the underlying DB implementation IMO
精彩评论