ORMLite快速入门操作

大家在做安卓项目时肯定都会碰到数据库存储,原生的效率上会比较低,为了提高开发效率,大多公司会用一些框架,目前市面上比较流行的框架有ormlite、greenDao、SQLBrite、Realm等,其中ormlite是JDBC(Java数据库连接)和Android的轻量级ORM java包,而GreenDao则是一种轻快地将对象映射到SQLite数据库的ORM解决方案。
下面让我们快速的学习一下ormlite的简单使用

下载ORMLite Jar包

首先去ormlite官网下载所需的jar包,现在最新版本已经更新到5.0,分别为:ormlite-android-5.0.jar 和 ormlite-core-5.0.jar

定义Bean类

这里我们定义两个类,父母和孩子的关系
父母类

package com.liuw.ormlite.bean;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

/**
 * 父母
 */
//定义表名
@DatabaseTable(tableName = "tab_parent")
public class Parents {
    //generatedId定义主键自增长,columnName定义该字段在数据库中的列名
    @DatabaseField(useGetSet=true,generatedId=true,columnName="id")
    private int id;

    @DatabaseField(useGetSet=true, columnName = "f_id")
    private String fid;//父母编号

    @DatabaseField(useGetSet=true, columnName = "f_name")
    private String fname;//父亲姓名

    @DatabaseField(useGetSet=true, columnName = "m_name")
    private String mname;//母亲姓名

    public Parents() {
    }

