您的位置:首页 > 移动开发 > Android开发

关于Android数据库orm工具库对比的几点思考(二)

2016-10-20 11:19 429 查看

一、前言

上一篇详细解析了关于greenDao的具体用法,接下来的主角就是OrmLite,本篇博客将详细介绍ORMLite的简易用法。感兴趣的可以去官网查看,点击进入官网,它的英文全称是Object Relational Mapping,意思是对象关系映射;如果接触过Java EE开发的,一定知道Java Web开发就有一个类似的数据库映射框架——Hibernate。简单来说,就是我们定义一个实体类,利用这个框架,它可以帮我们吧这个实体映射到我们的数据库中,在Android中是SQLite,数据中的字段就是我们定义实体的成员变量。

二、OrmLite的介绍

ormlite-android

项目地址:https://github.com/j256/ormlite-android

文档介绍:http://ormlite.com/sqlite_java_android_orm.shtml

优点:

轻量级

使用简单,易上手

封装完善

文档全面

缺点:

基于反射,效率较低

缺少中文翻译文档

三、OrmLite的使用

(一)导入jar包到项目libs文件夹下

可以通过官方发布页面下载jar包,ORMLite release page,目前最新的是5.0。在android应用中使用,我们需要下载ormlite-android-5.0.jar和ormlite-core-5.0.jar两个文件。

(二)工程使用

配置model类

User类:

// 配置该User实体类对应的表名为orm_user,如果不加tableName="orm_user"属性,则表名为类名
@DatabaseTable(tableName = "orm_user")
public class User {

// 配置字段名为id,并设为主键
@DatabaseField(columnName = "id", generatedId = true)
private int id;
// 配置字段名为name,并且该字段不能为空
@DatabaseField(columnName = "name", canBeNull = false)
private String name;
// 使用本身变量名为字段名
@DatabaseField
private int age;
// 使用本身变量名为字段名,并且设置默认值
@DatabaseField(defaultValue = "这个人很懒,什么也没说")
private String desc;
// 一个用户对应多篇文章,eager = true表示可以进行懒加载
// 注:这里是一对多的关系,如果是1对1,我们要用@DatabaseField注解,还要指定(foreign = true)表示是一个外键
@ForeignCollectionField(eager = true)
public ForeignCollection<Article> articles;

/**
* @return the id
*/
public int getId() {
return id;
}

/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}

/**
* @return the name
*/
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the age
*/
public int getAge() {
return age;
}

/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}

/**
* @return the desc
*/
public String getDesc() {
return desc;
}

/**
* @param desc the desc to set
*/
public void setDesc(String desc) {
this.desc = desc;
}

/**
* @return the articles
*/
public ForeignCollection<Article> getArticles() {
return articles;
}

/**
* @param articles the articles to set
*/
public void setArticles(ForeignCollection<Article> articles) {
this.articles = articles;
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + ", desc="
+ desc + "]";
}
}


Article类:

// 配置该Article实体类对应的表名为orm_article,如果不加tableName="orm_article"属性,则表名为类名
@DatabaseTable(tableName = "orm_article")
public class Article {

// 配置字段名为id,并设为主键
@DatabaseField(columnName="id",generatedId=true)
private int id;
// 配置字段名为name,并且该字段不能为空
@DatabaseField(columnName="uid",canBeNull = false)
private int uid;
// 使用本身变量名为字段名
@DatabaseField
private String title;
// 使用本身变量名为字段名
@DatabaseField
private String content;
// 使用本身变量名为字段名
@DatabaseField
private String date;

// 外部对象字段,并指定这个字段的对象是一个外键,外键值是这个对象的id
@DatabaseField(foreign = true, foreignAutoRefresh = true)
private User mUser;

/**
* @return the id
*/
public int getId() {
return id;
}

/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}

/**
* @return the uid
*/
public int getUid() {
return uid;
}

/**
* @param uid the uid to set
*/
public void setUid(int uid) {
this.uid = uid;
}

/**
* @return the title
*/
public String getTitle() {
return title;
}

/**
* @param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}

/**
* @return the content
*/
public String getContent() {
return content;
}

/**
* @param content the content to set
*/
public void setContent(String content) {
this.content = content;
}

/**
* @return the date
*/
public String getDate() {
return date;
}

/**
* @param date the date to set
*/
public void setDate(String date) {
this.date = date;
}

/**
* @return the mUser
*/
public User getmUser() {
return mUser;
}

/**
* @param mUser the mUser to set
*/
public void setmUser(User mUser) {
this.mUser = mUser;
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Article [id=" + id + ", uid=" + uid + ", title=" + title
+ ", content=" + content + ", date=" + date + "]";
}
}


@DatabaseTable
注解中,
tableName
参数是可选的,也就是这个类对应的表名。如果没有特别指出,那么这个类名将默认作为表名。对于类中的每个需要存储的成员变量,都需要添加
@DatabaseField
注解。

@DatabaseField
常用注解:

columnName
指定字段名,不指定则变量名作为字段名

canBeNull
字段是否能被分配null值。默认是true。如果你设置成false,那么你每次在数据库中插入数据是都必须为这个字段提供值。

