我试图使用MyBatis来生成一些对数据库的调用,但到目前为止我已经碰壁了。接口中的泛型类型和多态性
比方说,我有这样的实体和映射器:
public interface Entity {
<T extends Entity> Class<Insertable<T>> mapper();
}
public interface Insertable<T extends Entity> {
void insert(T entity);
}
public interface ClientMapper extends Insertable<Client> {
void insert(Client client);
}
public interface CampaignMapper extends Insertable<Campaign> {
void insert(Campaign campaign);
}
public class Client implements Entity {
private final Long id;
public Client(final Long id) {
this.id = id;
}
@Override
public <T extends Entity> Class<Insertable<T>> mapper() {
return ClientMapper.class; // Incompatible types error
}
我越来越即使ClientMapper
是Insertable<Client>
式的,可Client
一种类型的Entity
这个编译错误。
目标越来越为以下类型安全代码:
public class MapperOperation {
public static void insert(Entity entity) {
insert(entity, entity.mapper());
}
private static <V extends Entity, K extends Insertable<V>> void insert(V entity, Class<K> mapperClass) {
try (SqlSession session = PersistenceManager.get().openSession()) {
K mapper = session.getMapper(mapperClass);
mapper.insert(entity);
session.commit();
} catch (Exception e) {
log.error("Could not insert entity {}", entity, e);
}
}
}
这样一来,我就可以调用该方法insert
任何Entity
的一个实例,然后请他给我他的mapper
使我可以插入它。
这可能吗?难道我做错了什么?
我有一个“偏离主题”的问题:接口'ClientMapper'和'CampaignMapper'做了什么?我的意思是他们只是重新声明插入方法,具有相同的签名... –
这就是Mybatis的工作原理(据我所知)。每个接口都有一个与将要执行的查询关联的XML。然后使用会话获得该接口的实例(mapper),当您调用该方法时,Mybatis会发挥神奇功效。 – carcaret