Spring MVC:通用的DAO和服务类 [英] Spring MVC: Generic DAO and Service classes

查看:184
本文介绍了Spring MVC:通用的DAO和服务类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Spring MVC中写web。我使用Generic DAO编写了所有DAO。现在我想重写我的Service类。如何写通用服务?



有我的DAO:

  / * ################################# DAO ########### ##################### * / 
package net.example.com.dao;

import java.util.List;

public interface GenericDao< T> {
public T findById(int id);
public List< T>找到所有();
public void update(T entity);
public void save(T entity);
public void delete(T entity);
}

/ * ----------------------------------- ------------------- * /

package net.example.com.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

@Scope(prototype)
公共抽象类GenericHibernateDaoImpl< T extends Serializable>实现GenericDao< T> {

私人课程< T> clazz中;

@Autowired
private SessionFactory sessionFactory;

public final void setClazz(Class< T> clazzToSet){
this.clazz = clazzToSet;
}

@SuppressWarnings(unchecked)
public T findById(int id){
return(T)getCurrentSession()。get(clazz,id) ;
}

@SuppressWarnings(unchecked)
public List< T> findAll(){
return getCurrentSession()。createQuery(FROM+ clazz.getName())。list();
}

public void update(T entity){
getCurrentSession()。update(entity);
}

public void save(T entity){
getCurrentSession()。save(entity);
}

public void delete(T entity){
getCurrentSession()。delete(entity);
}

protected final session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
}

/ * ------------------------------ ------------------------ * /

包net.example.com.dao;

导入net.example.com.entity.Country;

public interface CountryDao extends GenericDao< Country> {

public Country findByName(String name);
public Country findByCode(String code);

}

/ * ------------------------------- ----------------------- * /

package net.example.com.dao;

import org.springframework.stereotype.Repository;

导入net.example.com.entity.Country;

@Repository
public class CountryDaoImpl extends GenericHibernateDaoImpl< Country> implements CountryDao {

@Override
public Country findByName(String name){
return(Country)getCurrentSession()
.createQuery(FROM Country WHERE name =名称)
.setString(name,name).uniqueResult();

$ b @Override
public Country findByCode(String code){
return(Country)getCurrentSession()
.createQuery(FROM Country WHERE code =:code)
.setString(code,code).uniqueResult();
}

}

/ * ########################## ####### DAO ################################ * /


$ b

和服务:

  / * ################################# SERVICE ################ ################ * / 

package net.example.com.service;

import java.util.List;

公共接口GenericManager< T> {// GenericManager< T>与GenericDao< T>相同。

public T findById(int id);
public List< T>找到所有();
public void update(T entity);
public void save(T entity);
public void delete(T entity);
}

/ * ----------------------------------- ------------------- * /

package net.example.com.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

导入net.example.com.dao.GenericDao;

@Service
公共抽象类GenericManagerImpl< T>实现GenericManager< T> {

@Autowired
保护GenericDao< T>道;

@Override
public T findById(int id){
return dao.findById(id);
}

@Override
public List< T> findAll(){
return dao.findAll();
}

@Override
public void update(T entity){
dao.update(entity);
}

@Override
public void save(T entity){
dao.save(entity);
}

@Override
public void delete(T entity){
dao.delete(entity);
}
}
/ * ---------------------------------- -------------------- * /

package net.example.com.dao;

导入net.example.com.entity.Country;

公共接口CountryManager扩展了GenericDao< Country> {// CountryManager与CountryDao相同

public Country findByName(String name);
public Country findByCode(String code);
}

/ * ----------------------------------- ------------------- * /

package net.example.com.service;

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.example.com.dao.CountryDao;
import net.example.com.entity.Country;

@Service
@Transactional
public class CountryManagerImpl extends GenericManagerImpl< Country>实现CountryManager {

@覆盖
公共列表< Country> findAll(){
return dao.findAll();
}

public国家findById(int id){
返回dao.findById(id);
}

@Override
public Country findByName(String name){
return dao.findByName(name); //编译器(和Eclipse)没有看到findByName !!!!!!!!!
}

@Override
public Country findByCode(String code){
return dao.findByCode(code); //编译器(和Eclipse)没有看到findByCode !!!!!!!!!
}

@Override
public void save(Country country){
dao.save(country);
}

@Override
public void delete(Country country){
dao.delete(country);
}

@Override
public void update(Country country){
dao.update(country);
}

}

/ * -------------------------- ---------------------------- * /

/ * ########## ####################### SERVICE ##########################编译器(和Eclipse)没有看到

###### * /
> findByName
findByCode 方法。我明白为什么。但是我该如何重写呢? 解决方案

问题是,您的GenericDao直接注入到您的GenericManager中,但没有一个是具体的Spring bean,你将永远无法使用你的特定CountryDao。



你不能autowire GenericDao,只能定义它并提供setter:

