Android 数据库框架OrmLite的使用(二)

前面说了OrmLite的基本使用,现在说下更规范的做法以及常用的一些功能。

1.DatabaseHelper

package com.example.ormlite.db;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import com.example.ormlite.bean.Article;
import com.example.ormlite.bean.User;
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;
/**
 * 1.整个DatabaseHelper使用单例只对外公布一个对象,保证app中只存在一个SQLite Connection,参考文章:http://www.touchlab.co/2011/10/single-sqlite-connection/
 * 2.对每个Bean创建一个XXXDao来处理当前Bean的数据库操作,当然真正去和数据库打交道的对象,通过getDao(T t)进行获取
 *      getDao为一个泛型方法,会根据传入的Class对象进行创建Dao,并且用一个Map来保存对所有的Dao对象,只有第一次调用时才会去调用底层的getDao()。
 * @author Administrator
 *
 */
public class DatabaseHelperTwo extends OrmLiteSqliteOpenHelper{

    private static final String TABLE_NAME="sqlite-test.db";
    private static DatabaseHelperTwo instance;

    private Map<String,Dao> daos=new HashMap<String,Dao>();
    public DatabaseHelperTwo(Context context) {
        super(context, TABLE_NAME, null, 4);
    }
    @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();
        }
    }

    /**
     * 单例获取该Helper
     * @param context
     * @return
     */
    public static synchronized DatabaseHelperTwo getHelper(Context context){
        context=context.getApplicationContext();
        if(instance==null){
            synchronized(DatabaseHelperTwo.class){
                if(instance==null){
                    instance=new DatabaseHelperTwo(context);
                }
            }
        }
        return instance;
    }

    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;
        }
    }
}

2.编写Dao类

package com.example.ormlite.dao;
import java.sql.SQLException;
import com.example.ormlite.bean.User;
import com.example.ormlite.db.DatabaseHelperTwo;
import com.j256.ormlite.dao.Dao;
import android.content.Context;

public class UserDaoTwo {
    private Context context;
    private Dao<User,Integer> userDaoImpl;
    private DatabaseHelperTwo helper;

