码迷,mamicode.com
首页 > 其他好文 > 详细

GreenDao源码学习

时间:2015-02-27 15:17:42      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

网上GreenDao相关的资料不是特别多,除了官方文档几乎没有特别好的资料。自己整理了一份,以备不时之需。

从源码上来分,GreenDao大体可以分成两个项目,DaoCore和DaoGenerator。


DaoGenerator部分:


FreeMarker

DaoGenerator使用FreeMarker根据指定的schema生成代码。

为了能够更好的介绍DaoGenerator的代码,有必要先简单介绍一下FreeMarker的基本功能,

一个基本的FreeMarker工程一般有这三个步骤组成。

1.声明一个configration,用来处理生成代码的逻辑

Configuration   config = new Configuration();

config.setClassForTemplateLoading(this.getClass(), "/");

config.setObjectWrapper(new DefaultObjectWrapper());


指定模版文件地址的方式有三种,

public void setClassForTemplateLoading(Class clazz, String pathPrefix);

public void setDirectoryForTemplateLoading(File dir) throws IOException;

public void setServletContextForTemplateLoading(Object servletContext, String path);


分别基于类路径、文件系统以及Servlet Context



2.生成ftl文件,用来作为生成代码的模版

Template temp = config.getTemplate("test.ftl”);


<html>

<head>

<title>Welcome!</title> </head>

<body>

<h1>Welcome ${user}!</h1>

<p>Our latest product:

<a href="${latestProduct.url}">${latestProduct.name}</a>!

</body>

</html>

这是一个简单的ftl模版的样子,其中${X}表示要用替换对象X进行替换。


3.通过config读取指定的ftl,生成template,进而结合模版,替换对象,输出流,生成最终的文件

Map root = this.getRoot();

Writer out = new OutputStreamWriter(System.out); 

temp.process(root, out);

out.flush();

这里的替换对象可以是Map的,也可以是一个普通的bean。


DaoGenerator:

下面切入正题开始看DaoGenerator的代码吧


包路径de.greenrobot.daogenerator 下面有如下几个类:


ContentProvider,

DaoGenerator,

DaoUtil,

Entity,

Index,

Property,

PropertyOrderList,

PropertyType,

Query,

QueryParam,

Schema,

ToMany,

ToOne,

使用顺序:

Schema作为一次完整的活动,它指定了生成代码的包名,其内部一般会有多个Entity,一个Entity对应数据库一张表,Entity下的Property,每个Property对应数据库中一个列。DaoGenerator作为一个入口,通过他的generateAll()方法来触发代码生成。


一般使用的顺序是这样的,先new一个schema,指定好生成代码包路径,然后通过Schema.addEntity(“表名”)得到一个Entity,然后再通过Entity.addXXProperty(“列名”)将指定的property添加到Entity(XX表示列的类型,比如int,String,等等)。

关系指定好之后通过DaoGenerator.generateAll(schema,srcOutputPath),触发根据schema中的关系和参数在数据库中建表,并在指定位置生成相应的实体bean和DAOs。


顺着使用时候的思路,我们来看一下源码里有什么值得我们借鉴的地方吧:


1.在Property的构造部分,由于property参数较多,这里他采用了Builder模式[Gamma95,p97],不直接生成想要的对象,而是让使用者利用必要的参数调用构造器(或者工厂模式),得到一个builder对象,然后使用者在builder对象上调用类似setter的方法,来设置每个可选的相关参数。 最后使用者调用build方法生成不可变的对象。这个builder是他构建的类的静态成员类,下面是他的实现:

public class Property {


    public static class PropertyBuilder {

        private final Property property;


        public PropertyBuilder(Schema schema, Entity entity, PropertyType propertyType, String propertyName) {

            property = new Property(schema, entity, propertyType, propertyName);

        }


        public PropertyBuilder columnName(String columnName) {

            property.columnName = columnName;

            return this;

        }


        public PropertyBuilder columnType(String columnType) {

            property.columnType = columnType;

            return this;

        }

.

.

.

.

.

public Property getProperty() { return property; }

}

.

.

}


使用起来是这个样子的:

public PropertyBuilder addProperty(PropertyType propertyType, String propertyName) {

        if (!propertyNames.add(propertyName)) {

            throw new RuntimeException("Property already defined: " + propertyName);

        }

        PropertyBuilder builder = new Property.PropertyBuilder(schema, this, propertyType, propertyName);

        properties.add(builder.getProperty());

        return builder;

    }


public PropertyBuilder addIdProperty() {

        PropertyBuilder builder = addLongProperty("id");

        builder.columnName("_id").primaryKey();

        return builder;

    }


注意这里类似setter的方法(columnName,columnType,等等)返回的都是builder本身,这样就可以把调用链起来。


GreenDao源码学习

标签:

原文地址:http://blog.csdn.net/yuyuanhuang/article/details/42032977

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!