  //将DAO作为genric参数添加
public abstract class GenericManagerImpl< T,D extends GenericDao< T>>实现GenericManager< T> {
private D dao;

保护无效setDao(D dao){
this.dao = dao;
}

...

}



然后,你将不得不在你的具体服务中注入一个混凝土spring bean。即在 CountryManagerImpl 中:

  //使用具体的DAO实例化具体服务
public class CountryManagerImpl扩展了GenericManagerImpl< Country,CountryDao>实现CountryManager {

//不要在这里重新声明你的dao以保留继承的

//不要忘记注入
@Inject( countryDao)
@Override
protected void setDao(CountryDao dao){
this.dao = dao;
}

...

}

然后,您将拥有一个完整的spring bean,并注入具体的CountryDao类型及其具体方法。



您可以看看我们在RESThub项目上做了什么关于通用服务: https://github.com/resthub/resthub-spring-stack/blob/master/resthub-common/src/main/java/org/resthub/common/service/CrudServiceImpl.java 和一些具体的例子: https://github.com/resthub/todo-backbone-example/blob/master/src/main/java/todo/TodoController.java (使用控制器而不是服务,但它是相似的) p>

希望它有帮助。



(如果有一些拼写错误,我不能现在仔细检查)



,顺便说一句,您应该考虑使用Spring Data而不是使用GenericDaos,但您仍然会对服务有相同的需求。


I am writting web in Spring MVC. I wrote all DAOs using Generic DAO. Now I would like to rewrite my Service classes. How can I write "Generic Service"?

There are my DAOs:

/* ################################# DAO ################################ */
package net.example.com.dao;

import java.util.List;

public interface GenericDao<T> {       
        public T findById(int id);     
        public List<T> findAll();      
        public void update(T entity);  
        public void save(T entity);    
        public void delete(T entity);
}

/* ------------------------------------------------------ */

package net.example.com.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

@Scope("prototype")
public abstract class GenericHibernateDaoImpl<T extends Serializable> implements GenericDao<T> {

        private Class<T> clazz;

        @Autowired
        private SessionFactory sessionFactory;

        public final void setClazz(Class<T> clazzToSet) {
                this.clazz = clazzToSet;               
        }

        @SuppressWarnings("unchecked")
        public T findById(int id) {
                return (T) getCurrentSession().get(clazz, id);
        }

        @SuppressWarnings("unchecked")
        public List<T> findAll() {
                return getCurrentSession().createQuery("FROM " + clazz.getName()).list();              
        }

        public void update(T entity) {
                getCurrentSession().update(entity);            
        }

        public void save(T entity) {
                getCurrentSession().save(entity);              
        }

        public void delete(T entity) {
                getCurrentSession().delete(entity);            
        }

        protected final Session getCurrentSession(){
                return sessionFactory.getCurrentSession();
        }
}

/* ------------------------------------------------------ */

package net.example.com.dao;

import net.example.com.entity.Country;

public interface CountryDao extends GenericDao<Country> {

    public Country findByName(String name);    
    public Country findByCode(String code);

}

/* ------------------------------------------------------ */

package net.example.com.dao;

import org.springframework.stereotype.Repository;

import net.example.com.entity.Country;

@Repository
public class CountryDaoImpl extends GenericHibernateDaoImpl<Country> implements CountryDao {

        @Override
        public Country findByName(String name) {
                return (Country) getCurrentSession()
                                .createQuery("FROM Country WHERE name = :name")
                                .setString("name", name).uniqueResult();
        }

