сервисный уровень связан с технологией БД в весеннем приложении - PullRequest
1 голос
/ 11 ноября 2010

у меня вопрос такой: привязан ли ваш сервисный уровень к используемой вами технологии?

Например, если вы используете hibernate, вы добавляете в свой сервисный слой некоторые hql-запросы или критерии-запросы, которые являются только функциями спящего режимаили вы просто называете DAO (а у dao есть hibernate-реализация, и, возможно, jdbc-реализация и т. д.)?

У меня возникли проблемы с созданием эффективной многоуровневой архитектуры для моего программного обеспечения.

РЕДАКТИРОВАТЬ Это простой сервис ... я думаю, что это сервис ... без привязки к технологии Я использую (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 ...
    }
}

Какой из этих двух подходов является правильным?


РЕДАКТИРОВАТЬ2

Итак, подведем итог тому, что я понял:

// 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 ]

2 голосов
/ 11 ноября 2010

Мое предложение:

для более крупных проектов, используйте выделенный слой 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 голос
/ 11 ноября 2010

DAO - это место для любых запросов к базе данных - JDBC или Hibernate в вашем случае.

Сервисный уровень предназначен для предоставления API пользователям, таким как уровень презентации или другие. Не было бы никакой причины загрязнять уровень обслуживания спецификой базы данных. Ваш уровень обслуживания может иметь бизнес-логику, которая подходит, но он не должен знать о базовой реализации БД IMO

...