dataType
指定字段的类型

defaultValue
当我们在表中创建新的记录时的一个字段的默认值。默认情况下是没有这个值的

width
字段的宽度,主要用于字符串字段。默认是0

id
这个字段是否是id,默认是false。在一个class中只有一个成变量可以有这个值。id字段是一条记录的唯一标识而且是必需的,只能在generatedId和 generatedIdSequence其中选一个。

generatedId
字段是否自动增加。默认为false。类中的一个成员变量设置了这个值,它告诉数据库每添加一条新记录都自动增加 id。当一个有generatedid的对象被创建时使用Dao.create()方法,数据库将为记录生成一个id,它会被返回并且被create方法设置进对象。

generatedIdSequence
序列编号的名字,这个值在生成的时候会被使用。和generatedId相似,但是你能够指定使用的序列名称。默认是没有的。

foreign
指定这个字段的对象是一个外键,外键值是这个对象的id

persisted
指定是否持久化此变量,默认true

foreignAutoCreate
外键不存在时是否自动添加到外间表中

foreignColumnName
外键字段指定的外键表中的哪个字段

还有一个外键的相关注解,这里也写下来供参考。

@ForeignCollectionField
常用注解

eager
表示该集合是在初始化这个对象的时候,是否讲对象取出还是在遍历的时候才取出,默认false遍历的时候才取出,size()方法也会引起遍历

columnName


orderColumnName


foreignFieldName


(三)创建DB Helper

创建一个自己的
DBHelper
类,继承自
OrmLiteSqliteOpenHelper
,这个类可以在程序被安装时创建或者升级数据库,同时也可以提供一个DAO给其他的类使用。这个helper类需要实现
onCreate(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource)
onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion)
方法。一个用于生成数据库,一个用于升级数据库。

继承OrmLiteSqliteOpenHelper类,自定义数据库辅助类DBHelper.class

public class DBHelper extends OrmLiteSqliteOpenHelper {
/**
* 数据库名字
*/
private static final String DB_NAME = "ormlite.db";

/**
* 数据库版本
*/
private static final int DB_VERSION = 1;

/**
* 用来存放Dao的Map集合,之所以创建Map集合,是为了方便对数据库资源的管理
*/
private Map<String, Dao> daos = new HashMap<String, Dao>();

/**
* 数据库连接对象
*/
private AndroidConnectionSource connectionSource;

/**
* 单例对象
*/
private static DBHelper instance;

/**
* <p>Title: DBHelper</p>
* <p>Description: 构造方法</p>
*
* @param context         上下文资源
* @param databaseName    数据库名称
* @param factory         游标工厂
* @param databaseVersion 数据库版本
*/
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}

/**
* @param context
* @return DBHelper
* @Title: getHelper
* @Description: TODO(使用单例模式获取数据库对象)
*/
public static synchronized DBHelper getHelper(Context context) {
if (instance == null) {
synchronized (DBHelper.class) {
if (instance == null) {
instance = new DBHelper(context);
}
}
}
return instance;
}

/**
* @param cls
* @return dao
* @Title: getDao
* @Description: TODO(通过类名获得指定的Dao,并将取得的Dao放入Map集合)
*/
public synchronized Dao getDao(Class cls) throws SQLException {
Dao dao = null;
// 获得类名
String className = cls.getSimpleName();
// 判断类名是否为空
if (!className.equals("") || !className.equals(null)) {
// 如果不为空则获取Dao对象
dao = super.getDao(cls);
// 将Dao对象放入Map集合
daos.put(className, dao);
} else {
return null;
}
return dao;
}

/* (non-Javadoc)
* @see com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase, com.j256.ormlite.support.ConnectionSource)
*/
@Override
public void onCreate(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource) {
// 创建操作
try {
// 创建用户表
TableUtils.createTable(connectionSource, User.class);
// 创建文章表
TableUtils.createTable(connectionSource, Article.class);
} catch (SQLException e) {
e.printStackTrace();
}
}

