以前一直使用Hibernate,习惯了关联实体的懒加载。最近使用Nutz,里面没有提供懒加载的支持,于是乎自己扩展了一下Dao代码使其支持懒加载。这样用户在获取数据时就无需关心从dao抓取关联对象的问题了,调用POPO的getter方法时即可自动加载关联实体。下面就具体方案整理如下:
1. 定义一个名为LinkFieldGetterIntercepter的方法拦截器: 用于调用POJO的getter时自动加载关联对象。
2. 自定义一个EntityHolder: reloadEntity时创建实体代理类,添加第1条中定义的拦截器。并使用实体代理类在mappings中缓存实体。
3. 自定义一个org.nutz.dao.entity.Borning: 便于将ResultSet转换成POJO时,创建的是POJO的代理类实例,而不是POJO原始类实体。
4. 自定义一个EntityMaker: make方法中解析实体时setBorning(...)为第3条中定义的Borning对象。
下面是本人使用JPA作为POJO的annotation,扩展后的相关代码,如果直接使用Nutz annotation实现应该更简单。方法都是一样的。
1. LinkFieldGetterIntercepter:
public class LinkFieldGetterIntercepter extends AbstractMethodInterceptor {
private static final Log log = Logs.getLog(LinkFieldGetterIntercepter.class);
private Dao dao;
private Link link;
public LinkFieldGetterIntercepter(Dao dao, Link link) {
this.dao = dao;
this.link = link;
}
public Object afterInvoke(Object obj, Object returnObj, Method method, Object... args) {
if (returnObj != null) {
return returnObj;
}
String name = link.getOwnField().getName();
dao.fetchLinks(obj, name);
returnObj = Mirrors.getValue(obj, name);
return returnObj;
}
}
2. EntityHolder
public class DemsyEntityHolder {
private Dao dao;// Dao 对象
private EntityMaker maker;
private Map<Class<?>, Entity<?>> mappings;// <AOP代理类,实体>
private Map<Class, Class> agentClassMap;// <实体类,AOP代理类>
public DemsyEntityHolder(DemsyNutDao dao) {
this.dao = dao;
this.maker = dao.getEntityMaker();
mappings = new HashMap<Class<?>, Entity<?>>();
agentClassMap = new HashMap<Class, Class>();
}
public <T> Entity<T> getEntity(Class<T> classOfT) {
// 转换成AOP代理类
if (!Mirrors.isAgent(classOfT)) {
classOfT = agentClassMap.get(classOfT);
}
if (classOfT == null) {
return null;
}
return (Entity<T>) mappings.get(classOfT);
}
@SuppressWarnings("unchecked")
public <T> Entity<T> reloadEntity(Class<T> classOfT, boolean autoCreateTable) {
JPAEntity<?> entity = (JPAEntity<?>) maker.make(null, null, classOfT);
// 缓存实体
mappings.put(agentClass(entity), entity);
return (Entity<T>) entity;
}
// 创建代理类
private Class agentClass(JPAEntity entity) {
Class cls = entity.getType();
if (Mirrors.isAgent(cls)) {
return cls;
}
ClassAgent classAgent = new AsmClassAgent();
List<Link> links = entity.getLinks(null);
if (links != null) {
for (Link link : links) {
String fieldName = link.getOwnField().getName();
fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
classAgent.addInterceptor(MethodMatcherFactory.matcher("get" + fieldName),
new LinkFieldGetterIntercepter(dao, link));
}
}
Class agentClass = classAgent.define(new DefaultClassDefiner(), cls);
entity.setAgentMirror(Mirror.me(agentClass));
this.agentClassMap.put(cls, agentClass);
return agentClass;
}
public int count() {
return mappings.size();
}
}
3 Borning:
class DemsyBorning implements Borning {
JPAEntity entity;
DemsyBorning(JPAEntity entity) {
this.entity = entity;
}
/**
* 创建实体代理实例
*
* @return
* @throws Exception
*/
public Object create() throws Exception {
//创建代理类的实例,而不是原始类的实例
return entity.getAgentMirror().born();
}
public Object born(ResultSet rs, FieldMatcher fm) throws Exception {
Object obj = create();
Iterator<EntityField> it = entity.fields().iterator();
while (it.hasNext()) {
EntityField ef = it.next();
if (null == fm || fm.match(ef.getField().getName()))
ef.fillValue(obj, rs);
}
return obj;
}
}
4 EntityMaker:
......
public Entity<?> make(DatabaseMeta db, Connection conn, Class<?> type) {
......
// Borning
entity.setBorning(new DemsyBorning(entity));
......
分享到:
相关推荐
活 -- 各个部分可以独立使用,比如在 Spring 里采用 Nutz.Dao ,又比如在 Nutz.Ioc 里使用 Hibernate 等 整 -- 它所有功能均不依赖第三方 jar 文件。 这就意味着:如果一个 Web 应用,你在 WEB-INF/lib 下只 需要...
数据库访问层 -- Nutz.Dao 反转注入支持 -- Nutz.Ioc Mvc 框架 -- Nutz.Mvc Json 解析器 -- Nutz.Json 更多的简化Java语法的函数和类 -- Nutz.Lang 以及 Nutz.Castors 不依赖任何第三方 Jar 包,从而便于程序员建立...
如果你觉得 Hibernate 控制比较繁琐,iBatis 编写SQL又比较麻烦,Nutz.Dao 专为你设计。 如果你觉得在多个服务器部署或者修改 Spring 配置文件很麻烦,Nutz.Ioc 专为你设计 如果你觉得直接写 XML 配置文件很麻烦,...
Spring 里采用 Nutz.Dao ,又比如在 Nutz.Ioc 里使用 Hibernate 等整 -- 它所有功能均不依赖第三方 jar 文件。这就意味着:如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置一个 nutz.jar 就够了当然你要使用其它...
nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册 nutz 使用手册
活 -- 各个部分可以独立使用,比如在 Spring 里采用 Nutz.Dao ,又比如在 Nutz.Ioc 里使用 Hibernate 等 整 -- 它所有功能均不依赖第三方 jar 文件。这就意味着:如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置...
NULL 博文链接:https://gevin.iteye.com/blog/1147922
nutzDao增删改查Demo
用于nutz邮箱验证jar包
nutz生成javabean工具.zip
nutz框架代码生成器,配置数据源后点击生成类,勾选数据表自动生成Action及实体类
nutz框架使用手册,从零到有深入学习nutz平台开发
可以快速定位路径 页面 本jar包是nutz实用插件 希望大家多多下载
nutz框架jar包
nutz框架开发手册,框架很方便使用的,和大家分享
在做nutz redis集成的实时,由于依赖包的问题被坑了一把,为了后人不要走同样的路,把所有依赖包放在上面了。
dao层使用nutz,view层使用beetl,数据源使用阿里的druid
让nutz支持freemarker。 具体使用和在struts2中使用是一样的
用开源框架nutz搭建的MVC框架,适合小型系统的开发,快捷方便!