几个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读取Matlab的Mat文件内容

    手头有别人写的Matlab程序,其中用到了Mat文件.现在不想安装Matlab,却又想读取Mat文件内容,该怎么办呢? 感谢scipy!!! import scipy.io data = scipy. ...

  2. UFLDL实验报告2:Sparse Autoencoder

    Sparse Autoencoder稀疏自编码器实验报告 1.Sparse Autoencoder稀疏自编码器实验描述 自编码神经网络是一种无监督学习算法,它使用了反向传播算法,并让目标值等于输入值, ...

  3. hdu3652B-number

    Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal for ...

  4. 【Java】Java XML 技术专题

    XML 基础教程 XML 和 Java 技术 Java XML文档模型 JAXP(Java API for XML Parsing) StAX(Streaming API for XML) XJ(XM ...

  5. Flux工作流

    Flux工作流 模型层(M)和控制层(C) Flux 只是这个模式的一个例子. 很多代码和一堆重复的模板 在其他JavaScript环境中实现重用. 强大又容易配置的模块化打包工具Webpack来简化 ...

  6. HDOJ 2015 偶数求和

    Problem Description 有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值 ...

  7. [操作系统] OS X Yosemite U盘制作

    话不多说,DiskMakerX,大小6.3M,下载地址:http://www.liondiskmaker.com/,然后准备好U盘和从官网下的Yosemite系统就可以开始了. DiskMaker X ...

  8. How many ways?? - hdu2157(矩阵快速幂-模板)

    分析:求Map^k,刚开始没有用快速幂,TLE了   代码如下: =================================================================== ...

  9. segment

    1.segmentedControlStyle 设置segment的显示样式. typedef NS_ENUM(NSInteger, UISegmentedControlStyle) { UISegm ...

  10. 个人整理--Java编码规范

    编码规范对于开发人员来说是非常重要的,有以下几个原因: 1.一个软件的生命周期中,80%的花费在于维护 2.几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护 3.编码规范可以改善软件 ...