几个ORM框架的比较

先介绍一下ORM的概念,以前也一直听说,不过没详细了解啥意思。其全称叫做对象关系映射(Object Relation Mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的.  两者之间是不匹配的。而ORM作为项目中间件形式实现数据在不同场景下数据关系映射。对象关系映射是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM就是这样而来的。

几个Android下的ORM框架:ORMLite、greendao、ormndroid、androrm、ActiveAndroid
下面对ORMLite和GreenDao做个简单的比较:

ormlite

基于注解和反射的的方式,导致ormlite性能有着一定的损失(注解其实也是利用了反射的原理)
优点:文档较全面,社区活跃,有好的维护,使用简单,易上手。
缺点:基于反射,效率较低

GreenDao
官网中明确指明了其首要设计目标:
  • Maximum performance (probably the fastest ORM for Android):性能最大化
  • Easy to use APIs:便于使用
  • Highly optimized for Android:对于Android高度优化
  • Minimal memory consumption:最小化内存开销
  • Small library size, focus on the essentials:较小的文件体积,只集中在必要的部分上
优点:
效率很高,插入和更新的速度是sqlite的2倍,加载实体的速度是ormlite的4.5倍
文件较小(<100K),占用更少的内存 ,但是需要create Dao
操作实体灵活:支持get,update,delete等操作

缺点:
学习成本较高。其中使用了一个java工程根据一些属性和规则去generate一些基础代码,类似于javaBean,但会有一些规则,另外还有QueryBuilder、Dao等API,所以首先要明白整个过程,才能方便使用。
没有ORMLite那样封装的完整,不过greenDao的官网上也提到了这一点,正是基于generator而不是反射,才使得其效率高的多。

另外GreenDao支持Protocol buffers协议数据的直接存储 ,如果通过protobuf协议和服务器交互,不需要任何的映射。
Protocol Buffers协议:以一种高效可扩展的对结构化数据进行编码的方式。google内部的RPC协议和文件格式大部分都是使用它。
RPC:远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。

Activity


public class MainActivity extends ListActivity {
    private TextView tv_info;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] array = { "添加一个用户", "获取一个用户的信息", "添加一篇文章", "获取一篇文章的信息", //
                "根据用户id获取此用户的全部文章", "方式二", };
        for (int i = 0; i < array.length; i++) {
            array[i] = i + "、" + array[i];
        }
        tv_info = new TextView(this);// 将内容显示在TextView中
        tv_info.setTextColor(Color.BLUE);
        tv_info.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
        tv_info.setPadding(20, 10, 20, 10);
        getListView().addFooterView(tv_info);
        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>(Arrays.asList(array))));
    }
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        int _id = new Random().nextInt(5);
        User user = null;
        Article article = null;
        switch (position) {
        case 0:
            user = new User();
            user.setName("包青天 " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
            new UserDao(this).add(user);
            break;
        case 1:
            user = new UserDao(this).get(_id);
            if (user == null) tv_info.setText("不存在id=" + _id + "的用户");
            else tv_info.setText(user.toString());
            break;
        case 2:
            article = new Article();
            article.setTitle("ORMLite的使用  " + new SimpleDateFormat("HH_mm_ss").format(new Date()));
            article.setUser(new UserDao(this).get(_id));
            new ArticleDao(this).add(article);
            break;
        case 3:
            article = new ArticleDao(this).get(_id);
            if (article == null) tv_info.setText("不存在id=" + _id + "的文章");
            else tv_info.setText(article.toString());
            break;
        case 4:
            tv_info.setText("【用户id为 " + _id + " 的全部文章】");
            List<Article> articles = new ArticleDao(this).listByUserId(_id);
            if (articles != null) {
                for (Article article2 : articles) {
                    tv_info.append("\n" + article2.toString());
                }
            }
            break;
        case 5:
            tv_info.setText("【用户id为 " + _id + " 的全部文章】");
            user = new UserDao(this).get(_id);
            if (user != null) {
                Collection<Article> articles3 = user.getArticles();
                if (articles3 != null) {
                    for (Article article3 : articles3) {
                        tv_info.append("\n" + article3.toString());
                    }
                }
            }
            break;
        }
    }
    public void addStudent() {
        try {
            Dao dao = MyDatabaseHelper.getHelper(this).getDao(Student.class);
            BaseDaoEnabled<Student, Integer> student = new Student("学生");
            student.setDao(dao);
            student.create();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

DAO

/**对每个Bean创建一个Dao来处理当前Bean的数据库操作*/
public class UserDao {
    private Dao<User, Integer> userDaoOpe;
    private MyDatabaseHelper helper;
    public UserDao(Context context) {
        try {
            helper = MyDatabaseHelper.getHelper(context);
            userDaoOpe = helper.getDao(User.class);//真正去和数据库打交道的对象,是通过getDao进行获取的
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 增加一个用户
     */
    public void add(User user) {
        try {
            userDaoOpe.create(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取一个用户,注意要判断是否获取到了指定id的用户
     */
    public User get(int id) {
        try {
            return userDaoOpe.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

public class ArticleDao {
    private Dao<Article, Integer> articleDaoOpe;
    private MyDatabaseHelper helper;
    @SuppressWarnings("unchecked")
    public ArticleDao(Context context) {
        try {
            helper = MyDatabaseHelper.getHelper(context);
            articleDaoOpe = helper.getDao(Article.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 添加一个Article
     */
    public void add(Article article) {
        try {
            articleDaoOpe.create(article);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 通过Id得到一个Article
     */
    @SuppressWarnings("unchecked")
    public Article getArticleWithUser(int id) {
        Article article = null;
        try {
            article = articleDaoOpe.queryForId(id);
            if (article != null) helper.getDao(User.class).refresh(article.getUser());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return article;
    }
    /**
     * 通过Id得到一篇文章
     */
    public Article get(int id) {
        Article article = null;
        try {
            article = articleDaoOpe.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return article;
    }
    /**
     * 通过UserId获取所有的文章
     */
    public List<Article> listByUserId(int userId) {
        try {
            return articleDaoOpe.queryBuilder().where().eq("user_id", userId).query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Bean

@DatabaseTable(tableName = "tb_user")
public class User {
    @DatabaseField(generatedId = true)
    private int id;//主键,id = true被注解对象就是主键;自增长的id,可以设置为generatedId = true来实现,当然还有很多其他的注解配置
    @DatabaseField
    private String name;
    @ForeignCollectionField
    private Collection<Article> articles;//一个作者有多个文章
    //******************************************************************************************
    public Collection<Article> getArticles() {
        return articles;
    }
    public void setArticles(Collection<Article> articles) {
        this.articles = articles;
    }
    public User() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "id=" + id + ", name=" + name;
    }
}

@DatabaseTable(tableName = "tb_article")
public class Article {//文章
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField
    private String title;//文章的标题
    @DatabaseField(canBeNull = true, foreign = true, columnName = "user_id", foreignAutoRefresh = true)
    private User user;//作者。canBeNull= true 表示能为null;foreign=true表示是一个外键;columnName 列名
    //******************************************************************************************
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "id=" + id + ", title=" + title + "\n作者为 " + user;
    }
}

@DatabaseTable(tableName = "tb_student")
public class Student extends BaseDaoEnabled<Student, Integer> {
    @DatabaseField(generatedId = true)
    public int id;
    @DatabaseField
    public String name;
    public Student(String name) {
        this.name = name;
    }
}

helper

public class MyDatabaseHelper extends OrmLiteSqliteOpenHelper {
    public static final String TABLE_NAME = "sqlite-test.db";
    private Map<String, Dao> daos = new HashMap<String, Dao>();
    //******************************************************************************************
    private static MyDatabaseHelper instance;
    //整个SqliteOpenHelper使用单例只对外公布出一个对象,保证只存在一个SQLite Connection
    private MyDatabaseHelper(Context context) {
        super(context, TABLE_NAME, null, 4);
    }
    /**
     * 单例获取该Helper
     */
    public static synchronized MyDatabaseHelper getHelper(Context context) {
        context = context.getApplicationContext();
        if (instance == null) {
            synchronized (MyDatabaseHelper.class) {
                if (instance == null) instance = new MyDatabaseHelper(context);
            }
        }
        return instance;
    }
    //******************************************************************************************
    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try {
            TableUtils.createTable(connectionSource, User.class);
            TableUtils.createTable(connectionSource, Article.class);
            TableUtils.createTable(connectionSource, Student.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
            TableUtils.dropTable(connectionSource, User.class, true);
            TableUtils.dropTable(connectionSource, Article.class, true);
            TableUtils.dropTable(connectionSource, Student.class, true);
            onCreate(database, connectionSource);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**getDao为一个泛型方法,会根据传入Class对象进行创建Dao,并且使用一个Map来保持所有的Dao对象,只有第一次调用时才会去调用底层的getDao()。*/
    @Override
    public synchronized Dao getDao(Class clazz) throws SQLException {
        Dao dao = null;
        String className = clazz.getSimpleName();
        if (daos.containsKey(className)) dao = daos.get(className);
        if (dao == null) {
            dao = super.getDao(clazz);
            daos.put(className, dao);
        }
        return dao;
    }
    /**
     * 释放资源
     */
    @Override
    public void close() {
        super.close();
        for (String key : daos.keySet()) {
            Dao dao = daos.get(key);
            dao = null;
        }
    }
}

附件列表

数据库 ORM框架 ORMLite的更多相关文章

  1. 数据库开源框架ormlite

    今天听说了ORM框架ORMLITE,特地去了解了一下. 该框架可以使用注解方式来生成数据库表,还封装了常用的数据库操作. 类似J2EE的HIBERNATE框架对数据库的处理. 省去了书写建表语句的麻烦 ...

  2. LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...

  3. 数据库ORM框架GreenDao

    常用的数据库: 1). Sql Server2). Access3). Oracle4). Sysbase5). MySql6). Informix7). FoxPro8). PostgreSQL9) ...

  4. Android 数据库ORM框架GreenDao学习心得及使用总结<一>

    转: http://www.it165.net/pro/html/201401/9026.html 最近在对开发项目的性能进行优化.由于项目里涉及了大量的缓存处理和数据库运用,需要对数据库进行频繁的读 ...

  5. 【转载】Android开源:数据库ORM框架GreenDao学习心得及使用总结

    转载链接:http://www.it165.net/pro/html/201401/9026.html 最近在对开发项目的性能进行优化.由于项目里涉及了大量的缓存处理和数据库运用,需要对数据库进行频繁 ...

  6. android ORM框架ORMLite封装

    源码:http://download.csdn.net/detail/a924571572/9415506 一.框架效率对比 由于目前公司里面android端数据的数据量基本在千条以内,所以选择了更为 ...

  7. android数据库持久化框架, ormlite框架,

    前言 Android中内置了SQLite,但是对于数据库操作这块,非常的麻烦.其实可以试用第3方的数据库持久化框架对之进行结构上调整, 摆脱了访问数据库操作的细节,不用再去写复杂的SQL语句.虽然这样 ...

  8. Django框架之数据库ORM框架

    首先,我来介绍一下什么是ORM框架: O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思.在ORM框架中,它帮 ...

  9. Python元类实战,通过元类实现数据库ORM框架

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第19篇文章,我们一起来用元类实现一个简易的ORM数据库框架. 本文主要是受到了廖雪峰老师Python3入门教程的启 ...

随机推荐

  1. Python自动化运维之31、Tornado框架

    Tornado 官网:http://www.tornadoweb.org/en/stable/ Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本. ...

  2. Python - 多元组(tuple)

    声明一个多元组 (4, 5, 6) 这是列表 [4, 5, 6] 与列表不一样在于多元组使用() 来组织元素而list使用方括号[] 而且多元组不能更改,用于当你的数组不想像list一样会被更改时就使 ...

  3. centos 下vmware 下添加硬盘到root

    ### #vmware 里找到硬盘拖大点...,如果不想从启动么,添加个新 #的也行.不过那个是另外的方法了 ###   #### ##找下硬盘添加在哪里 #### fdisk -l    //创建分 ...

  4. websphere安装和mvn dependency:copy-dependencies

    http://www.blogjava.net/paulwong/archive/2009/09/19/295657.html http://ljhzzyx.blog.163.com/blog/sta ...

  5. 两个div之间有空隙

    加句*{ margin:0; padding:0;} 最近在做网页时发现,在IE7下(FF没试过),div与div之间有时会出20个像素左右的空隙,除非把margin设成负值,否则空隙无法去除.我在 ...

  6. 根据body的内容 查找h2标签的@class="subtitle"的值

    <pre name="code" class="html"><body class="api jquery listing" ...

  7. pygame安装

    进入这个网站 http://www.pygame.org/wiki/Compilation 可以选择不同系统的安装方法 其中ubuntu的安装命令是 #这是python .X #install dep ...

  8. 【转】Android的onCreateOptionsMenu()创建菜单Menu详解

    原文网址:http://www.linuxidc.com/Linux/2012-02/55500.htm Android一共有三种形式的菜单:            1.选项菜单(optinosMen ...

  9. iOS: 关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系

    刚接触iOS开发的人难免会对苹果的各种证书.配置文件等不甚了解,可能你按照网上的教程一步一步的成功申请了真机调试,但是还是对其中的缘由一知半解.这篇文章就对Certificate.Provisioni ...

  10. VSTS负载测试——如何:使用 SQL 创建结果存储区

    原文地址:http://www.cnblogs.com/chenxizhang/archive/2009/06/01/1493939.html 原文参见:http://msdn.microsoft.c ...