Android中有很多操作SQLite数据库的框架,现在最常见、最常用的是ORMLite和GreenDAO。ORMLite相比与GreenDAO来说是一个轻量级的框架,而且学习成本相对较低。所以这个帖子中先介绍ORMLite,下个帖子再介绍GreenDAO。

要使用ORMLite,首先需要导入ORMLite的依赖:在build.gradle中加入以下代码:

    compile 'com.j256.ormlite:ormlite-android:5.0'compile 'com.j256.ormlite:ormlite-core:5.0'

ORMLite需要我们自己实现一个类似原生操作SQLite数据库的DatabaseHelper,但必须继承自ORMLite为我们提供的OrmLiteSqliteOpenHelper。以下是一个功能比较齐全,性能相对也比较好的实例,这个实例不仅仅起到了创建数据库和更新数据库的操作,还对自身对象进行了单例、对DAO进行了统一的管理。代码如下:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;import com.example.itgungnir.testormlite.entity.ArticleBean;
import com.example.itgungnir.testormlite.entity.UserBean;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;/*** 数据库操作管理工具类* <p>* 我们需要自定义一个类继承自ORMlite给我们提供的OrmLiteSqliteOpenHelper,创建一个构造方法,重写两个方法onCreate()和onUpgrade()* 在onCreate()方法中使用TableUtils类中的createTable()方法初始化数据表* 在onUpgrade()方法中我们可以先删除所有表,然后调用onCreate()方法中的代码重新创建表* <p>* 我们需要对这个类进行单例,保证整个APP中只有一个SQLite Connection对象* <p>* 这个类通过一个Map集合来管理APP中所有的DAO,只有当第一次调用这个DAO类时才会创建这个对象(并存入Map集合中)* 其他时候都是直接根据实体类的路径从Map集合中取出DAO对象直接调用*/
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {// 数据库名称public static final String DATABASE_NAME = "mydb.db";// 本类的单例实例private static DatabaseHelper instance;// 存储APP中所有的DAO对象的Map集合private Map<String, Dao> daos = new HashMap<>();// 获取本类单例对象的方法public static synchronized DatabaseHelper getInstance(Context context) {if (instance == null) {synchronized (DatabaseHelper.class) {if (instance == null) {instance = new DatabaseHelper(context);}}}return instance;}// 私有的构造方法private DatabaseHelper(Context context) {super(context, DATABASE_NAME, null, 1);}// 根据传入的DAO的路径获取到这个DAO的单例对象(要么从daos这个Map中获取,要么新创建一个并存入daos)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 onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {try {TableUtils.createTable(connectionSource, UserBean.class);TableUtils.createTable(connectionSource, ArticleBean.class);} catch (SQLException e) {e.printStackTrace();}}@Override // 数据库版本更新时调用的方法public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {try {TableUtils.dropTable(connectionSource, UserBean.class, true);TableUtils.dropTable(connectionSource, ArticleBean.class, true);onCreate(database, connectionSource);} catch (SQLException e) {e.printStackTrace();}}// 释放资源@Overridepublic void close() {super.close();for (String key : daos.keySet()) {Dao dao = daos.get(key);dao = null;}}
}

在这个帖子中,我们通过这样一个例子来了解ORMLite:数据库中有两个表,一个是user表,其中存储用户的信息;另一个是article表,存储文章信息,一个用户可以关良多篇文章,一篇文章只能关联一个用户。

有了上面的需求,下面我们来写两个实体类:

UserBean类中的代码如下:

import com.j256.ormlite.dao.ForeignCollection;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;import java.util.Date;/*** UserBean实体类,存储数据库中user表中的数据* <p>* 注解:* DatabaseTable:通过其中的tableName属性指定数据库名称* DatabaseField:代表数据表中的一个字段* ForeignCollectionField:一对多关联,表示一个UserBean关联着多个ArticleBean(必须使用ForeignCollection集合)* <p>* 属性:* id:当前字段是不是id字段(一个实体类中只能设置一个id字段)* columnName:表示当前属性在表中代表哪个字段* generatedId:设置属性值在数据表中的数据是否自增* useGetSet:是否使用Getter/Setter方法来访问这个字段* canBeNull:字段是否可以为空,默认值是true* unique:是否唯一* defaultValue:设置这个字段的默认值*/
@DatabaseTable(tableName = "user") // 指定数据表的名称
public class UserBean {// 定义字段在数据库中的字段名public static final String COLUMNNAME_ID = "id";public static final String COLUMNNAME_NAME = "name";public static final String COLUMNNAME_SEX = "sex";public static final String COLUMNNAME_BIRTHDAY = "birthday";public static final String COLUMNNAME_ADDRESS = "address";@DatabaseField(generatedId = true, columnName = COLUMNNAME_ID, useGetSet = true)private int id;@DatabaseField(columnName = COLUMNNAME_NAME, useGetSet = true, canBeNull = false, unique = true)private String name;@DatabaseField(columnName = COLUMNNAME_SEX, useGetSet = true, defaultValue = "1")private char sex;@DatabaseField(columnName = COLUMNNAME_BIRTHDAY, useGetSet = true)private Date birthday;@DatabaseField(columnName = COLUMNNAME_ADDRESS, useGetSet = true)private String address;@ForeignCollectionField(eager = true)private ForeignCollection<ArticleBean> articles;public UserBean() {}public UserBean(String name, char sex, Date birthday, String address) {this.name = name;this.sex = sex;this.birthday = birthday;this.address = address;}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;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public ForeignCollection<ArticleBean> getArticles() {return articles;}public void setArticles(ForeignCollection<ArticleBean> articles) {this.articles = articles;}@Overridepublic String toString() {return "UserBean{" +"id=" + id +", name='" + name + '\'' +", sex=" + sex +", birthday=" + birthday +", address='" + address + '\'' +", articles=" + articles +'}';}
}