/* (non-Javadoc)
* @see com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase,
com.j256.ormlite.support.ConnectionSource, int, int)
*/
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int oldVersion,
int newVersion) {
// 更新操作
try {
// 更新用户表
TableUtils.dropTable(connectionSource, User.class, true);
// 更新文章表
TableUtils.dropTable(connectionSource, Article.class, true);
onCreate(sqLiteDatabase, connectionSource);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
* @Title: close
* @Description: TODO(释放资源)
*/
public void close() {
super.close();
for (String key : daos.keySet()) {
Dao dao = daos.get(key);
// 释放Dao资源
dao = null;
}
}
}


(四)创建DAO

public class UserDao {
private Dao<User, Integer> userDao;
private DBHelper dbHelper;

/**
*
* <p>Title: UserDao</p>
* <p>Description: 构造方法</p>
* @param context  上下午资源对象
*/
public UserDao(Context context) {
try {
// 使用单例模式
dbHelper = DBHelper.getHelper(context);
userDao = dbHelper.getDao(User.class);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
* @Title: add
* @Description: TODO(添加用户)
* @param  user
* @return void
*/
public void add(User user) {
try {
userDao.create(user);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
* @Title: delete
* @Description: TODO(根据ID删除单条记录)
* @param  id
* @return void
*/
public void delete(int id) {
try {
userDao.deleteById(id);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
*
* @Title: update
* @Description: TODO(更新单条记录)
* @param  user
* @return void
*/
public void update(User user) {
try {
userDao.createOrUpdate(user);
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
* @Title: queryForId
* @Description: TODO(根据ID查询单条记录)
* @param  id
* @return User
*/
public User queryForId(int id) {
User user = null;
try {
user = userDao.queryForId(id);
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}

/**
* @Title: queryForAll
* @Description: TODO(查询所有记录)
* @return List<User>
*/
public List<User> queryForAll() {
List<User> mUsers = new ArrayList<User>();
try {
mUsers = userDao.queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return mUsers;
}
}


DAO里的主要方法:

create 插入一条数据

createIfNotExists 如果不存在则插入

createOrUpdate 如果指定id则更新

queryForId 更具id查找

update 查找出数据

delete 删除数据

queryBuilder() 创建一个查询生成器:进行复杂查询

deleteBuilder() 创建一个删除生成器,进程复杂条件删除

updateBuilder() 创建修条件生成器,进行复杂条件修改

(五)数据增删改查

public class MainActivity extends Activity implements OnClickListener {

private TextView tv_show;      // 控制台显示文本
private Button btn_add;          // 新增
private Button btn_query;          // 查询
private Button btn_update;          // 更新
private Button btn_delete;          // 删除
private User user;
private UserDao userDao;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userDao = new UserDao(this);
// 实例化控件
init();
// 设置监听事件
setListener();
}

/**
* @param
* @return void
* @Title: init
* @Description: TODO(实例化控件)
*/
private void init() {
tv_show = (TextView) findViewById(R.id.tv_show);
btn_add = (Button) findViewById(R.id.btn_add);
btn_query = (Button) findViewById(R.id.btn_query);
btn_update = (Button) findViewById(R.id.btn_update);
btn_delete = (Button) findViewById(R.id.btn_delete);
}

/**
* @param
* @return void
* @Title: setListener
* @Description: TODO(设置监听事件)
*/
private void setListener() {
btn_add.setOnClickListener(this);
btn_query.setOnClickListener(this);
btn_update.setOnClickListener(this);
btn_delete.setOnClickListener(this);
}

/* (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
// 新增操作
case R.id.btn_add:
add();
break;
// 查询操作
case R.id.btn_query:
query();
break;
// 更新操作
case R.id.btn_update:
update();
break;
// 删除操作
case R.id.btn_delete:
delete();
break;

default:
break;
}
}

/**
* @param
* @return void
* @Title: add
* @Description: TODO(添加数据)
*/
private void add() {
for (int i = 1; i <= 10; i++) {
user = new User();
user.setName("Alonez_" + i);   // 设置姓名
user.setAge(10 + i);        // 设置年龄
userDao.add(user);
}
tv_show.setText("新增了" + userDao.queryForAll().size() + "位用户\n第1位用户名为:" +
userDao.queryForAll().get(0).getName() +
"\n" + "第" + userDao.queryForAll().size() + "位用户名为:" +
"" + userDao.queryForAll().get(userDao.queryForAll().size() - 1).getName());
}

/**
* @param
* @return void
* @Title: query
* @Description: TODO(查询数据)
*/
private void query() {
user = userDao.queryForId(5);
tv_show.setText("第5位用户ID:" + user.getId() + "\n"
+ "第5位用户姓名:" + user.getName() + "\n"
+ "第5位用户年龄:" + user.getAge() + "\n"
+ "第5位用户描述:" + user.getDesc());
}

/**
* @param
* @return void
* @Title: update
* @Description: TODO(更新操作)
*/
private void update() {
user = new User();
user.setId(5);
user.setName("我是第5位用户");
user.setAge(77);
user.setDesc("啦啦啦,德玛西亚");
userDao.update(user);

user = userDao.queryForId(5);
tv_show.setText("第5位用户ID:" + user.getId() + "\n"
+ "第5位用户姓名:" + user.getName() + "\n"
+ "第5位用户年龄:" + user.getAge() + "\n"
+ "第5位用户描述:" + user.getDesc());
}

/**
* @param
* @return void
* @Title: delete
* @Description: TODO(删除操作)
*/
private void delete() {
userDao.delete(1);
tv_show.setText("数据库还有" + userDao.queryForAll().size() + "位用户");
}
}


布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sence.testormlite.MainActivity"
android:orientation="vertical">

<TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="17dp"
android:text="显示文本"/>

<Button
android:id="@+id/btn_add"
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="创建十条数据"/>
<Button
android:id="@+id/btn_query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询一条数据"/>
<Button
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更新一条数据"/>
<Button
android:id="@+id/btn_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除一条数据"/>
</LinearLayout>


这章内容到这里就要结束了,后期还会继续更其他数据库框架的内容,当然最后会作一期对比总结版,じゃ、みんな、さようなら。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android orm 数据库