    public Parents(String fid, String fname, String mname) {
        this.fid = fid;
        this.fname = fname;
        this.mname = mname;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFid() {
        return fid;
    }

    public void setFid(String fid) {
        this.fid = fid;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public String getMname() {
        return mname;
    }

    public void setMname(String mname) {
        this.mname = mname;
    }

    @Override
    public String toString() {
        return "Parents{" +
                "id=" + id +
                ", fid='" + fid + '\'' +
                ", fname='" + fname + '\'' +
                ", mname='" + mname + '\'' +
                '}';
    }
}

child类,孩子是属于某个父母,那肯定是需要parent类的主键才能找到关系,有的人可能会直接在child类里声明一个parent类里的fid属性,当做普通属性来处理,但这样就违背了面向对象思想
所以这里我们采用面向对象思想应该是这样,child属于某个parent,在child类里声明外键parent类来处理,这样的话在获取孩子信息的同时也能获取到对应父母的信息

package com.liuw.ormlite.bean;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

/**
 * 孩子
 */
@DatabaseTable(tableName = "tab_child")
public class Childs {

    @DatabaseField(useGetSet=true,generatedId=true,columnName="id")
    private int id;

    @DatabaseField(useGetSet=true, columnName = "s_name")
    private String sname;//姓名

    @DatabaseField(useGetSet=true, columnName = "s_gender")
    private String sgender;//性别

    @DatabaseField(useGetSet=true, columnName = "s_age")
    private String sage;//年龄

    @DatabaseField(useGetSet=true, columnName = "s_phone")
    private String sphone;//联系方式

    //引入外键(columnName值默认存储父类中的主键对应的值,也可以换成foreignColumnName指定父类字段,格式为foreignColumnName = "父表里的字段"
    //如foreignColumnName = "f_name",此时将会存储父表里对应的字段内容)
    @DatabaseField(useGetSet=true, canBeNull = true, foreign = true, columnName = "s_parent")
    private Parents parents;//父母信息

    public Childs() {

    }

    public Childs(String sname, String sgender, String sage) {
        this.sname = sname;
        this.sgender = sgender;
        this.sage = sage;
    }

    public String getSphone() {
        return sphone;
    }

    public void setSphone(String sphone) {
        this.sphone = sphone;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSgender() {
        return sgender;
    }

    public void setSgender(String sgender) {
        this.sgender = sgender;
    }

    public String getSage() {
        return sage;
    }

    public void setSage(String sage) {
        this.sage = sage;
    }

    public Parents getParents() {
        return parents;
    }

    public void setParents(Parents parents) {
        this.parents = parents;
    }

    @Override
    public String toString() {
        return "Childs{" +
                "id=" + id +
                ", sname='" + sname + '\'' +
                ", sgender='" + sgender + '\'' +
                ", sage='" + sage + '\'' +
                ", parents=" + parents +
                '}';
    }
}

SQLiteOpenHelper类

原生的数据库操作,都需要继承SQLiteOpenHelper,而ormlite我们则需要继承OrmLiteSqliteOpenHelper

package com.liuw.ormlite.dao;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;

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 com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Courses;
import com.liuw.ormlite.bean.Parents;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
    private static final String TABLE_NAME = "ormlite_test.db";//默认是在data/data/包名/databases/路径下
    public static final String DATABASE_PATH = Environment.getExternalStorageDirectory() + "/liuw/" + TABLE_NAME;//指定路径
    private static final int DB_VERSION = 3;

    private Map daos = new HashMap();

    private DatabaseHelper(Context context) {
        super(context, DATABASE_PATH, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database,
                         ConnectionSource connectionSource) {
        try {
            TableUtils.createTableIfNotExists(connectionSource, Childs.class);
            TableUtils.createTableIfNotExists(connectionSource, Courses.class);
            TableUtils.createTableIfNotExists(connectionSource, Parents.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase database,
                          ConnectionSource connectionSource, int oldVersion, int newVersion) {
           //整表删除创建
//        try {
//            TableUtils.dropTable(connectionSource, Childs.class, true);
//            TableUtils.dropTable(connectionSource, Courses.class, true);
//            TableUtils.dropTable(connectionSource, Parents.class, true);
//            onCreate(database, connectionSource);
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
    //更新数据库时只需添加新增字段
        if (newVersion == 3) {
            //数据库、表名、列名、类型
            DatabaseUtil.updateColumn(database, "tab_child", "s_phone", "VARCHAR", null);
        }
    }

    private static DatabaseHelper instance;

    /**
     * 单例获取该Helper
     *
     * @param context
     * @return
     */
    public static synchronized DatabaseHelper getHelper(Context context) {
        context = context.getApplicationContext();
        if (instance == null) {
            synchronized (DatabaseHelper.class) {
                if (instance == null)
                    instance = new DatabaseHelper(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;
        }
    }

}

这里详细就不做介绍了,onCreate创建表,onUpgrade更新表,网上教程大多都是采用删除再创建的方式更新,这里我们可以通过自定义的DatabaseUtil类来实现表结构的更新,其实内部就是一个添加列的原生SQL语句,代码如下:

package com.liuw.ormlite.dao;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class DatabaseUtil {
    public static void updateColumn(SQLiteDatabase db, String tableName,
                                    String columnName, String columnType, Object defaultField) {
        try {
            if (db != null) {
                Cursor c = db.rawQuery("SELECT * from " + tableName
                        + " limit 1 ", null);
                boolean flag = false;

                if (c != null) {
                    for (int i = 0; i < c.getColumnCount(); i++) {
                        if (columnName.equalsIgnoreCase(c.getColumnName(i))) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        String sql = "alter table " + tableName + " add "
                                + columnName + " " + columnType + " default "
                                + defaultField;
                        db.execSQL(sql);
                    }
                    c.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void deleteRecordsWithoutForeignKey(SQLiteDatabase db, String tableName){
        if (db != null) {
            String sql = "DELETE from " + tableName;
            db.execSQL(sql);
        }
    }
}

这样做的好处是不用再整表删除、创建,从而提高了工作效率

编写Dao类

我们可以将需要的增、删、改、查等方法都放在Dao里,便于操作使用
父类Dao

package com.liuw.ormlite.dao;

import android.content.Context;

import com.j256.ormlite.dao.Dao;
import com.liuw.ormlite.bean.Parents;

import java.sql.SQLException;

public class ParentDao {
    private Dao parentDao;
    private DatabaseHelper helper;

    public ParentDao(Context contex) {
        try {
            helper = DatabaseHelper.getHelper(contex);
            parentDao = helper.getDao(Parents.class);
            if (parentDao == null) {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 增
     * @param parent
     */
    public void addParent(Parents parent) {
        try {
            parentDao.create(parent);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

孩子类Dao

package com.liuw.ormlite.dao;

import android.content.Context;

import com.j256.ormlite.dao.Dao;
import com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Parents;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ChildDao {
    private Dao childDao;
    private DatabaseHelper helper;

    public ChildDao(Context contex) {
        try {
            helper = DatabaseHelper.getHelper(contex);
            childDao = helper.getDao(Childs.class);
            if (childDao == null) {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 增
     * @param child
     */
    public void addChild(Childs child) {
        try {
            childDao.create(child);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删(通过实体)
     * @param child
     */
    public void delChild(Childs child) {
        try {
            childDao.delete(child);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删(通过id)
     * @param id
     */
    public void delChildById(Integer id) {
        try {
            childDao.deleteById(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 改
     * @param child
     */
    public void updateChild(Childs child) {
        try {
            childDao.update(child);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查
     * @return
     */
    public List queryAllChild() {
        ArrayList childs = null;
        try {
            childs = (ArrayList) childDao.queryForAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return childs;
    }

    /**
     * 获取user
     * @param id child编号
     * @return
     */
    public Childs getChild(Integer id) {
        try {
            //父母信息为空
            return childDao.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取user
     * @param id child编号
     * @return
     */
    public Childs getChildAndParent(Integer id) {
        try {
            //父母信息有值,此处的refresh也可通过在数据中添加foreignAutoRefresh = true来实现
            Childs child = childDao.queryForId(id);
            helper.getDao(Parents.class).refresh(child.getParents());
            return child;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取user
     * @param name child姓名
     * @return
     */
    public List getChildByName(String name) {
        try {
            List childs = childDao.queryBuilder().where().eq("s_name", name).query();
            return childs;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
}

测试

测试之前不要忘了加读写权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
package com.liuw.ormlite;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Parents;
import com.liuw.ormlite.dao.ParentDao;
import com.liuw.ormlite.dao.ChildDao;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
    }

    private void initData() {
        ParentDao parentDao = new ParentDao(getApplicationContext());
        ChildDao childDao = new ChildDao(getApplicationContext());

        Parents p1 = new Parents("001", "曹建华", "于晓红");
        parentDao.addParent(p1);

        Childs s1 = new Childs("猪小明", "男", "15");
        s1.setParents(p1);
        childDao.addChild(s1);

        Parents p2 = new Parents("002", "余正华", "谋女郎");
        parentDao.addParent(p2);

        Childs s2 = new Childs("闰土", "男", "20");
        s2.setParents(p2);
        childDao.addChild(s2);

        //id自增长默认从1开始
        Childs student1 = childDao.getChild(1);
        if (student1 != null) {
            //结果:Childs{id=1, sname='猪小明', sgender='男', sage='15', parents=Parents{id=1,fid='null' fname='null', mname='null'}}
            Log.i("liuw", student1.toString());
        }

        Childs student2 = childDao.getChildAndParent(2);
        if (student2 != null) {
            //结果:Childs{id=2, sname='闰土', sgender='男', sage='20', parents=Parents{id=2,fid='002' fname='余正华', mname='谋女郎'}}
            Log.i("liuw", student2.toString());
        }

        List students = childDao.getChildByName("闰土");
        if (students != null && students.size() > 0) {
            Log.i("liuw", "数据大小为:"+students.size());
        }

    }
}

注意上面的两个结果的区别,具体可以看下两个方法,可以手动刷新,也可以直接在数据库的表里添加foreignAutoRefresh = true来实现;
本来是准备写一篇多表、多条件之间查询的,不过模拟数据添加起来有点麻烦,这里先介绍两篇文章做参考吧
复杂条件查询
ormlite参数及方法介绍

你可能感兴趣的:(Android)