ArticleBean类中的代码如下:

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;/*** ArticleBean实体类,存储article数据表中的数据* 数据库中的article表和user表是关联的,因此我们需要在article表中配置外键* <p>* foreignColumnName:外键约束指向的类中的属性名* foreign:当前字段是否是外键* foreignAutoRefresh:如果这个属性设置为true,在关联查询的时候就不需要再调用refresh()方法了*/
@DatabaseTable(tableName = "article")
public class ArticleBean {// article表中各个字段的名称public static final String COLUMNNAME_ID = "id";public static final String COLUMNNAME_TITLE = "title";public static final String COLUMNNAME_CONTENT = "content";public static final String COLUMNNAME_USER = "user_id";@DatabaseField(generatedId = true, columnName = COLUMNNAME_ID, useGetSet = true)private int id;@DatabaseField(columnName = COLUMNNAME_TITLE, useGetSet = true, canBeNull = false, unique = true)private String title;@DatabaseField(columnName = COLUMNNAME_CONTENT, useGetSet = true)private String content;@DatabaseField(columnName = COLUMNNAME_USER, foreign = true, foreignAutoRefresh = true, foreignAutoCreate = true,foreignColumnName = UserBean.COLUMNNAME_ID)private UserBean user_id;public ArticleBean() {}public ArticleBean(String title, String content, UserBean user) {this.title = title;this.content = content;this.user_id = user;}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 String getContent() {return content;}public void setContent(String content) {this.content = content;}public UserBean getUser() {return user_id;}public void setUser(UserBean user) {this.user_id = user;}@Overridepublic String toString() {return "ArticleBean{" +"id=" + id +", title='" + title + '\'' +", content='" + content + '\'' +", user=" + user_id +'}';}
}

从两个实体类中的代码来看,ORMLite和JavaWeb框架中的Hibernate相似,都是使用注解的方式来标注数据库中的表、字段、关联关系的,这也是ORMLite的工作原理:ORMLite是基于反射机制工作的,然而这也成为了ORMLite的一个非常致命的缺点,性能不好。因此,如果是对想能要求不高的项目,我们可以考虑使用ORMLite,而如果项目对性能要求较高,我们可以考虑使用GreenDAO。

至于各个标签、各个属性的用途,将在本贴的最后贴出。

现在让我们再来看ORMLite中的另一个比较重要的东西——DAO。DAO是用来将操作某张表的方法(增、删、改、查)封装起来的工具类。下面来看代码:

UserDao类中的代码:

import android.content.Context;import com.example.itgungnir.testormlite.db.DatabaseHelper;
import com.example.itgungnir.testormlite.entity.UserBean;
import com.j256.ormlite.dao.Dao;import java.sql.SQLException;
import java.util.List;/*** 操作User数据表的Dao类,封装这操作User表的所有操作* 通过DatabaseHelper类中的方法获取ORMLite内置的DAO类进行数据库中数据的操作* <p>* 调用dao的create()方法向表中添加数据* 调用dao的delete()方法删除表中的数据* 调用dao的update()方法修改表中的数据* 调用dao的queryForAll()方法查询表中的所有数据*/
public class UserDao {private Context context;// ORMLite提供的DAO类对象,第一个泛型是要操作的数据表映射成的实体类;第二个泛型是这个实体类中ID的数据类型private Dao<UserBean, Integer> dao;public UserDao(Context context) {this.context = context;try {this.dao = DatabaseHelper.getInstance(context).getDao(UserBean.class);} catch (SQLException e) {e.printStackTrace();}}// 向user表中添加一条数据public void insert(UserBean data) {try {dao.create(data);} catch (SQLException e) {e.printStackTrace();}}// 删除user表中的一条数据public void delete(UserBean data) {try {dao.delete(data);} catch (SQLException e) {e.printStackTrace();}}// 修改user表中的一条数据public void update(UserBean data) {try {dao.update(data);} catch (SQLException e) {e.printStackTrace();}}// 查询user表中的所有数据public List<UserBean> selectAll() {List<UserBean> users = null;try {users = dao.queryForAll();} catch (SQLException e) {e.printStackTrace();}return users;}// 根据ID取出用户信息public UserBean queryById(int id) {UserBean user = null;try {user = dao.queryForId(id);} catch (SQLException e) {e.printStackTrace();}return user;}
}