    @SuppressWarnings("unchecked")
    public UserDaoTwo(Context context){
        this.context=context;
        try {
            helper=DatabaseHelperTwo.getHelper(context);
            userDaoImpl=helper.getDao(User.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void add(User user){
        try {
            userDaoImpl.create(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    //......other operations
}

3.外键引用

package com.example.ormlite.bean;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
 * ORMLite外键引用
 * 需求:两个表User,Article,其中Article中需要存储User的主键作为关联,在ORMLite中如何实现?
 * 直接在Article中声明一个Int类型userId属性,当作普通属性处理搞定,也是可行的。但是并没有体现面向对象的思想。
 * 可按如下实现:
 * 1.不去定义一个int类型的userId,而是直接定义一个User成员变量,表示本Article属于该User。
 * 2.在User user属性上添加:@DatabaseField(canBeNull=true,foreign=true,columnName="user_id")
 *      canBeNull--表示不能为null;foreign=true表示一个外键;columnName列名
 * @author Administrator
 *
 */
@DatabaseTable(tableName="tb_article")
public class Article {
    @DatabaseField(generatedId=true)
    private int id;
    @DatabaseField(columnName="title")
    private String title;
    @DatabaseField(canBeNull=true,foreign=true,columnName="user_id")
    private User user;
    public Article() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Article(String title, User user) {
        super();
        this.title = title;
        this.user = 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 User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "Article [id=" + id + ", title=" + title + ", user=" + user
                + "]";
    }
}

接下来编写ArticleDao:

package com.example.ormlite.dao;
import java.sql.SQLException;
import java.util.List;
import android.content.Context;
import com.example.ormlite.bean.Article;
import com.example.ormlite.bean.User;
import com.example.ormlite.db.DatabaseHelperTwo;
import com.j256.ormlite.dao.Dao;

public class ArticleDao {
    private Dao<Article,Integer> articleDaoImpl;
    private DatabaseHelperTwo helper;

    @SuppressWarnings("unchecked")
    public ArticleDao(Context context){
        helper=DatabaseHelperTwo.getHelper(context);
        try {
            articleDaoImpl=helper.getDao(Article.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加
     * @param article
     */
    public void add(Article article){
        try {
            articleDaoImpl.create(article);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过Id得到一个Article
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public Article getArticleWithUser(int id){
        Article article=null;
        try {
            article=articleDaoImpl.queryForId(id);
            //如何做到只传一个Article的id,然后能够拿到Article对象,且内部的user属性直接赋值?
            //方式1
            helper.getDao(User.class).refresh(article.getUser());
            //方式2
            //在user属性的注解上:@DatabaseField(canBeNull = true, foreign = true, columnName = "user_id", foreignAutoRefresh = true)
            //foreignAutoRefresh =true,当调用queryForId时,拿到Article对象则直接携带了user
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return article;
    }

    /**
     * 通过Id得到一片文章
     * @param id
     * @return
     */
    public Article getArticleById(int id){
        Article article=null;
        try {
            article=articleDaoImpl.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return article;
    }

    public List<Article> getArticleListByUserId(int userId){
        try {
            return articleDaoImpl.queryBuilder().where().eq("user_id", userId).query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试:

package com.example.ormlite.test;
import java.util.List;
import android.test.AndroidTestCase;
import android.util.Log;
import com.example.ormlite.bean.Article;
import com.example.ormlite.bean.User;
import com.example.ormlite.dao.ArticleDao;
import com.example.ormlite.dao.UserDao;
import com.example.ormlite.dao.UserDaoTwo;

public class OrmLiteDbTestTwo extends AndroidTestCase{
    public void AddArticle(){
        User u=new User();
        u.setName("yq");
        u.setDesc("developer");
        new UserDao(getContext()).add(u);

        Article article=new Article();
        article.setTitle("ORMLite的使用");
        article.setUser(u);
        new ArticleDao(getContext()).add(article);
    }

    public void testGetArticleById(){
        Article article = new ArticleDao(getContext()).getArticleById(1);
        Log.i("OrmLiteDbTestTwo", article.getUser().toString() + " , " + article.getTitle());
    }

    /**
     * 通过id获取一个携带User的Article
     */
    public void testGetArticleWithUser(){
        Article article = new ArticleDao(getContext()).getArticleWithUser(1);
        Log.i("OrmLiteDbTestTwo", article.getUser().toString() + " , " + article.getTitle());
    }

    public void testSGetArticleListByUserId(){
        List<Article> articles =new ArticleDao(getContext()).getArticleListByUserId(1);
        Log.i("OrmLiteDbTestTwo", articles.toString());
    }
}

4.关联一个集合

每个User关联一个或多个Article,如果在User中声明一个Collection<Article> articles,可否做到在查询User的时候一并能够获取到articles的值?

是可以的。在User中加属性:

@ForeignCollectionField
private Collection<Article> articles;

UserDao中加方法:

public User getUserById(int id){
        try {
            return userDaoImpl.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

测试中加方法:

public void testGetUserById(){
        User user=new UserDaoTwo(getContext()).getUserById(2);
        Log.i("OrmLiteDbTestTwo", user.getName());
        if(user.getArticles()!=null){
            for (Article article : user.getArticles()) {
                Log.i("OrmLiteDbTestTwo", article.toString());
            }
        }
    }

5.查询条件QueryBuilder的使用

(1)简单的where等于

articleDaoImpl.queryBuilder().where().eq("user_id", userId).query(); //返回Article的列表

(2)where and

QueryBuilder<Article, Integer> queryBuilder=articleDaoImpl.queryBuilder();
            Where<Article, Integer> where=queryBuilder.where();
            where.eq("user_id", 2);
            where.and();
            where.eq("name", "xxx");

            //或者
            articleDaoImpl.queryBuilder().where().eq("user_id", userId).and().eq("name", "xxx");

上述的两种方法都相当于:select * from tb_article where user_id = 2 and name = ‘xxx‘ ;

(3)复杂查询

where.or(
                    where.and(
                            where.eq("user_id", 1),where.eq("name", "xxx")),
                    where.and(
                            where.eq("user_id", 2),where.eq("name", "yyy")));

select * from tb_article where ( user_id = 1 and name = ‘xxx‘ )  or ( user_id = 2 and name = ‘yyy‘ )  ;

再复杂的查询也可通过拼凑获得。

6.updateBuilder、deleteBuilder

使用queryBuilder是我们希望查询完后直接返回List<Bean>集合,对于update我们并不关注返回值,可以直接用articleDaoImpl.updateRaw(statement, arguments);传入sql和参数即可。也就没必要去用

articleDaoImpl.updateBuilder().updateColumnValue("name","zzz").where().eq("user_id", 1);这么痛苦了。

同理,deleteBuilder也建议直接瓶邪sql,当然很简单的除外。

7.事务

在Dao中直接写如下代码:

TransactionManager.callInTransaction(helper.getConnectionSource(),
                    new Callable<Void>() {

                        @Override
                        public Void call() throws Exception {

                            return null;
                        }
                    });

8.其他操作

1.当Bean继承BaseDaoEnable时,可以使用bean.create(bean); bean.update(bean)一类操作

例如:

package com.example.ormlite.bean;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.misc.BaseDaoEnabled;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "tb_student")
public class Student extends BaseDaoEnabled<Student, Integer>
{
    @DatabaseField(generatedId = true)
    private int id;

    @DatabaseField
    private String name;

    public Student(){
    }

    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;
    }
}
Dao dao=DatabaseHelperTwo.getHelper(context).getDao(Student.class);
            Student stu=new Student();
            stu.setDao(dao);
            stu.setName("qq");
            stu.create();

前提是dao需要手动设置,如果dao为null会报错。

2.Join

Article与User做Join操作:

QueryBuilder<Article, Integer> articleBuilder = articleDaoImpl.queryBuilder();
            QueryBuilder userBuilder = helper.getDao(User.class).queryBuilder();
            articleBuilder.join(userBuilder); 

其他具体的查看官方文档。

源码下载:http://pan.baidu.com/s/1ntMX99n 提取码:jri5

时间: 2024-10-12 09:55:25

Android 数据库框架OrmLite的使用(二)的相关文章

Android 数据库框架OrmLite的使用(一)

在这里记录下最基本的用法,官网上可了解相关的介绍. 1.下载OrmLite jar 在下载android的:ormlite-android-4.48.jar和ormlite-core-4.48.jar,放在你项目的libs目录下. 2.编写Bean类 package com.example.ormlite.bean; import java.util.Collection; import com.j256.ormlite.field.DatabaseField; import com.j256.

Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包

Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的,不是我们三言两语就能解决的,我一直想抽个时间自己再过一遍Sqlite和JDBC的,但是,大家也知道,琐事比较多,我们来说一下数据库的框架吧,事实上市面上,我觉得还可以的数据库框架有两个,ORMLite和GreenDao,我以前做的运动类的应用上,就需要存储大量的运动数据,我们最开始是在本地写数据库的

Android 数据库框架ormlite 使用精要

Android 数据库框架ormlite 使用精要 前言 本篇博客记录一下笔者在实际开发中使用到的一个数据库框架,这个可以让我们快速实现数据库操作,避免频繁手写sql,提高我们的开发效率,减少出错的机率. ormlite是什么? 首先可以去它的官网看看www.ormlite.com,它的英文全称是Object Relational Mapping,意思是对象关系映射:如果接触过Java EE开发的,一定知道Java Web开发就有一个类似的数据库映射框架--Hibernate.简单来说,就是我们

Android数据库框架-----ORMLite 的基本用法

ORMLite 是一款非要流行的Android平台上的数据库框架,性能优秀,代码简洁: 简述: 优点: 1.轻量级:2.使用简单,易上手:3.封装完善:4.文档全面. 缺点:1.基于反射,效率较低(本人还没有觉得效率低):2.缺少中文翻译文档 准备工作: jar包 地址:http://ormlite.com/releases/ 集成方法:把jar包复制到as的libs文件夹下,并且引用jar包即可 之后创建一个类User,并完成相关配置 @DatabaseTable(tableName="tb_

Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite

Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 但是对于我个人来说,我可能更加倾向于用GreenDao,所以今天也为大家带来了GreenDao的详细博客,希望大家喜欢,之前也详细介绍了ORM的思想,如果不明白可以先看一下前面的博文,这里就不多赘述了,我们新建一个工程 一.相关介绍 官方网站 : http://greendao

自己动手写Android数据库框架

前言 相信不少开发人员跟我一样,每次都非常烦恼自己写数据库,并且那些数据库语句也经常记不住.当然网上也有非常多非常好的数据库框架,你能够直接拿来用,可是 非常多时候我们的项目.特别是一个小型的Andrond应用原本用到的数据库结构比較简单,不是必需去用那些有点臃肿的框架.当然,即使你用那些框架.当你遇到问题时,你是否也得去改动它?你要改动别人的框架必须的读懂他人的设计代码.所以无论从那个角度出发,你都得掌握简单的数据库操作.那么这篇博客就从简单的数据库操作来学习Android数据库相关知识点.然

【光速使用开源框架系列】数据库框架OrmLite

[关于本系列] 最近看了不少开源框架,网上的资料也非常多,但是我认为了解一个框架最好的方法就是实际使用.本系列博文就是带领大家快速的上手一些常用的开源框架,体会到其作用. 由于作者水平有限,本系列只会描述如何快速的使用框架的基本功能,更多的详细设置大家可以在这些项目的页面上找到. [介绍]: ORMLite是一款辅助开发数据库的框架,可以通过给实体配置标注来快速建立数据表,也可以通过其提供的DAO类中的方法来快速对数据库进行操作,如增删改查等. [项目页面]: http://ormlite.co

Android数据库框架GreenDao封装使用,易理解、易扩展

一.概述 在之前一个项目中,因为涉及到数据库,所以就接触到了ORM框架的GreenDao.后面就去网上大量的搜索下载学习,发现很多都是官网的翻译或者是官网DEMO的简单入门讲解,而且对于小白,也不知道从何下手,最终还是放弃选择了本地sqlite. 时隔不久,GreenDao的应用已经是家常便饭了,于是乎,在上个周末就抽取了些时间对官网的DEMO进行拆解封装,并且完善了功能,尽可能的易于理解和扩展,方便以后直接拿来用. 二.效果图 下图addData/deleteData/changeData/q

Android Volley框架的使用(二)

使用请求队列RequestQueue Volley中的Request都需要添加到RequestQueue中才能执行,所以首先需要创建一个RequestQueue RequestQueue = Volley.newRequestQueue(mContext); 通常情况在一个应用中需要统一管理一个请求队列,所以采用单例模式(注意:这不是必须的),创建一个类并在这个类中初始化RequestQueue等核心对象,以及实现一些我们所需的方法: 代码如下: package com.javen.volley