Android ORM数据库之OrmLite使用框架及源码分析

article/2025/10/29 11:39:56

一、简介

 OrmLite是一个数据库框架,这个可以让我们快速实现数据库操作,避免频繁手写sql,提高我们的开发效率,减少出错的机率。
 首先可以去它的官网看看www.ormlite.com,它的英文全称是Object Relational Mapping,意思是对象关系映射;如果接触过Java EE开发的,一定知道Java Web开发就有一个类似的数据库映射框架——Hibernate。简单来说,就是我们定义一个实体类,利用这个框架,它可以帮我们吧这个实体映射到我们的数据库中,在Android中是SQLite,数据中的字段就是我们定义实体的成员变量。
优点
1)轻量级
2)使用简单,易上手
3)封装完善
4)文档全面
缺点
1)基于反射,效率较低
2)缺少中文翻译文档

二、运用

1. 集成
 首先到Ormlite官网下载Android的架包:http://ormlite.com/releases/。
这里写图片描述
 可以看到,目前最新版本为4.49,对于Android的架包为: ormlite-android-4.48.jar 和 ormlite-core-4.48.jar。把两个jar拷贝到libs下,一般Gradle里面都会包含编译libs:

compile fileTree(dir: 'libs', include: ['*.jar'])

这里写图片描述
 编译后就可以看到以上架包结构。

2.配置Bean类

 数据库肯定离不开Bean类,先来看看我建的一个User类:

@DatabaseTable(tableName = "user")
public class User {@DatabaseField(generatedId = true)private int id;@DatabaseField(columnName = "name")private String name;@DatabaseField(canBeNull = false, columnName = "desc")private String desc;/*关键啊,一定要加, 为每个class添加一个无参的构造器,并且构造器在包内是可见的*/public User() {}public User(String name, String desc) {this.name = name;this.desc = desc;}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 String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}}

 首先在User类上添加@DatabaseTable(tableName = “user”),标明这是数据库中的一张表,标明为user;然后分别在属性上添加@DatabaseField(columnName = “name”) ,columnName的值为该字段在数据中的列名@DatabaseField(generatedId = true) ,generatedId 表示id为主键且自动生成,canBeNull表示该属性的内容不能为空,下面来介绍更多常用的属性设置:

成员名数据类型描述
generatedIdBoolean字段是否自动增加。默认为false。类中的一个成员变量设置了这个值,它告诉数据库每添加一条新记录都自动增加id。当一个有generatedid的对象被创建时使用Dao.create()方法,数据库将为记录生成一个id,它会被返回并且被create方法设置进对象。
columnNameString数据库的列名。如果你没有设置这个成员名,会用标准的形式代替它。
canBeNullBoolean字段是否能被分配null值。默认是true。如果你设置成false,那么你每次在数据库中插入数据是都必须为这个字段提供值。
dataType字段的数据类型。通常情况下,数据类型是从java类的成员变量获取的,并不需要进行特殊指出。它相当于是SQL的数据类型。
defaultValueString当我们在表中创建新的记录时的一个字段的默认值。默认情况下是没有这个值的。
widthInteger字段的宽度,主要用于字符串字段。默认是0,意味着采用默认的数据类型和具体的数据库的默认情况。
idBoolean这个字段是否是id,默认是false。在一个class中只有一个成变量可以有这个值。
columnNameString数据库的列名。如果你没有设置这个成员名,会用标准的形式代替它。

