サービスレイヤーは、春のアプリケーションでDBテクノロジーにバインドされています

StackOverflow https://stackoverflow.com/questions/4152928

質問

私の質問は、あなたのサービスレイヤーが使用しているテクノロジーに縛られていますか?

たとえば、Hibernateを使用している場合、サービスレイヤーにHQL-QueriesまたはCriteria-Queriesを使用して、Hibernate機能のみであるか、単にDAOを呼び出す(DAOには冬眠の実装、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 ...
    }
}

これらの2つのアプローチのうちは正しいですか?


編集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
}

このテキストの壁には申し訳ありませんが、多分私が望む他の人に役立つかもしれません、私は正しい方向に行くでしょうか?私のサービスレイヤーにはインターフェイスが必要ですか?すべてがレイヤードされていますか?コントロールレイヤーも必要ですか?

ありがとう。

役に立ちましたか?

解決

私のおすすめ:

大規模なプロジェクトには、専用のインターフェイスベースのDAOレイヤーを使用します。根底にある永続性テクノロジーについて、サービスレイヤーに何も知らせないでください。 hibernate / jpa / jdbc / jdo / dao層のみの場合は何でも使用します。

小規模なプロジェクトでは、サービスレイヤーのみを持っているだけでも大丈夫かもしれません(特に両方の冬眠があるという事実を考えると Session とJPA EntityManager ほとんどの標準的なDAOの動作を箱から出します。

基本的な経験則:テクノロジーを変更している場合は、アプリケーションの1つのレイヤーのみを変更する必要があることを確認してください

アップデート: これがサンプル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または冬眠の場所です。

サービス層は、プレゼンテーション層などのような消費者にAPIを提供するためのものです。データベースの詳細を使用して、サービス層を汚染する理由はありません。あなたのサービス層には問題ないビジネスロジックがあるかもしれませんが、基礎となるDB実装IMOに気づかないはずです

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top