ArticleDao类中的代码:

import android.content.Context;import com.example.itgungnir.testormlite.db.DatabaseHelper;
import com.example.itgungnir.testormlite.entity.ArticleBean;
import com.j256.ormlite.dao.Dao;import java.sql.SQLException;
import java.util.List;/*** 操作article表的DAO类*/
public class ArticleDao {private Context context;// ORMLite提供的DAO类对象,第一个泛型是要操作的数据表映射成的实体类;第二个泛型是这个实体类中ID的数据类型private Dao<ArticleBean, Integer> dao;public ArticleDao(Context context) {this.context = context;try {this.dao = DatabaseHelper.getInstance(context).getDao(ArticleBean.class);} catch (SQLException e) {e.printStackTrace();}}// 添加数据public void insert(ArticleBean data) {try {dao.create(data);} catch (SQLException e) {e.printStackTrace();}}// 删除数据public void delete(ArticleBean data) {try {dao.delete(data);} catch (SQLException e) {e.printStackTrace();}}// 修改数据public void update(ArticleBean data) {try {dao.update(data);} catch (SQLException e) {e.printStackTrace();}}// 通过ID查询一条数据public ArticleBean queryById(int id) {ArticleBean article = null;try {article = dao.queryForId(id);} catch (SQLException e) {e.printStackTrace();}return article;}// 通过条件查询文章集合(通过用户ID查找)public List<ArticleBean> queryByUserId(int user_id) {try {return dao.queryBuilder().where().eq(ArticleBean.COLUMNNAME_USER, user_id).query();} catch (SQLException e) {e.printStackTrace();}return null;}
}

最后就是测试代码了。我们直接在MainActivity中写代码,然后运行看结果。在MainActivity中,我们首先创建两张表并向表中添加数据,然后从数据表中分别取出数据,展示到TextView中。代码如下:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;import com.example.itgungnir.testormlite.dao.ArticleDao;
import com.example.itgungnir.testormlite.dao.UserDao;
import com.example.itgungnir.testormlite.entity.ArticleBean;
import com.example.itgungnir.testormlite.entity.UserBean;
import com.j256.ormlite.dao.ForeignCollection;import java.util.Date;
import java.util.Iterator;public class MainActivity extends AppCompatActivity {private TextView tv;private StringBuffer contentBuffer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv = (TextView) findViewById(R.id.tv);contentBuffer = new StringBuffer();initData();initView();}// 初始化数据private void initData() {// 添加用户数据UserBean userData = new UserBean("张三", '1', new Date(), "北京");new UserDao(MainActivity.this).insert(userData);// 添加文章数据ArticleBean articleData = new ArticleBean("标题", "内容内容内容内容内容内容", userData);new ArticleDao(MainActivity.this).insert(articleData);}// 初始化视图private void initView() {// 从数据库中根据ID取出文章信息ArticleBean articleBean = new ArticleDao(MainActivity.this).queryById(1);contentBuffer.append(articleBean.toString());// 根据取出的用户id查询用户信息UserBean userBean = new UserDao(MainActivity.this).queryById(articleBean.getUser().getId());contentBuffer.append("\n\n" + userBean.toString());// 从用户信息中取出关联的文章列表信息ForeignCollection<ArticleBean> articles = userBean.getArticles();Iterator<ArticleBean> iterator = articles.iterator();contentBuffer.append("\n\n");while (iterator.hasNext()) {ArticleBean article = iterator.next();contentBuffer.append(article.toString() + "\n");}// 设置TextView的文本tv.setText(contentBuffer.toString());}
}

运行结果如下图所示:

最后,贴出ORMLite中常用标签和各个属性代表的意义:

常见标签:

 DatabaseTable:通过其中的tableName属性指定数据库名称DatabaseField:代表数据表中的一个字段ForeignCollectionField:一对多关联,表示一个UserBean关联着多个ArticleBean(必须使用ForeignCollection集合)

常见属性:

id:当前字段是不是id字段(一个实体类中只能设置一个id字段)
columnName:表示当前属性在表中代表哪个字段
generatedId:设置属性值在数据表中的数据是否自增
useGetSet:是否使用Getter/Setter方法来访问这个字段
canBeNull:字段是否可以为空,默认值是true
unique:是否唯一
defaultValue:设置这个字段的默认值
foreignColumnName:外键约束指向的类中的属性名
foreign:当前字段是否是外键
foreignAutoRefresh:如果这个属性设置为true,在关联查询的时候就不需要再调用refresh()方法了

以上就是对ORMLite框架的基本使用了,希望对大家有帮助~~~~

【Android - 框架】之ORMLite的使用相关推荐

  1. 【Android】在Android上使用OrmLite数据库框架 之 基本用法

    转载自:http://blog.csdn.net/oo8_8oo/article/details/7302156 官网:http://ormlite.com/ 官方帮助,目录: http://orml ...

  2. 从零开始搭建Android框架系列

    原文链接:http://www.jianshu.com/nb/3767449 开篇介绍和工程目录结构[从零开始搭建android框架系列(1)] 不容错过,最全的安卓架构合集[从零开始搭建androi ...

  3. 【Android 系统开发】Android框架 与 源码结构

    一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...

  4. 浅入浅出 Android 安全:第四章 Android 框架层安全

    第四章 Android 框架层安全 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 如我们在第1.2节中所描述的那样,应用程 ...

  5. 一个C#开发者用Java搭建Android框架的心路历程

    前言 Java框架实在是太多了,因为是初学乍练,所以,只好以百度为标准选择框架了. Java的框架文章太难写了,因为他引用了太多框架,而没一个框架都有很繁琐的配置,把每个框架都写一遍,就等于写书了:所 ...

  6. Android框架之ButterKnife(黄油刀)

    Android框架之ButterKnife(黄油刀) Butterknife简介 ButterKnife是一个专注于Android系统的View注入框架,可以减少大量的findViewById以及se ...

  7. 360 android框架,360 董福源 - Android框架虚拟化实战.pdf

    Android框架虚拟化实战 董福源 360手机卫士 2017. 什么是虚拟化 原生apk 在封闭系统内 免安装运行 Android系统的一种沙箱技术 2017. 技术架构 Sandbox apps ...

  8. Android框架排行榜,上百项资源汇总不容错过

    1.Retrofit 一句话介绍:Retrofit是一款类型安全的网络框架,基于HTTP协议,服务于Android和java语言 上榜理由:Retrofit以21.8k的stars量雄踞github中 ...

  9. Android框架排行榜

    Android框架排行榜 1.Retrofit 一句话介绍:Retrofit是一款类型安全的网络框架,基于HTTP协议,服务于Android和java语言 上榜理由:Retrofit以21.8k的st ...

  10. 60个实用Android框架排行榜

    1.Retrofit 一句话介绍:Retrofit是一款类型安全的网络框架,基于HTTP协议,服务于Android和java语言 上榜理由:Retrofit以21.8k的stars量雄踞github中 ...

最新文章

  1. linux 为什么 c语言,为什么C程序里一定要写main函数
  2. java 时间加减_Java中时间加减的比较
  3. System.arraycopy
  4. equals变量在前面和后面的区别,equals已知(存在实际值)的变量在前的好处
  5. SAP Commerce Cloud Spartacus UI footer 区域的设计模型
  6. java sqlite 创建_关于Java:创建3个由sqlite数据库填充的微调器
  7. exadata磁盘组无法mount恢复---惜分飞 1
  8. 3.2 LSTM、GRU RNN概述
  9. nvme固态硬盘开机慢_win10 Samsung NVMe固态硬盘测速很慢的解决方法
  10. CGAL 计算几何库
  11. mysql索引左倾_MySQL索引学习
  12. 创建Docker镜像
  13. javascript常用工具类的封装
  14. H.265之三 -帧内预测(3)
  15. 使用 Telnet 手动接收邮件 (基于 macOS 系统)
  16. 2022款联想拯救者Y9000P和Y9000X的区别
  17. Python画出时钟
  18. iOS 创建代码块 并附上常用的代码块(Swift 代码)
  19. i html设置为不倾斜,css如何不让字体倾斜?
  20. [经济杂谈]经济危机的真相

热门文章

  1. Python + matplotlib.animation 模拟斜抛运动动画(含完整代码)
  2. 网商银行×OceanBase:首家云上银行的分布式数据库应用实践
  3. 计算机学院评估报告,学校评估报告(共10篇).docx
  4. 持续交付(CD)与持续集成(CI)
  5. 操作系统 - Windows
  6. 波士顿动力机器人会跑了!机器狗学会上下楼!(视频)
  7. ThinkSNS 2018年春节放假及值班通知!
  8. cumulative sum
  9. pmd java规则_静态代码扫描 (一)——PMD 自定义规则入门
  10. vscode java环境_VSCode中Java开发环境的配置方法