3.封装Dao类
 在普通Sqlite使用过程中,我们都会自己写个Helper类来继承SQLiteOpenHelper,然后里面封装一些方法来操作数据库,OrmLite也一样,但我们需要继承的是OrmLiteSqliteOpenHelper:

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {private static final String TABLE_NAME = "demo.db";private static Context mApplicationContext;private static DatabaseHelper instance;private Map<String, Dao> daoMaps = new HashMap<>();private DatabaseHelper(Context context) {super(context, TABLE_NAME, null, 2);}@Overridepublic void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {try {TableUtils.createTable(connectionSource, User.class);TableUtils.createTable(connectionSource, Article.class);} catch (SQLException e) {e.printStackTrace();}}@Overridepublic void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {try {TableUtils.dropTable(connectionSource, User.class, true);TableUtils.dropTable(connectionSource, Article.class, true);onCreate(database, connectionSource);} catch (SQLException e) {e.printStackTrace();}}public static void initOrmLite(Context context) {mApplicationContext = context;getInstance();}/*** 单例获取该Helper*/public static DatabaseHelper getInstance() {if (instance == null) {synInit(mApplicationContext);}return instance;}private synchronized static void synInit(Context context) {if (instance == null) {instance = new DatabaseHelper(context);}}/*** 获得Dao** @return* @throws SQLException*/public synchronized Dao getDao(Class clazz) throws SQLException {Dao dao;String className = clazz.getSimpleName();if (daoMaps.containsKey(className)) {dao = daoMaps.get(className);} else {dao = super.getDao(clazz);daoMaps.put(className, dao);}return dao;}/*** 释放资源*/@Overridepublic void close() {super.close();for (String key : daoMaps.keySet()) {Dao dao = daoMaps.get(key);dao = null;}}}

 这里需要实现两个方法:
创建表,我们直接使用ormlite提供的TableUtils.createTable(connectionSource, User.class);进行创建。

onCreate(SQLiteDatabase database,ConnectionSource connectionSource)

更新表:使用ormlite提供的TableUtils.dropTable(connectionSource, User.class, true);进行删除操作~

onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion)

 我这里封装的是单例,所以一般最好在Application的OnCreate方法初始化:

DatabaseHelper.initOrmLite(this);

 我看了很多人的写法,都喜欢在Helper里面写各种方法,获取各种Dao来操作数据库,要是应用数据复杂些,就会有很多很多的方法,复杂不容易管理,就像一个Activity写了几千行代码,让我是没兴趣去往下看方法,找方法也麻烦。所以我再这个Helper里面只写了个简单的getDao方法,通过传入是Bean类找到它对应的Dao类,然后只操作对应的Dao类,这样就做出了分离;而且可以发现我使用了一个Map将Dao存起来,做了个缓存。下面来看看我封装的Dao类代码:

public class UserDao {public static UserDao mUserDaoInstance;private Dao<User, Integer> mUserDao;public UserDao() {try {mUserDao = DatabaseHelper.getInstance().getDao(User.class);} catch (SQLException e) {e.printStackTrace();}}public static UserDao getInstance() {if (mUserDaoInstance == null) {mUserDaoInstance = new UserDao();}return mUserDaoInstance;}/*** 单条插入数据*/public void insertUser(User user) {try {mUserDao.create(user);} catch (SQLException e) {e.printStackTrace();}}/*** 多条插入数据*/public void insertUsers(List<User> users) {try {mUserDao.create(users);} catch (SQLException e) {e.printStackTrace();}}/*** 查询所有数据*/public List<User> queryAllUser() {List<User> users = new ArrayList<>();try {users = mUserDao.queryForAll();} catch (SQLException e) {e.printStackTrace();}return users;}/*** 通过id查询数据*/public User queryUserById(int id) {User user = null;try {user = mUserDao.queryForId(id);} catch (SQLException e) {e.printStackTrace();}return user;}/*** 删除该id的数据*/public void deleteUserById(int id) {try {mUserDao.deleteById(id);} catch (SQLException e) {e.printStackTrace();}}/*** 删除这些id的数据*/public void deleteUserByIds(List<Integer> ids) {try {mUserDao.deleteIds(ids);} catch (SQLException e) {e.printStackTrace();}}/*** 删除所有*/public void deleteAllUser() {try {mUserDao.deleteBuilder().delete();} catch (SQLException e) {e.printStackTrace();}}/*** 更新当前实体类数据*/public void updateUser(User user) {try {mUserDao.update(user);} catch (SQLException e) {e.printStackTrace();}}/*** 更新当前数据的id*/public void updateUserById(User user, int id) {try {mUserDao.updateId(user, id);} catch (SQLException e) {e.printStackTrace();}}/*** 自定义查询*/public List<User> queryBy() throws SQLException {QueryBuilder<User, Integer> queryBuilder = mUserDao.queryBuilder();Where<User, Integer> where = queryBuilder.where();where.eq("id", 1);where.and();where.eq("name", "xxx");//或者mUserDao.queryBuilder().where().eq("id", 1).and().eq("name", "xxx");return queryBuilder.query();}
}

