2

spring / hibernate プロジェクト用にカスタム汎用サービス DAO を構成しました。これは、コントローラーから簡単に再利用できるという考えです。

基本的には次のようになります。

public class DefaultService<T> {

private Class<T> e;

public String className(Class<T> e) {
    String clip = e.getName();
    clip = clip.substring(clip.lastIndexOf('.') + 1, clip.length());
    return clip;
}
public List<T> getAll(Integer status) {
    Session session = sessionFactory.getCurrentSession();
    Query query = session.createQuery("FROM " + className(e) + " WHERE status = " + status);
    return query.list();
}
...

以下によって参照されます。

@Autowired
public DefaultService<Address> addressService;
addressService.get(1);

ただし、String clip = e.getName()行は Null ポインター例外をスローします。クラスを属性セクションに移動すると、これを機能させることができます (addressService.get(Address.class, 1)ただし、特に複数の異なるクラスが呼び出されている場合は、これがやや乱雑であることがわかります.

すべての関数に値を繰り返し追加せずに、クラスに値を正しく生成させる方法はありますか?

前もって感謝します。

4

3 に答える 3

5

私は似たようなことをしました。ジェネリッククラスもコンストラクター引数である必要があります。私のものは休止状態のエンティティを使用しますが、テーブル名の文字列を渡すことができます。

public class DomainRepository<T> {

    @Resource(name = "sessionFactory")
    protected SessionFactory sessionFactory;

 public DomainRepository(Class genericType) {
        this.genericType = genericType;
    }

 @Transactional(readOnly = true)
    public T get(final long id) {
        return (T) sessionFactory.getCurrentSession().get(genericType, id);
    }

次に、(必要に応じて)サブクラス化して、以下のようにSpring構成でBeanをカスタマイズまたは単純にセットアップできます。

<bean id="tagRepository" class="com.yourcompnay.data.DomainRepository">
        <constructor-arg value="com.yourcompnay.domain.Tag"/>
</bean>

したがって、コードでそのようにtagRepositoryを参照できます(上および下に投稿されているもの以外のコードは必要ありません):

@Resource(name = "tagRepository")
private DomainRepository<Tag> tagRepository;

また、私はそれをサービスではなくリポジトリと呼びます。サービスはさまざまなタイプとそれらの相互作用(1つだけではない)を処理します。特にSQL文字列を使用した例:

public final String tableName;
public DomainRepository(String tableName) {
      this.tableName = tableName;
}
public List<T> getAll(Integer status) {
    Session session = sessionFactory.getCurrentSession();
    Query query = session.createQuery("FROM " + tableName + " WHERE status = " + status);
    return query.list();
}

そしてあなたの豆をそのように定義してもらいます

<bean id="addressRepository" class="com.yourcompnay.data.DomainRepository">
  <constructor-arg value="address"/>
</bean>

そして、必要に応じて自分でサブクラスを作成することもできます。

public class PersonRepository extends DomainRepository<Person> {
    public PersonRepository(){
        super("person"); //assumes table name is person
    }
于 2013-02-21T13:01:56.023 に答える
0

私が理解しているように、このフィールドに値を設定しなかったため、NPE が発生しました。したがって、この問題は次の 2 つの方法で解決できます。

  1. コメント NimChimpsky のように手動でクラス オブジェクトを設定します。
  2. クラス型を動的に取得します。たとえば、Spring を使用している場合は、次を試してください。

protected Class getEntityClass() { return GenericTypeResolver.resolveTypeArguments(getClass(), DefaultService.class)[0]; }

またはここでいくつかの回避策

于 2013-02-21T13:08:39.513 に答える
0

Address サービス用に特定のクラスを定義することをお勧めします

public class AddressService extends DefaultService<Address>{
  public String getClassName(){
   return "Address";
  }
}

どこ

public String getClassName();

DefaultService で宣言された抽象メソッドであり、(メソッド className() のように) データ アクセス ロジックで使用されます。

このアプローチを使用すると、特定のデータ アクセス ロジック (getUsersByAddress など) を追加できます。

于 2013-02-21T13:18:08.637 に答える