几个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. STM32学习笔记——定时器中断(向原子哥学习)

    定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...

  2. hdu不要62

    Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来, ...

  3. Solr4.8.0源码分析(26)之Recovery失败造成的宕机原因分析

    最近在公司做SolrCloud的容灾测试,刚好碰到了一个比较蛋疼的问题,跟SolrCloud的Recovery和leader选举有关,正好拿出来分析下. 现象是这样的:比如我有一台3个shard的So ...

  4. Oracle中数字格式的文本化处理

    Select TO_CHAR(123.0233,'FM999,999,90.09') FROM DUAL 1.小数点后面的0指示至少保留1位小数,9表示最多保留两位小数 2.小数点前面的0指示至少保留 ...

  5. IIC总线协议

    前言:年前给老师做个红外抄表系统,,现在对当中用到的一些模块总结一下. 1.只有在总线空闲时才允许启动数据传送. 2.在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变.时钟线 ...

  6. 电容式触摸控制器PCB布局

    在目前市场上可提供的PCB(印刷电路板)基材中,FR4是最常用的一种.FR4是一种玻璃纤维增强型环氧树脂层压板,PCB可以是单层或多层. 在触摸模块的尺寸受限的情况下,使用单层PCB不是总能行得通的, ...

  7. 7.DropDownList的绑定

    ListView中是无法像TextBox等控件那样将DropDownList的选中值绑定到数据字段的,必须编程处理.如例子:人员的性别(男,女,保密),三个值固定写在DropDownList中. 在显 ...

  8. sublime每次打开时都提示升级,怎么取消这个弹出框?

    答案其实很简单,设置如下: 进入Preferences -> Settings-User ,添加 "update_check": false 重启Sublime. 发现了什么 ...

  9. iOS应用架构浅谈

    (整理至http://www.cocoachina.com/ios/20150414/11557.html) 缘由 从事iOS工作一年多了,主要从事QQ钱包SDK开发和财付通app维护,随着对业务的慢 ...

  10. Container With Most Water——LeetCode

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...