        @Override
        public Country findByCode(String code) {
                return (Country) getCurrentSession()
                                .createQuery("FROM Country WHERE code = :code")
                                .setString("code", code).uniqueResult();
        }

}

/* ################################# DAO ################################ */

and Services:

/* ################################# SERVICE ################################ */

package net.example.com.service;

import java.util.List;

public interface GenericManager<T> { // GenericManager<T> is the same as GenericDao<T>

        public T findById(int id);     
        public List<T> findAll();      
        public void update(T entity);  
        public void save(T entity);    
        public void delete(T entity);
}

/* ------------------------------------------------------ */

package net.example.com.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.example.com.dao.GenericDao;

@Service
public abstract class GenericManagerImpl<T> implements GenericManager<T> {

        @Autowired
        protected GenericDao<T> dao;

        @Override
        public T findById(int id) {
                return dao.findById(id);
        }

        @Override
        public List<T> findAll() {
                return dao.findAll();
        }

        @Override
        public void update(T entity) {
                dao.update(entity);
        }

        @Override
        public void save(T entity) {
                dao.save(entity);
        }

        @Override
        public void delete(T entity) {
                dao.delete(entity);    
        }
}
/* ------------------------------------------------------ */

package net.example.com.dao;

import net.example.com.entity.Country;

public interface CountryManager extends GenericDao<Country> { // CountryManager is the same as CountryDao

    public Country findByName(String name);    
    public Country findByCode(String code);
}

/* ------------------------------------------------------ */

package net.example.com.service;

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.example.com.dao.CountryDao;
import net.example.com.entity.Country;

@Service
@Transactional
public class CountryManagerImpl extends GenericManagerImpl<Country> implements CountryManager {

        @Override
        public List<Country> findAll() {
                return dao.findAll();
        }

        public Country findById(int id) {
                return dao.findById(id);
        }

        @Override
        public Country findByName(String name) {
                return dao.findByName(name); // compiler (and Eclipse) do not see findByName !!!!!!!!!
        }

        @Override
        public Country findByCode(String code) {
                return dao.findByCode(code); // compiler (and Eclipse) do not see findByCode !!!!!!!!!
        }

        @Override
        public void save(Country country) {
                dao.save(country);
        }

        @Override
        public void delete(Country country) {
                dao.delete(country);
        }

        @Override
        public void update(Country country) {
                dao.update(country);
        }

}

/* ------------------------------------------------------ */

/* ################################# SERVICE ################################ */

Compiler (and Eclipse) do not see findByName and findByCode methods. I understand why. But how can I rewrite it?

解决方案

The problem is that your inject directly your GenericDao in your GenericManager but none of them is a concrete Spring bean and you will never be able to use your specific CountryDao.

You must not autowire GenericDao but only define it and provide setter :

// Add DAO as a genric parameter
public abstract class GenericManagerImpl<T, D extends GenericDao<T>> implements GenericManager<T> {
    private D dao;

    protected void setDao (D dao) {
        this.dao = dao;
    }

...

}

Then, you will have to inject a concrete spring bean in your concrete services. i.e. in CountryManagerImpl:

// Instantiate your concrete service with your concrete DAO
public class CountryManagerImpl extends GenericManagerImpl<Country, CountryDao> implements CountryManager {

    // Do not redeclare your dao here in order to keep the inherited one

    // Don't forget to inject
    @Inject("countryDao")
    @Override
    protected void setDao (CountryDao dao) {
        this.dao = dao;
    }

...

}

You will have then a full spring bean injected with your concrete CountryDao type and its specific methods.

You can take a look at what we did on RESThub project regarding generic services : https://github.com/resthub/resthub-spring-stack/blob/master/resthub-common/src/main/java/org/resthub/common/service/CrudServiceImpl.java and some concrete example : https://github.com/resthub/todo-backbone-example/blob/master/src/main/java/todo/TodoController.java (with a Controller instead of a Service but it is similar)

Hope it will help.

(and sorry if there is some typos, I cannot double check right now)

and, BTW, you should consider using Spring Data instead of using GenericDaos but you will still have the same needs regarding your Services.

这篇关于Spring MVC:通用的DAO和服务类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