关于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工具库对比的几点思考(一)
- 关于Android数据库orm工具库对比的几点思考(三)
- 关于Android数据库orm工具库对比的几点思考(四)
- Android 关于ormlite数据库框架解析(二)
- Android数据库工具ORM-greenDAO学习
- 关于android sqlite数据库使用的几点心得
- Android 开源项目android-open-project工具库解析之(一) 依赖注入,图片缓存,网络相关,数据库orm工具包,Android公共库
- Android ORM数据库框架对比
- 关于Android 数据库使用的几点心得
- 关于数据库查询业务的几点思考
- 关于数据库查询业务的几点思考
- 关于微软停止移植 Android 应用的几点思考
- Android 开源项目android-open-project工具库解析之(一) 依赖注入,图片缓存,网络相关,数据库orm工具包,Android公共库
- 关于Java的ORM及 PHP直接面向数据库关系 模式的思考
- Android Sqlite数据库执行插入查询更新删除的操作对比
- 关于《微积分阅览室》的几点思考
- Android 关于Service的几点理解
- 关于androidUI设计的几点建议
- 关于软件开发人员评价的几点思考
- Android记录5--关于Android云测试的小思考