Java 如何用类参数表示dao

Java 如何用类参数表示dao,java,class,reflection,factory,Java,Class,Reflection,Factory,我想创建一个返回dao实例的工厂,具体取决于类clazz 团队成员、场景和设备是我的模型课程 我的刀是这样的: public class JDBCTeammemberDAO implements JdbcDAO<Teammember> public class DAOFactory { JdbcDAO createDAO(Class clazz) { if(clazz.equals(Teammember.class)) { retu

我想创建一个返回dao实例的工厂,具体取决于类clazz

团队成员、场景和设备是我的模型课程

我的刀是这样的:

public class JDBCTeammemberDAO implements JdbcDAO<Teammember>
public class DAOFactory {

    JdbcDAO createDAO(Class clazz) {
        if(clazz.equals(Teammember.class)) {
            return new JDBCTeammemberDAO();
        }
        if(clazz.equals(Scene.class)) {
            return new JDBCSceneDAO();
        }
        if(clazz.equals(Equipment.class)) {
            return new JDBCEquipmentDAO();
        }
        return null;

    }
}
public class DaoRegistry {
        private Map<Class, JdbcDAO> daoMap;

        public synchronized void register (Class type, JdbcDao dao) {
                if (!daoMap.containsKey(type))
                     daoMap.put (type, dao);
                else
                     logger.error ("Something is really wrong because you are creating another dao for this class.", e);

            }

        public JdbcDAO get(Class type) {return daoMap.get(type);
}
我在考虑开关和多态性,但我不知道怎么做

基本上我想找到“SomeClass实现JdbcDAO”的实现

我的第一个方法是:

String name = clazz.getName().substring(6); // model.Teammember
Class<?> forName;
try {
    forName = Class.forName("dao.jdbc.JDBC" + name + "DAO");
    return (JdbcDAO) forName.newInstance();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
String name=clazz.getName().substring(6);//模型。团队成员
类forName;
试一试{
forName=Class.forName(“dao.jdbc.jdbc”+name+“dao”);
返回(JdbcDAO)forName.newInstance();
}catch(classnotfounde异常){
e、 printStackTrace();
}捕获(实例化异常e){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}

但我觉得用String方法处理这个问题不太好。此外,如果我有不同的模型和Dao名称(比如:JDBCMemberDAO而不是JDBCTeammemberDAO),它也不起作用。

如果您不介意稍微重新设计一下,这个问题很容易解决,只需一点泛型和多态性:

public interface JdbcDAO<T> {
    T find(Long id) ;
    T create(T entity);
    T update(T entity);
    void delete(T entity);

    // Other common definitions
}

public class JdbcDAOImpl<T> {
    private Class<T> clazz;

    public JdbcDAOImpl() {
        super();
    }

    protected JdbcDAOImpl(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    // Common implementation here
}

public class EquipmentDAO extends JdbcDAOImpl<Equipment> {
    public EquipmentDAO() {
        super(Equipment.class);
    }

    // Subclass specific implementation here
}
公共接口JdbcDAO{
找不到(长id);
T创建(T实体);
T更新(T实体);
无效删除(T实体);
//其他共同定义
}
公共类JdbcDAOImpl{
私人课堂;
公共JdbcDAOImpl(){
超级();
}
受保护的JdbcDAOImpl(类clazz){
超级();
this.clazz=clazz;
}
//这里的通用实现
}
公共类设备DAO扩展了JdbcDAOImpl{
公共设备{
超级(设备级);
}
//这里是特定于子类的实现
}

冲洗并重复每个模型的特定impl,并直接实例化它们(无需使用工厂)

Sormula的工作原理如您所述。它提供了一种获取行/记录类的“DAO”的方法。参见
database.getTable(Inventory.class)输入。您不需要编写任何DAO。

我也遇到过类似的情况,决定使用DAO注册表来处理这个问题。使用提到的@Perception通用dao模式:

public interface JdbcDAO<T> {
    T find(Long id) ;
    T create(T entity);
    T update(T entity);
    void delete(T entity);
}

public class JdbcDAOImpl<T> {
    this.clazz = clazz;
    DaoRegistry.register (clazz, this);
}
公共接口JdbcDAO{
找不到(长id);
T创建(T实体);
T更新(T实体);
无效删除(T实体);
}
公共类JdbcDAOImpl{
this.clazz=clazz;
daogregistry.register(clazz,this);
}
那你就可以吃晚饭了

   public class JDBCTeammemberDAO extend JdbcDAOImpl<TeamMember> {
       public class JDBCTeammemberDAO () {
          super(TeamMember.class);
       }
   }
公共类JDBCTeammemberDAO扩展JdbcDAOImpl{
公共类JDBCTeammemberDAO(){
super(TeamMember.class);
}
}
DaoRegistry的外观如下所示:

public class JDBCTeammemberDAO implements JdbcDAO<Teammember>
public class DAOFactory {

    JdbcDAO createDAO(Class clazz) {
        if(clazz.equals(Teammember.class)) {
            return new JDBCTeammemberDAO();
        }
        if(clazz.equals(Scene.class)) {
            return new JDBCSceneDAO();
        }
        if(clazz.equals(Equipment.class)) {
            return new JDBCEquipmentDAO();
        }
        return null;

    }
}
public class DaoRegistry {
        private Map<Class, JdbcDAO> daoMap;

        public synchronized void register (Class type, JdbcDao dao) {
                if (!daoMap.containsKey(type))
                     daoMap.put (type, dao);
                else
                     logger.error ("Something is really wrong because you are creating another dao for this class.", e);

            }

        public JdbcDAO get(Class type) {return daoMap.get(type);
}
公共类注册表{
私人地图;
公共同步无效寄存器(类类型,JdbcDao){
如果(!daoMap.containsKey(类型))
daoMap.put(类型,dao);
其他的
logger.error(“由于您正在为此类创建另一个dao,所以出现了一些问题。”,e);
}
公共JdbcDAO get(类类型){return daoMap.get(类型);
}

这只是一个玩笑,你需要确保它是线程安全的。希望这会有帮助。

但是我如何获得正确的DAO?通过使用
JdbcDAOImpl equipmentDao=new JdbcDAOImpl()
?我想要为我的服务类创建一个工厂,它不应该关心它得到哪一个。(特别是如果我想模拟它)如果工厂是你设计的核心,那么上面的代码对你没有帮助。但是我也质疑你为什么还需要特定于模型的DAO。这不是我的核心。我需要一种方法来模拟/存根我的服务类。我们只在学校里通过工厂学习到了这一点——如果你有更好的想法,我决定你。