美文网首页
【Android - 框架】之ORMLite的使用(转)

【Android - 框架】之ORMLite的使用(转)

作者: 是我拉叔 | 来源:发表于2019-07-18 11:13 被阅读0次

https://www.cnblogs.com/itgungnir/p/6210949.html

【Android - 框架】之ORMLite的使用

  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对象直接调用

*/publicclassDatabaseHelperextends OrmLiteSqliteOpenHelper {

    // 数据库名称publicstaticfinalString DATABASE_NAME = "mydb.db";

    // 本类的单例实例privatestatic DatabaseHelper instance;

    // 存储APP中所有的DAO对象的Map集合privateMap daos =newHashMap<>();

    // 获取本类单例对象的方法publicstaticsynchronized 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)publicsynchronizedDao 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 // 创建数据库时调用的方法publicvoid onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {

        try {

            TableUtils.createTable(connectionSource, UserBean.class);

            TableUtils.createTable(connectionSource, ArticleBean.class);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    @Override // 数据库版本更新时调用的方法publicvoidonUpgrade(SQLiteDatabase database, ConnectionSource connectionSource,intoldVersion,int newVersion) {

        try {

            TableUtils.dropTable(connectionSource, UserBean.class,true);

            TableUtils.dropTable(connectionSource, ArticleBean.class,true);

            onCreate(database, connectionSource);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 释放资源    @Override

    publicvoid 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")// 指定数据表的名称publicclass UserBean {

    // 定义字段在数据库中的字段名publicstaticfinalString COLUMNNAME_ID = "id";

    publicstaticfinalString COLUMNNAME_NAME = "name";

    publicstaticfinalString COLUMNNAME_SEX = "sex";

    publicstaticfinalString COLUMNNAME_BIRTHDAY = "birthday";

    publicstaticfinalString COLUMNNAME_ADDRESS = "address";

    @DatabaseField(generatedId =true, columnName = COLUMNNAME_ID, useGetSet =true)

    privateint id;

    @DatabaseField(columnName = COLUMNNAME_NAME, useGetSet =true, canBeNull =false, unique =true)

    private String name;

    @DatabaseField(columnName = COLUMNNAME_SEX, useGetSet =true, defaultValue = "1")

    privatechar sex;

    @DatabaseField(columnName = COLUMNNAME_BIRTHDAY, useGetSet =true)

    private Date birthday;

    @DatabaseField(columnName = COLUMNNAME_ADDRESS, useGetSet =true)

    private String address;

    @ForeignCollectionField(eager =true)

    privateForeignCollection articles;

    public UserBean() {

    }

    publicUserBean(String name,char sex, Date birthday, String address) {

        this.name = name;

        this.sex = sex;

        this.birthday = birthday;

        this.address = address;

    }

    publicint getId() {

        return id;

    }

    publicvoidsetId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    publicvoid setName(String name) {

        this.name = name;

    }

    publicchar getSex() {

        return sex;

    }

    publicvoidsetSex(char sex) {

        this.sex = sex;

    }

    public Date getBirthday() {

        return birthday;

    }

    publicvoid setBirthday(Date birthday) {

        this.birthday = birthday;

    }

    public String getAddress() {

        return address;

    }

    publicvoid setAddress(String address) {

        this.address = address;

    }

    publicForeignCollection getArticles() {

        return articles;

    }

    publicvoidsetArticles(ForeignCollection articles) {

        this.articles = articles;

    }

    @Override

    public 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")publicclass ArticleBean {

    // article表中各个字段的名称publicstaticfinalString COLUMNNAME_ID = "id";

    publicstaticfinalString COLUMNNAME_TITLE = "title";

    publicstaticfinalString COLUMNNAME_CONTENT = "content";

    publicstaticfinalString COLUMNNAME_USER = "user_id";

    @DatabaseField(generatedId =true, columnName = COLUMNNAME_ID, useGetSet =true)

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

    }

    publicint getId() {

        return id;

    }

    publicvoidsetId(int id) {

        this.id = id;

    }

    public String getTitle() {

        return title;

    }

    publicvoid setTitle(String title) {

        this.title = title;

    }

    public String getContent() {

        return content;

    }

    publicvoid setContent(String content) {

        this.content = content;

    }

    public UserBean getUser() {

        return user_id;

    }

    publicvoid setUser(UserBean user) {

        this.user_id = user;

    }

    @Override

    public 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()方法查询表中的所有数据

*/publicclass UserDao {

    private Context context;

    // ORMLite提供的DAO类对象,第一个泛型是要操作的数据表映射成的实体类;第二个泛型是这个实体类中ID的数据类型privateDao dao;

    public UserDao(Context context) {

        this.context = context;

        try {

            this.dao = DatabaseHelper.getInstance(context).getDao(UserBean.class);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 向user表中添加一条数据publicvoid insert(UserBean data) {

        try {

            dao.create(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 删除user表中的一条数据publicvoid delete(UserBean data) {

        try {

            dao.delete(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 修改user表中的一条数据publicvoid update(UserBean data) {

        try {

            dao.update(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 查询user表中的所有数据publicList selectAll() {

        List users =null;

        try {

            users = dao.queryForAll();

        } catch (SQLException e) {

            e.printStackTrace();

        }

        return users;

    }

    // 根据ID取出用户信息publicUserBean 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类

*/publicclass ArticleDao {

    private Context context;

    // ORMLite提供的DAO类对象,第一个泛型是要操作的数据表映射成的实体类;第二个泛型是这个实体类中ID的数据类型privateDao dao;

    public ArticleDao(Context context) {

        this.context = context;

        try {

            this.dao = DatabaseHelper.getInstance(context).getDao(ArticleBean.class);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 添加数据publicvoid insert(ArticleBean data) {

        try {

            dao.create(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 删除数据publicvoid delete(ArticleBean data) {

        try {

            dao.delete(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 修改数据publicvoid update(ArticleBean data) {

        try {

            dao.update(data);

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    // 通过ID查询一条数据publicArticleBean queryById(int id) {

        ArticleBean article =null;

        try {

            article = dao.queryForId(id);

        } catch (SQLException e) {

            e.printStackTrace();

        }

        return article;

    }

    // 通过条件查询文章集合(通过用户ID查找)publicList queryByUserId(int user_id) {

        try {

            return dao.queryBuilder().where().eq(ArticleBean.COLUMNNAME_USER, user_id).query();

        } catch (SQLException e) {

            e.printStackTrace();

        }

        returnnull;

    }

}

  最后就是测试代码了。我们直接在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;publicclassMainActivityextends AppCompatActivity {

    private TextView tv;

    private StringBuffer contentBuffer;

    @Override

    protectedvoid onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        tv = (TextView) findViewById(R.id.tv);

        contentBuffer =new StringBuffer();

        initData();

        initView();

    }

    // 初始化数据privatevoid initData() {

        // 添加用户数据UserBean userData =newUserBean("张三", '1',newDate(), "北京");

        newUserDao(MainActivity.this).insert(userData);

        // 添加文章数据ArticleBean articleData =newArticleBean("标题", "内容内容内容内容内容内容", userData);

        newArticleDao(MainActivity.this).insert(articleData);

    }

    // 初始化视图privatevoid initView() {

        // 从数据库中根据ID取出文章信息ArticleBean articleBean =newArticleDao(MainActivity.this).queryById(1);

        contentBuffer.append(articleBean.toString());

        // 根据取出的用户id查询用户信息UserBean userBean =newUserDao(MainActivity.this).queryById(articleBean.getUser().getId());

        contentBuffer.append("\n\n" + userBean.toString());

        // 从用户信息中取出关联的文章列表信息ForeignCollection articles = userBean.getArticles();

        Iterator 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的使用(转)

      本文链接:https://www.haomeiwen.com/subject/zqiklctx.html