 我在这里也写成了单例模式,因为考虑到不止一个地方使用UserDao,使用代码如下:

User user = new User("jianglei", "金陵小霸王");
UserDao.getInstance().insertUser(user);

 其他的数据库操作同理,这样在维护一个数据库表的一些操作就比较简单了,在一个类里面维护,想找哪个数据库表的操作,就去对应类的Dao里面去找就行了。

 看完OrmLite,大家可以再看看更简单,效率更高的GreenDao框架,我也整理好了,大家可以对比下:http://blog.csdn.net/qq_19711823/article/details/51837032

 下面就是要讲比较枯燥的源码分析,没有兴趣的童鞋可以止步了。

三、源码分析

1.创建表
 我们先来看看创建表的方法:

@Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {try {TableUtils.createTable(connectionSource, User.class);} catch (SQLException e) {e.printStackTrace();}
}

 大家可以跟踪源码,可以发现,最主要的是doCreateTable中的两句话:

addCreateTableStatements(databaseType, tableInfo, statements, queriesAfter, ifNotExists);int stmtC = doStatements(connection, "create", statements, false, databaseType.isCreateTableReturnsNegative(), databaseType.isCreateTableReturnsZero());

 先来看看addCreateTableStatements实现:

private static <T, ID> void addCreateTableStatements(DatabaseType databaseType, TableInfo<T, ID> tableInfo, List<String> statements, List<String> queriesAfter, boolean ifNotExists) throws SQLException {StringBuilder sb = new StringBuilder(256);sb.append("CREATE TABLE ");if(ifNotExists && databaseType.isCreateIfNotExistsSupported()) {sb.append("IF NOT EXISTS ");}databaseType.appendEscapedEntityName(sb, tableInfo.getTableName()); // 添加表名sb.append(" (");ArrayList additionalArgs = new ArrayList();ArrayList statementsBefore = new ArrayList();ArrayList statementsAfter = new ArrayList();boolean first = true;FieldType[] i$ = tableInfo.getFieldTypes(); // 获取表的属性int arg = i$.length;for(int i$1 = 0; i$1 < arg; ++i$1) {FieldType fieldType = i$[i$1];if(!fieldType.isForeignCollection()) {if(first) {first = false;} else {sb.append(", "); // 第一个参数之前不需要“,”}String columnDefinition = fieldType.getColumnDefinition();if(columnDefinition == null) {databaseType.appendColumnArg(tableInfo.getTableName(), sb, fieldType, additionalArgs, statementsBefore, statementsAfter, queriesAfter);} else {databaseType.appendEscapedEntityName(sb, fieldType.getColumnName());sb.append(' ').append(columnDefinition).append(' '); // 添加列名}}}databaseType.addPrimaryKeySql(tableInfo.getFieldTypes(), additionalArgs, statementsBefore, statementsAfter, queriesAfter);databaseType.addUniqueComboSql(tableInfo.getFieldTypes(), additionalArgs, statementsBefore, statementsAfter, queriesAfter);Iterator var16 = additionalArgs.iterator();while(var16.hasNext()) {String var15 = (String)var16.next();sb.append(", ").append(var15);}sb.append(") "); // 拼装结束databaseType.appendCreateTableSuffix(sb);statements.addAll(statementsBefore);statements.add(sb.toString());statements.addAll(statementsAfter);addCreateIndexStatements(databaseType, tableInfo, statements, ifNotExists, false);addCreateIndexStatements(databaseType, tableInfo, statements, ifNotExists, true);}

 到这里,大家终于看到了一些熟悉的字眼,那些就是数据库最初的sql语句,这个函数主要是负责去生成我们要执行的sql语句。然后就是doStatements执行sql语句:

private static int doStatements(DatabaseConnection connection, String label, Collection<String> statements, boolean ignoreErrors, boolean returnsNegative, boolean expectingZero) throws SQLException {int stmtC = 0;for(Iterator i$ = statements.iterator(); i$.hasNext(); ++stmtC) {String statement = (String)i$.next();int rowC = 0;CompiledStatement compiledStmt = null;compiledStmt = connection.compileStatement(statement, StatementType.EXECUTE, noFieldTypes, -1);rowC = compiledStmt.runExecute();logger.info("executed {} table statement changed {} rows: {}", label,                          Integer.valueOf(rowC), statement); }...return stmtC;
}

http://chatgpt.dhexx.cn/article/JEymmoBS.shtml

相关文章

ORMLite完全解析(一)通过实例理解使用流程

在android中使用原始的SQLiteOpenHelper操作数据库显得过于繁琐&#xff0c;而且对于不是很熟悉数据库操作的人来说比较容易出现一些隐藏的漏洞。所以一般都会想到使用相关的ORMLite框架完成开发&#xff0c;类似于J2EE开发中的Hibernate和Mybatis等等&#xff0c;在提高开发效…

Android数据库ORMlite框架

前言 由于第二章是整个文档的核心&#xff0c;内容也很多&#xff0c;所以分次翻译。下一章的内容会继续本章接着翻译。 ------------------------------------------------------------------------------------- 2 如何使用 这一章进入到更多详细地使用ORMLite的各种功能。 2…

Ormlite 介绍 一

概述 ORMlite是类似hibernate的对象映射框架,主要面向java语言,同时,是时下最流行的android面向数据库的的编程工具。 官方网站:http://ormlite.com/ 如果需要开发android,只需要下载core和android两个jar包: ORMlite的使用 1,建立映射关系 Ormlite与数据库…

ormlite介绍一

概述 ORMlite是类似hibernate的对象映射框架&#xff0c;主要面向java语言&#xff0c;同时&#xff0c;是时下最流行的android面向数据库的的编程工具。 官方网站&#xff1a;http://ormlite.com/ 如果需要开发android&#xff0c;只需要下载core和android两个jar包&#xff…

Lite-Orm数据库

1. 初步认识 GItHub库 自动化且比系统自带数据库操作快1倍&#xff01; LiteOrm是android上的一款数据库&#xff08;ORM&#xff09;框架库。速度快、体积小、性能高。开发者基本一行代码实现数据库的增删改查操作&#xff0c;以及实体关系的持久化和自动映射。 2.导入orm相…

Android 数据库框架ormlite 使用精要

Android 数据库框架ormlite 使用精要 前言 本篇博客记录一下笔者在实际开发中使用到的一个数据库框架&#xff0c;这个可以让我们快速实现数据库操作&#xff0c;避免频繁手写sql&#xff0c;提高我们的开发效率&#xff0c;减少出错的机率。 ormlite是什么&#xff1f; 首…

ormlite 的简单应用

在android开发中还有哪些技术可以方便的操作数据库&#xff0c;我不大清楚&#xff0c;今天学习了一下 ormlite&#xff0c;觉得还不错&#xff0c;非常方便。 ormlite官网下载&#xff1a;http://ormlite.com/releases/ 1、引入jar包 2、写实体类 package com.example.aandr…

OrmLite for android--Ormlite的大概介绍

Ormlite 是一种ORM工具&#xff0c;并且是一种轻量级别的工具。我们可以使用它来对Android中内嵌的sqlite数据库进行相关的操作。Android 的应用程序应使用 Ormlite for android 版本来进行相关的开发。Ormlite for android 提供两个jar库&#xff1a;ormlite-android-4.22.j…

Ormlite 介绍 一

概述 ORMlite是类似hibernate的对象映射框架&#xff0c;主要面向java语言&#xff0c;同时&#xff0c;是时下最流行的android面向数据库的的编程工具。 官方网站&#xff1a;http://ormlite.com/ 如果需要开发android&#xff0c;只需要下载core和android两个jar包&#xff…

Ormlite基本使用

首先需要导入ORMLite的依赖&#xff1a;在build.gradle中加入以下代码&#xff1a; implementation com.j256.ormlite:ormlite-android:5.1implementation com.j256.ormlite:ormlite-core:5.1建立Bean类&#xff08;以OneTableBean为例&#xff09; import com.j256.ormlite.f…

Android 数据库框架ormlite 使用

ormlite是什么&#xff1f; 首先可以去它的官网看看www.ormlite.com&#xff0c;它的英文全称是Object Relational Mapping&#xff0c;意思是对象关系映射&#xff1b;如果接触过Java EE开发的&#xff0c;一定知道Java Web开发就有一个类似的数据库映射框架——Hibernate。简…

Android ORMLite数据库简介

&#xfeff;&#xfeff; 一般的项目中&#xff0c;Android自身提供的SQLite数据库&#xff0c;可以满足轻量级的数据存储应用&#xff0c;但是&#xff0c;只要是存储模型稍微复杂的项目&#xff0c;以及数据结构模型复杂的应用&#xff0c;就很难再用SQLite支撑整个项目的数…

python的网络请求库urllib、urllib2、urllib3、request的联系

文章目录 1. 简介2. urllib3. urllib24. urllib35. requests6. 相关文章 1. 简介 urllib、urllib2、urllib3、request均能通过网络访问互联网上的资源文件&#xff0c;它们通过使用统一资源定位符&#xff08;URL&#xff09;并结合re模块完成很多意想不到的操作。 urllib&am…

python3安装urllib2_python3.6想使用urllib2包怎么办

Python3.6.6或者说python3.x找不到urllib2语法问题修改之后&#xff0c;会报一个没有安装urllib2的包的错误。 通过pip install urllib2也会提示找不到包。(推荐学习&#xff1a;Python视频教程) 通过pip3 install urllib2也会提示找不到包。 这是因为builtwith依赖于urllib2包…

pythonurllib2方法_解决python3.6想使用urllib2包的方法

解决python3.6想使用urllib2包的方法 发布时间&#xff1a;2020-08-11 14:24:50 来源&#xff1a;亿速云 阅读&#xff1a;131 作者&#xff1a;小新 小编给大家分享一下解决python3.6想使用urllib2包的方法&#xff0c;相信大部分人都还不怎么了解&#xff0c;因此分享这篇文章…

python安装urllib2_Python如何安装urllib2库

urllib2 是 Python2.7 自带的模块(不需要下载,导入即可使用)。 urllib2库的基本使用 所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 在Python中有很多库可以用来抓取网页,我们先学习urllib2。urllib2 是 Python2.7 自带的模块(不需要下载,…

python爬虫-urllib2的使用方法详解(python3)

文章目录 python编程快速上手&#xff08;持续更新中…&#xff09;python爬虫从入门到精通urllib2概述python2与python3对比urlopenRequestUser-Agent添加更多的Header信息 urllib2默认只支持HTTP/HTTPS的GET和POST方法URL编码转换&#xff1a;urllib.parse.urlencode模拟百度…

Urllib2库丨Python爬虫基础入门系列(12)

提示&#xff1a;文末有福利&#xff01;最新Python爬虫资料/学习指南>>戳我直达 文章目录 前言Urllib2库学习目的urlopenGET请求方式利用urllib2.Request类,添加Header信息POST请求方式抓取招聘信息思考一下 小结 总结 前言 Urllib2库 urllib2是python2.7自带的模块(不…

Hyper-V虚拟化

第一章 Hyper-V 介绍 1-1 Hyper-V发展历史 2003 年&#xff0c;微软收购了一家虚拟化软件公司。2004 年推出了第一个桌面虚拟化产品Virtual PC 2004&#xff0c;其功能类似于VMware 工作站(work station)。由于该虚拟化产品集成在操作系统之中&#xff0c;所以用户可以在windo…

QNX Hypervisor管理程序

QNX Hypervisor管理程序 借助 QNX 管理程序&#xff0c;可以将具有不同操作系统&#xff0c;不同可靠性和安全要求的多个嵌入式系统&#xff0c;整合到单个片上系统 (SoC) 中。可以轻松地将未修改的代码移动到最新的硬件上&#xff0c;只需在适当配置的hypervisor 管理程序虚拟…