程序员

在Hibernate中,我们来浅谈一下泛型DAO

2016-08-16  本文已影响150人  浑身演技

背景:最近项目组同事希望大家一起写一个泛型DAO,然后大家可以一起使用。

作为项目组中拥有审核代码权限的人,我认为,至少在使用Hibernate这个对象关系映射框架中,是不必要的。而我之所以反对的原因是

也正是因为以上的观点,我想出了一种基于抽象工厂、适配器的混合设计模式 。

Talk is cheap,show me the code

// DAO的工厂接口
public interface DaoFactory<T,P> {
    // 取消注册
    public void unrgistered(T type);
    // 注册
    public void register(T type,P provider);
    // 更新
    public void update(T type, P provider);
     // 获取
    public P valueOf(T type);
}

// DAO的适配器
@FunctionalInterface
public interface DaoProvider<T> {
    public T of();
}

// DAO的类型
public interface DaoType {}

// DAO的抽象工厂
public abstract class AbstractDaoFactory<T extends DaoType,P extends DaoProvider<?>> implements DaoFactory<T,P>{
    protected static final Map<DaoType, DaoProvider<?>> map = new ConcurrentHashMap<>(4);
    @Override
    public void register(T type,P provider){
        Objects.requireNonNull(type);
        Objects.requireNonNull(provider);
        if (map.containsKey(type))
            throw new DaoRegisteredException();
        map.putIfAbsent(type, provider);
    }
    @Override
    public void unrgistered(T type){
        Objects.requireNonNull(type);

        if (!map.containsKey(type))
            throw new DaoUnregisteredException();
        map.remove(type);
    }
    @Override
    public void update(T type, P provider){
        Objects.requireNonNull(type);
        Objects.requireNonNull(provider);

        if (!map.containsKey(type))
            throw new DaoUpdatedException();

        map.replace(type, provider);
    }
    @SuppressWarnings("unchecked")
    @Override
    public P valueOf(T type){
        Objects.requireNonNull(type);

        if (!map.containsKey(type))
            throw new DaoUnregisteredException();
        return (P) map.get(type);
    }    
}

public class DaoRegisteredException extends RuntimeException {
    private static final long serialVersionUID = -3794217705148674984L;

    public DaoRegisteredException() {
        super("Dao has registered,using update method please...");
    }

    public DaoRegisteredException(String message, Throwable cause, boolean enableSuppression,
            boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public DaoRegisteredException(String message, Throwable cause) {
        super(message, cause);
    }

    public DaoRegisteredException(String message) {
        super(message);
    }

    public DaoRegisteredException(Throwable cause) {
        super(cause);
    }
    
}

public class DaoUnregisteredException extends RuntimeException {
    private static final long serialVersionUID = 5997668949853885283L;

    public DaoUnregisteredException() {
        super("Dao still unregistered,using register method please...");
    }

    public DaoUnregisteredException(String message, Throwable cause, boolean enableSuppression,
            boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public DaoUnregisteredException(String message, Throwable cause) {
        super(message, cause);
    }

    public DaoUnregisteredException(String message) {
        super(message);
    }

    public DaoUnregisteredException(Throwable cause) {
        super(cause);
    }
    
}

public class DaoUpdatedException extends RuntimeException {
    private static final long serialVersionUID = -1424730522134154582L;

    public DaoUpdatedException() {
        super("Dao still unregisted,using register method please...");
    }

    public DaoUpdatedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

    public DaoUpdatedException(String message, Throwable cause) {
        super(message, cause);
    }

    public DaoUpdatedException(String message) {
        super(message);
    }

    public DaoUpdatedException(Throwable cause) {
        super(cause);
    }
    
}

这里,我提供了DaoFactory的接口(注册,取消注册,更新Dao适配器与获取适配器等方法),并且同时提供了DAO的适配器、DAO的类型。

同时在AbstractDaoFactory中,我对其进行了简单的实现。到了这里,其实大家可以看出,我就是对于一个抽象模型的增删查改的DAO进行拆分。因为我现在设计的这些类要解决的就是上面的三个问题。

简单应用案例:

@SuppressWarnings("rawtypes")
public interface HotelOrderDetailDaoProvider extends DaoProvider<HotelOrderDetailQueryDao>{}

@FunctionalInterface
public interface HotelOrderDetailQueryDao<T> {
    public T queryHotelOrderDetail(int id);
}


public final class HotelOrderDetailDaoFactory extends AbstractDaoFactory<HotelOrderDetailType,HotelOrderDetailDaoProvider> implements DaoFactory<HotelOrderDetailType,HotelOrderDetailDaoProvider>{
    private static final Logger log=LoggerFactory.getLogger(HotelOrderDetailDaoFactory.class);
    private static final HotelOrderDetailDaoFactory factory=new HotelOrderDetailDaoFactory();
    private HotelOrderDetailDaoFactory(){
        log.info("HotelOrderDaoFactory start accepting registration...");
    }
    /**
     * @return
     */
    public static HotelOrderDetailDaoFactory getInstance() {
        return factory;
    }
}

Thanks for reading,have a good night :)

上一篇 下一篇

猜你喜欢

热点阅读