xutils3框架之数据库使用详解!

这段时间公司做项目,基本每天都要和数据库打交道,当初选择使用xutils3框架;刚开始使用的时候,也是遇到很多坑,小弟在此一一总结一下,希望能帮到大家,顺便自己也做个笔记。

如何导入SDK我就不说了,先从初始化说起。一般三方的东西最好都是在application里面完成,代码如下:

 daoConfig = new DbManager.DaoConfig()
                .setDbName("iDEvent.db")//设置数据库名称
                        // 不设置dbDir时, 默认存储在app的私有目录.
                .setDbDir(new File("sdcard/SitSmice/iDEvent/DownLoad/dbPath")) // 数据库存储路径
                .setDbVersion(1)//设置数据库版本
                .setDbOpenListener(new DbManager.DbOpenListener() {
                    @Override
                    public void onDbOpened(DbManager db) {
                        // 开启WAL, 对写入加速提升巨大
                        db.getDatabase().enableWriteAheadLogging();
                    }
                })
//                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
//                    @Override
//                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
//                        // TODO: ...
//                        try {
//                            db.addColumn(Sign.class,"test");
//                        } catch (DbException e) {
//                            MLog.e("test","数据库更新失败");
//                            e.printStackTrace();
//                        }
//                        // db.dropTable(...);
//                        // ...
//                        // or
//                        // db.dropDb();
//                    }
//                })
        ;
        //db还有其他的一些构造方法,比如含有更新表版本的监听器的
        db = x.getDb(daoConfig);//获取数据库单例
需要注意的是,我这里把那个监听数据库升级的监听屏蔽了,一般升级数据不需要特殊处理的话最好不要设置监听;正常升级数据库的方法是:比如你的app第一版数据库版本设置的是1,如果第二版数据库字段有变动,那就直接把版本设置成2就可以了,但是这样会删除你app里面的数据库,看监听源码得知:
 public synchronized static DbManager getInstance(DaoConfig daoConfig) {

        if (daoConfig == null) {//使用默认配置
            daoConfig = new DaoConfig();
        }

        MyDbBase dao = DAO_MAP.get(daoConfig);
        if (dao == null) {
            dao = new MyDbBase(daoConfig);
            DAO_MAP.put(daoConfig, dao);
        } else {
            dao.daoConfig = daoConfig;
        }

        // update the database if needed
        SQLiteDatabase database = dao.database;
        int oldVersion = database.getVersion();
        int newVersion = daoConfig.getDbVersion();
        if (oldVersion != newVersion) {
            if (oldVersion != 0) {
                DbUpgradeListener upgradeListener = daoConfig.getDbUpgradeListener();
                if (upgradeListener != null) {//如果你不想删除之前app里面的数据,那就可以设置监听,在监听里面将之前表数据拷贝到新的表里面就可以了
                    upgradeListener.onUpgrade(dao, oldVersion, newVersion);
                } else {
                    try {
                        dao.dropDb();//如果设置了监听,那就直接删除了数据库,之前保存的数据就没有了
                    } catch (DbException e) {
                        LogUtil.e(e.getMessage(), e);
                    }
                }
            }
            database.setVersion(newVersion);
        }

        return dao;
    }

 这里插个小曲:xutils3主要看两个类Dbmanger和DbmangerImpl,从名称就能看出来,前者是管理类,用于初始化数据库操作的接口类,后者是相对应的实现类。想研究源码的同学可以去DbmangerImpl好好学习一下。 
  

接下来就是创建一张表了,代码如下:

@Table(name = "test")//表名
public class Test {

    /**
     * isId = true 代表该字段是这张表的主键,类型也可以是String (赋值为false就不是主键了),虽然数据库表可以设置多个主键,但是在实际操作的时候还是设置一个      * 主键最好,小弟设置过两个主键,但是并没有达到我想要的效果
     * autoGen = true 代表主键自增长,如果不是自增长,那就赋值false (这里主键是否自增长很关键,会影响到后面数据库的操作,下面再结合方法来解释)
     */
    @Column(name = "_id",isId = true,autoGen = true)
    public int _id;

    @Column(name = "column1")//字段名称1
    public String column1;

    @Column(name = "column2")//字段名称2
    public String column2;

    @Column(name = "column3")//字段名称3
    public String column3;

    @Override
    public String toString() {
        return "Test{" +
                "_id=" + _id +
                ", column1='" + column1 + '\'' +
                ", column2='" + column2 + '\'' +
                ", column3='" + column3 + '\'' +
                '}';
    }

    public int get_id() {
        return _id;
    }

    public void set_id(int _id) {
        this._id = _id;
    }

    public String getColumn1() {
        return column1;
    }

    public void setColumn1(String column1) {
        this.column1 = column1;
    }

    public String getColumn2() {
        return column2;
    }

    public void setColumn2(String column2) {
        this.column2 = column2;
    }

    public String getColumn3() {
        return column3;
    }

    public void setColumn3(String column3) {
        this.column3 = column3;
    }
}
表初始化完整之后,有人会问怎么创建这张表呢?遗憾的是xutils3并没有提供单独创建一张表的方法,他是在你调插入数据库操作的时候会判断是否存在这张表,如果不存在就会去创建,查看源码得知:

 @Override
    public void saveOrUpdate(Object entity) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);//这里就是判断如果不存在这张表,那就创建这张表
                for (Object item : entities) {
                    saveOrUpdateWithoutTransaction(table, item);
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                createTableIfNotExist(table);
                saveOrUpdateWithoutTransaction(table, entity);
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }
那如果有人需要单独创建一张表怎么办呢?方法当然是有的,小弟当初一开始是这么干的:

MyApplication.db.save(new Test());
这样不是不可以,但是这么干会让你的数据库插入一条空的Test对象,略有强迫症的小弟显然不会这么干,想着一定要创建一张空表,后来研究了一番,发现只能继承DbBase这个类,重新里面的creatTable方法,代码如下:

package com.sitsmice.utils;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Build;

import com.sitsmice.MyApplication;
import com.sitsmice.idevevt_jar.MLog;
import com.sitsmice.model.Message;
import com.sitsmice.model.sign.Sign_User;
import com.sitsmice.model.teamtask.TeamTask;

import org.xutils.DbManager;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.KeyValue;
import org.xutils.common.util.LogUtil;
import org.xutils.db.Selector;
import org.xutils.db.sqlite.SqlInfo;
import org.xutils.db.sqlite.SqlInfoBuilder;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.db.table.ColumnEntity;
import org.xutils.db.table.DbBase;
import org.xutils.db.table.DbModel;
import org.xutils.db.table.TableEntity;
import org.xutils.ex.DbException;
import org.xutils.x;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by sahara on 2016/6/3.
 */
public class MyDbBase extends DbBase{
    public static MyDbBase myDbBase;

    public static MyDbBase getInstance(){
        if (myDbBase==null){
            myDbBase = new MyDbBase(MyApplication.daoConfig);
        }
        return myDbBase;
    }

    /**
     * 创建一张表
     * @param t
     * @param 
     * @throws DbException
     */
    public  void  creatTable(T t) throws DbException {
        TableEntity table = this.getTable(t.getClass());
        createTableIfNotExist(table);
    }

    /**
     * 按照字段checked_time降序将sign_user对象查询出来
     */
    public List orderBY(int status,String snid) throws DbException {
        Cursor cursor = MyApplication.db.execQuery("SELECT * FROM sign_user WHERE status = '" + status + "' and snid = '" + snid + "'ORDER BY checked_time DESC");
        List list = new ArrayList<>();
        while (cursor.moveToNext()){
            Sign_User sign_user = new Sign_User();
            sign_user._id = cursor.getInt(cursor.getColumnIndex("_id"));
            sign_user.snuid = cursor.getString(cursor.getColumnIndex("snuid"));
            sign_user.snid = cursor.getString(cursor.getColumnIndex("snid"));
            sign_user.mid = cursor.getInt(cursor.getColumnIndex("mid"));
            sign_user.lid = cursor.getInt(cursor.getColumnIndex("lid"));
            sign_user.userName = cursor.getString(cursor.getColumnIndex("userName"));
            sign_user.company = cursor.getString(cursor.getColumnIndex("company"));
            sign_user.phone = cursor.getString(cursor.getColumnIndex("phone"));
            sign_user.sex = cursor.getString(cursor.getColumnIndex("sex"));
            sign_user.email = cursor.getString(cursor.getColumnIndex("email"));
            sign_user.ivcode = cursor.getString(cursor.getColumnIndex("ivcode"));
            sign_user.checked = cursor.getString(cursor.getColumnIndex("checked"));
            sign_user.reason = cursor.getString(cursor.getColumnIndex("reason"));
            sign_user.checked_time = cursor.getString(cursor.getColumnIndex("checked_time"));
            sign_user.signData = cursor.getString(cursor.getColumnIndex("signData"));
            sign_user.delete_time = cursor.getString(cursor.getColumnIndex("delete_time"));
            sign_user.status = cursor.getInt(cursor.getColumnIndex("status"));
            sign_user.url = cursor.getString(cursor.getColumnIndex("url"));
            sign_user.referer_url = cursor.getString(cursor.getColumnIndex("referer_url"));
            sign_user.add_ip = cursor.getString(cursor.getColumnIndex("add_ip"));
            sign_user.add_time = cursor.getString(cursor.getColumnIndex("add_time"));
            sign_user.add_user_name = cursor.getString(cursor.getColumnIndex("add_user_name"));
            sign_user.update_ip = cursor.getString(cursor.getColumnIndex("update_ip"));
            sign_user.update_time = cursor.getString(cursor.getColumnIndex("update_time"));
            sign_user.update_user_name = cursor.getString(cursor.getColumnIndex("update_user_name"));
            sign_user.SIGN_KEY = cursor.getString(cursor.getColumnIndex("SIGN_KEY"));
            sign_user.CAUSE = cursor.getString(cursor.getColumnIndex("CAUSE"));
            sign_user.eating_habits = cursor.getString(cursor.getColumnIndex("eating_habits"));
            sign_user.update = cursor.getInt(cursor.getColumnIndex("update"));
            sign_user.longitude = cursor.getString(cursor.getColumnIndex("longitude"));
            sign_user.latitude = cursor.getString(cursor.getColumnIndex("latitude"));
            sign_user.deviceid = cursor.getString(cursor.getColumnIndex("deviceid"));
//            MLog.e("test","当前解析对象:"+sign_user.toString());
            list.add(sign_user);
        }
        if (cursor!=null){
            cursor.close();
        }
        return list;
    }

    /**
     * 按照字段checked_time降序将sign_user对象查询出来
     */
    public List orderBYDianM(int status,String snid) throws DbException {
        Cursor cursor = MyApplication.db.execQuery("SELECT * FROM sign_user WHERE status = '"+status+"' and snid = '"+snid+"'ORDER BY checked DESC,checked_time DESC");
        List list = new ArrayList<>();
        while (cursor.moveToNext()){
            Sign_User sign_user = new Sign_User();
            sign_user._id = cursor.getInt(cursor.getColumnIndex("_id"));
            sign_user.snuid = cursor.getString(cursor.getColumnIndex("snuid"));
            sign_user.snid = cursor.getString(cursor.getColumnIndex("snid"));
            sign_user.mid = cursor.getInt(cursor.getColumnIndex("mid"));
            sign_user.lid = cursor.getInt(cursor.getColumnIndex("lid"));
            sign_user.userName = cursor.getString(cursor.getColumnIndex("userName"));
            sign_user.company = cursor.getString(cursor.getColumnIndex("company"));
            sign_user.phone = cursor.getString(cursor.getColumnIndex("phone"));
            sign_user.sex = cursor.getString(cursor.getColumnIndex("sex"));
            sign_user.email = cursor.getString(cursor.getColumnIndex("email"));
            sign_user.ivcode = cursor.getString(cursor.getColumnIndex("ivcode"));
            sign_user.checked = cursor.getString(cursor.getColumnIndex("checked"));
            sign_user.reason = cursor.getString(cursor.getColumnIndex("reason"));
            sign_user.checked_time = cursor.getString(cursor.getColumnIndex("checked_time"));
            sign_user.signData = cursor.getString(cursor.getColumnIndex("signData"));
            sign_user.delete_time = cursor.getString(cursor.getColumnIndex("delete_time"));
            sign_user.status = cursor.getInt(cursor.getColumnIndex("status"));
            sign_user.url = cursor.getString(cursor.getColumnIndex("url"));
            sign_user.referer_url = cursor.getString(cursor.getColumnIndex("referer_url"));
            sign_user.add_ip = cursor.getString(cursor.getColumnIndex("add_ip"));
            sign_user.add_time = cursor.getString(cursor.getColumnIndex("add_time"));
            sign_user.add_user_name = cursor.getString(cursor.getColumnIndex("add_user_name"));
            sign_user.update_ip = cursor.getString(cursor.getColumnIndex("update_ip"));
            sign_user.update_time = cursor.getString(cursor.getColumnIndex("update_time"));
            sign_user.update_user_name = cursor.getString(cursor.getColumnIndex("update_user_name"));
            sign_user.SIGN_KEY = cursor.getString(cursor.getColumnIndex("SIGN_KEY"));
            sign_user.CAUSE = cursor.getString(cursor.getColumnIndex("CAUSE"));
            sign_user.eating_habits = cursor.getString(cursor.getColumnIndex("eating_habits"));
            sign_user.update = cursor.getInt(cursor.getColumnIndex("update"));
            sign_user.longitude = cursor.getString(cursor.getColumnIndex("longitude"));
            sign_user.latitude = cursor.getString(cursor.getColumnIndex("latitude"));
            sign_user.deviceid = cursor.getString(cursor.getColumnIndex("deviceid"));
//            MLog.e("test","当前解析对象:"+sign_user.toString());
            list.add(sign_user);
        }
        if (cursor!=null){
            cursor.close();
        }
        return list;
    }

    /**
     * 按照指定字段排序并解析出相应的任务列表
     */
    public List orderBYtask(int status,HashMap map,String condition) throws DbException {
        List list = new ArrayList<>();
        Cursor cursor;
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT * FROM teamtask WHERE status = '" + status+"'");
        for (Map.Entry entry:map.entrySet()) {
            sb.append("and "+entry.getKey()+"='"+entry.getValue()+"'");
        }
        if (condition.equals("update_time")){
            sb.append("ORDER BY update_time DESC");
//            cursor = MyApplication.db.execQuery("SELECT * FROM teamtask WHERE status = '" + status + "' and mid = '" + mid + "' and tuid = '" + tuid + "'ORDER BY update_time DESC");
        }
        if (condition.equals("endtime")){
            sb.append("ORDER BY endtime DESC");
//            cursor = MyApplication.db.execQuery("SELECT * FROM teamtask WHERE status = '" + status + "' and mid = '" + mid + "' and tuid = '" + tuid + "'ORDER BY endtime DESC");
        }
        MLog.e("test","MyDbBase log:当前sql语句-"+sb.toString());
        cursor = MyApplication.db.execQuery(sb.toString());
        if (cursor!=null){
            while (cursor.moveToNext()){//开始解析
                TeamTask teamTask = new TeamTask();
                teamTask._id = cursor.getInt(cursor.getColumnIndex("_id"));
                teamTask.tid = cursor.getInt(cursor.getColumnIndex("tid"));
                teamTask.mid = cursor.getInt(cursor.getColumnIndex("mid"));
                teamTask.parentid = cursor.getInt(cursor.getColumnIndex("parentid"));
                teamTask.tuid = cursor.getInt(cursor.getColumnIndex("tuid"));
                teamTask.creattuid = cursor.getInt(cursor.getColumnIndex("creattuid"));
                teamTask.typeid = cursor.getInt(cursor.getColumnIndex("typeid"));
                teamTask.startask = cursor.getInt(cursor.getColumnIndex("startask"));

                teamTask.title = cursor.getString(cursor.getColumnIndex("title"));
                teamTask.content = cursor.getString(cursor.getColumnIndex("content"));
                teamTask.attachment = cursor.getString(cursor.getColumnIndex("attachment"));
                teamTask.nickname = cursor.getString(cursor.getColumnIndex("nickname"));
                teamTask.creatnickname = cursor.getString(cursor.getColumnIndex("creatnickname"));
                teamTask.typename = cursor.getString(cursor.getColumnIndex("typename"));
                teamTask.starttime = cursor.getString(cursor.getColumnIndex("starttime"));
                teamTask.endtime = cursor.getString(cursor.getColumnIndex("endtime"));
                teamTask.mark = cursor.getString(cursor.getColumnIndex("mark"));
                teamTask.situation = cursor.getString(cursor.getColumnIndex("situation"));

                teamTask.delete_time = cursor.getString(cursor.getColumnIndex("delete_time"));
                teamTask.status = cursor.getInt(cursor.getColumnIndex("status"));
                teamTask.url = cursor.getString(cursor.getColumnIndex("url"));
                teamTask.referer_url = cursor.getString(cursor.getColumnIndex("referer_url"));
                teamTask.add_ip = cursor.getString(cursor.getColumnIndex("add_ip"));
                teamTask.add_time = cursor.getString(cursor.getColumnIndex("add_time"));
                teamTask.add_user_name = cursor.getString(cursor.getColumnIndex("add_user_name"));
                teamTask.update_ip = cursor.getString(cursor.getColumnIndex("update_ip"));
                teamTask.update_time = cursor.getString(cursor.getColumnIndex("update_time"));
                teamTask.update_user_name = cursor.getString(cursor.getColumnIndex("update_user_name"));
                teamTask.SIGN_KEY = cursor.getString(cursor.getColumnIndex("SIGN_KEY"));
                teamTask.CAUSE = cursor.getString(cursor.getColumnIndex("CAUSE"));
                list.add(teamTask);
            }
            cursor.close();
        }
        return list;
    }

    /**
     * 按照指定字段排序并解析出相应的任务列表
     */
    public List orderBYtaskstar(int status,int mid,int tuid,String condition) throws DbException {
        List list = new ArrayList<>();
        String strSql = "SELECT * FROM teamtask WHERE status = '" + status + "' and mid = '" + mid + "' and (tuid = '" + tuid + "' or ()ORDER BY update_time DESC";
        Cursor cursor= MyApplication.db.execQuery(strSql);
        MLog.e("test","MyDbBase log:当前sql语句-"+strSql);
        if (cursor!=null){
            while (cursor.moveToNext()){//开始解析
                TeamTask teamTask = new TeamTask();
                teamTask._id = cursor.getInt(cursor.getColumnIndex("_id"));
                teamTask.tid = cursor.getInt(cursor.getColumnIndex("tid"));
                teamTask.mid = cursor.getInt(cursor.getColumnIndex("mid"));
                teamTask.parentid = cursor.getInt(cursor.getColumnIndex("parentid"));
                teamTask.tuid = cursor.getInt(cursor.getColumnIndex("tuid"));
                teamTask.creattuid = cursor.getInt(cursor.getColumnIndex("creattuid"));
                teamTask.typeid = cursor.getInt(cursor.getColumnIndex("typeid"));
                teamTask.startask = cursor.getInt(cursor.getColumnIndex("startask"));

                teamTask.title = cursor.getString(cursor.getColumnIndex("title"));
                teamTask.content = cursor.getString(cursor.getColumnIndex("content"));
                teamTask.attachment = cursor.getString(cursor.getColumnIndex("attachment"));
                teamTask.nickname = cursor.getString(cursor.getColumnIndex("nickname"));
                teamTask.creatnickname = cursor.getString(cursor.getColumnIndex("creatnickname"));
                teamTask.typename = cursor.getString(cursor.getColumnIndex("typename"));
                teamTask.starttime = cursor.getString(cursor.getColumnIndex("starttime"));
                teamTask.endtime = cursor.getString(cursor.getColumnIndex("endtime"));
                teamTask.mark = cursor.getString(cursor.getColumnIndex("mark"));
                teamTask.situation = cursor.getString(cursor.getColumnIndex("situation"));

                teamTask.delete_time = cursor.getString(cursor.getColumnIndex("delete_time"));
                teamTask.status = cursor.getInt(cursor.getColumnIndex("status"));
                teamTask.url = cursor.getString(cursor.getColumnIndex("url"));
                teamTask.referer_url = cursor.getString(cursor.getColumnIndex("referer_url"));
                teamTask.add_ip = cursor.getString(cursor.getColumnIndex("add_ip"));
                teamTask.add_time = cursor.getString(cursor.getColumnIndex("add_time"));
                teamTask.add_user_name = cursor.getString(cursor.getColumnIndex("add_user_name"));
                teamTask.update_ip = cursor.getString(cursor.getColumnIndex("update_ip"));
                teamTask.update_time = cursor.getString(cursor.getColumnIndex("update_time"));
                teamTask.update_user_name = cursor.getString(cursor.getColumnIndex("update_user_name"));
                teamTask.SIGN_KEY = cursor.getString(cursor.getColumnIndex("SIGN_KEY"));
                teamTask.CAUSE = cursor.getString(cursor.getColumnIndex("CAUSE"));
                list.add(teamTask);
            }
            cursor.close();
        }
        return list;
    }

    /**
     * 按时间降序排序推送消息
     */
    public List orderBYMessage(String tuid){
        List list = new ArrayList<>();
        String sql = "SELECT * FROM message WHERE tuid = '"+tuid+"' and _id != '0' ORDER BY time DESC";
        MLog.e("test","当前sql语句:"+sql);
        try {
            Cursor cursor = MyApplication.db.execQuery(sql);
            if (cursor!=null){
                while (cursor.moveToNext()){
                    Message msg = new Message();
                    msg._id = cursor.getInt(cursor.getColumnIndex("_id"));
                    msg.tuid = cursor.getString(cursor.getColumnIndex("tuid"));
                    msg.time = cursor.getString(cursor.getColumnIndex("time"));
                    msg.title = cursor.getString(cursor.getColumnIndex("title"));
                    msg.content = cursor.getString(cursor.getColumnIndex("content"));
                    msg.isRead = cursor.getInt(cursor.getColumnIndex("isRead"));
                    list.add(msg);
                }
                cursor.close();
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * key: dbName
     */
    private final static HashMap DAO_MAP = new HashMap();

    private SQLiteDatabase database;
    private DaoConfig daoConfig;
    private boolean allowTransaction;

    private MyDbBase(DaoConfig config) {
        if (config == null) {
            throw new IllegalArgumentException("daoConfig may not be null");
        }
        this.daoConfig = config;
        this.allowTransaction = config.isAllowTransaction();
        this.database = openOrCreateDatabase(config);
        DbOpenListener dbOpenListener = config.getDbOpenListener();
        if (dbOpenListener != null) {
            dbOpenListener.onDbOpened(this);
        }
    }

    public synchronized static DbManager getInstance(DaoConfig daoConfig) {

        if (daoConfig == null) {//使用默认配置
            daoConfig = new DaoConfig();
        }

        MyDbBase dao = DAO_MAP.get(daoConfig);
        if (dao == null) {
            dao = new MyDbBase(daoConfig);
            DAO_MAP.put(daoConfig, dao);
        } else {
            dao.daoConfig = daoConfig;
        }

        // update the database if needed
        SQLiteDatabase database = dao.database;
        int oldVersion = database.getVersion();
        int newVersion = daoConfig.getDbVersion();
        if (oldVersion != newVersion) {
            if (oldVersion != 0) {
                DbUpgradeListener upgradeListener = daoConfig.getDbUpgradeListener();
                if (upgradeListener != null) {
                    upgradeListener.onUpgrade(dao, oldVersion, newVersion);
                } else {
                    try {
                        dao.dropDb();
                    } catch (DbException e) {
                        LogUtil.e(e.getMessage(), e);
                    }
                }
            }
            database.setVersion(newVersion);
        }

        return dao;
    }

    @Override
    public SQLiteDatabase getDatabase() {
        return database;
    }

    @Override
    public DaoConfig getDaoConfig() {
        return daoConfig;
    }

    //*********************************************** operations ********************************************************

    @Override
    public void saveOrUpdate(Object entity) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);
                for (Object item : entities) {
                    saveOrUpdateWithoutTransaction(table, item);
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                createTableIfNotExist(table);
                saveOrUpdateWithoutTransaction(table, entity);
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public void replace(Object entity) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, item));
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                createTableIfNotExist(table);
                execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, entity));
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public void save(Object entity) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, item));
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                createTableIfNotExist(table);
                execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public boolean saveBindingId(Object entity) throws DbException {
        boolean result = false;
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return false;
                TableEntity table = this.getTable(entities.get(0).getClass());
                createTableIfNotExist(table);
                for (Object item : entities) {
                    if (!saveBindingIdWithoutTransaction(table, item)) {
                        throw new DbException("saveBindingId error, transaction will not commit!");
                    }
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                createTableIfNotExist(table);
                result = saveBindingIdWithoutTransaction(table, entity);
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
        return result;
    }

    @Override
    public void deleteById(Class entityType, Object idValue) throws DbException {
        TableEntity table = this.getTable(entityType);
        if (!table.tableIsExist()) return;
        try {
            beginTransaction();

            execNonQuery(SqlInfoBuilder.buildDeleteSqlInfoById(table, idValue));

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public void delete(Object entity) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                if (!table.tableIsExist()) return;
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildDeleteSqlInfo(table, item));
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                if (!table.tableIsExist()) return;
                execNonQuery(SqlInfoBuilder.buildDeleteSqlInfo(table, entity));
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public void delete(Class entityType) throws DbException {
        delete(entityType, null);
    }

    @Override
    public int delete(Class entityType, WhereBuilder whereBuilder) throws DbException {
        TableEntity table = this.getTable(entityType);
        if (!table.tableIsExist()) return 0;
        int result = 0;
        try {
            beginTransaction();

            result = executeUpdateDelete(SqlInfoBuilder.buildDeleteSqlInfo(table, whereBuilder));

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
        return result;
    }

    @Override
    public void update(Object entity, String... updateColumnNames) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List entities = (List) entity;
                if (entities.isEmpty()) return;
                TableEntity table = this.getTable(entities.get(0).getClass());
                if (!table.tableIsExist()) return;
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, item, updateColumnNames));
                }
            } else {
                TableEntity table = this.getTable(entity.getClass());
                if (!table.tableIsExist()) return;
                execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, entity, updateColumnNames));
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

    @Override
    public int update(Class entityType, WhereBuilder whereBuilder, KeyValue... nameValuePairs) throws DbException {
        TableEntity table = this.getTable(entityType);
        if (!table.tableIsExist()) return 0;

        int result = 0;
        try {
            beginTransaction();

            result = executeUpdateDelete(SqlInfoBuilder.buildUpdateSqlInfo(table, whereBuilder, nameValuePairs));

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }

        return result;
    }

    @Override
    @SuppressWarnings("unchecked")
    public  T findById(Class entityType, Object idValue) throws DbException {
        return null;
    }

    @Override
    public  T findFirst(Class entityType) throws DbException {
        return this.selector(entityType).findFirst();
    }

    @Override
    public  List findAll(Class entityType) throws DbException {
        return this.selector(entityType).findAll();
    }

    @Override
    public  Selector selector(Class entityType) throws DbException {
        return null;
    }

    @Override
    public DbModel findDbModelFirst(SqlInfo sqlInfo) throws DbException {
        return null;
    }

    @Override
    public List findDbModelAll(SqlInfo sqlInfo) throws DbException {
        return null;
    }

    //******************************************** config ******************************************************

    private SQLiteDatabase openOrCreateDatabase(DaoConfig config) {
        SQLiteDatabase result = null;

        File dbDir = config.getDbDir();
        if (dbDir != null && (dbDir.exists() || dbDir.mkdirs())) {
            File dbFile = new File(dbDir, config.getDbName());
            result = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
        } else {
            result = x.app().openOrCreateDatabase(config.getDbName(), 0, null);
        }
        return result;
    }

    //***************************** private operations with out transaction *****************************
    private void saveOrUpdateWithoutTransaction(TableEntity table, Object entity) throws DbException {
        ColumnEntity id = table.getId();
        if (id.isAutoId()) {
            if (id.getColumnValue(entity) != null) {
                execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, entity));
            } else {
                saveBindingIdWithoutTransaction(table, entity);
            }
        } else {
            execNonQuery(SqlInfoBuilder.buildReplaceSqlInfo(table, entity));
        }
    }

    private boolean saveBindingIdWithoutTransaction(TableEntity table, Object entity) throws DbException {
        ColumnEntity id = table.getId();
        if (id.isAutoId()) {
            execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
            long idValue = getLastAutoIncrementId(table.getName());
            if (idValue == -1) {
                return false;
            }
            id.setAutoIdValue(entity, idValue);
            return true;
        } else {
            execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
            return true;
        }
    }

    //************************************************ tools ***********************************

    private long getLastAutoIncrementId(String tableName) throws DbException {
        long id = -1;
        Cursor cursor = execQuery("SELECT seq FROM sqlite_sequence WHERE name='" + tableName + "' LIMIT 1");
        if (cursor != null) {
            try {
                if (cursor.moveToNext()) {
                    id = cursor.getLong(0);
                }
            } catch (Throwable e) {
                throw new DbException(e);
            } finally {
                IOUtil.closeQuietly(cursor);
            }
        }
        return id;
    }

    @Override
    public void close() throws IOException {
        if (DAO_MAP.containsKey(daoConfig)) {
            DAO_MAP.remove(daoConfig);
            this.database.close();
        }
    }

    ///////////////////////////////////// exec sql /////////////////////////////////////////////////////

    private void beginTransaction() {
        if (allowTransaction) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && database.isWriteAheadLoggingEnabled()) {
                database.beginTransactionNonExclusive();
            } else {
                database.beginTransaction();
            }
        }
    }

    private void setTransactionSuccessful() {
        if (allowTransaction) {
            database.setTransactionSuccessful();
        }
    }

    private void endTransaction() {
        if (allowTransaction) {
            database.endTransaction();
        }
    }


    @Override
    public int executeUpdateDelete(SqlInfo sqlInfo) throws DbException {
        SQLiteStatement statement = null;
        try {
            statement = sqlInfo.buildStatement(database);
            return statement.executeUpdateDelete();
        } catch (Throwable e) {
            throw new DbException(e);
        } finally {
            if (statement != null) {
                try {
                    statement.releaseReference();
                } catch (Throwable ex) {
                    LogUtil.e(ex.getMessage(), ex);
                }
            }
        }
    }

    @Override
    public int executeUpdateDelete(String sql) throws DbException {
        SQLiteStatement statement = null;
        try {
            statement = database.compileStatement(sql);
            return statement.executeUpdateDelete();
        } catch (Throwable e) {
            throw new DbException(e);
        } finally {
            if (statement != null) {
                try {
                    statement.releaseReference();
                } catch (Throwable ex) {
                    LogUtil.e(ex.getMessage(), ex);
                }
            }
        }
    }

    @Override
    public void execNonQuery(SqlInfo sqlInfo) throws DbException {
        SQLiteStatement statement = null;
        try {
            statement = sqlInfo.buildStatement(database);
            statement.execute();
        } catch (Throwable e) {
            throw new DbException(e);
        } finally {
            if (statement != null) {
                try {
                    statement.releaseReference();
                } catch (Throwable ex) {
                    LogUtil.e(ex.getMessage(), ex);
                }
            }
        }
    }

    @Override
    public void execNonQuery(String sql) throws DbException {
        try {
            database.execSQL(sql);
        } catch (Throwable e) {
            throw new DbException(e);
        }
    }

    @Override
    public Cursor execQuery(SqlInfo sqlInfo) throws DbException {
        try {
            return database.rawQuery(sqlInfo.getSql(), sqlInfo.getBindArgsAsStrArray());
        } catch (Throwable e) {
            throw new DbException(e);
        }
    }

    @Override
    public Cursor execQuery(String sql) throws DbException {
        try {
            return database.rawQuery(sql, null);
        } catch (Throwable e) {
            throw new DbException(e);
        }
    }

}
使用的时候:

MyDbBase.getInstance().creatTable(new Test());
上面的类里面我还封装了几个数据库排序的方法以及解析过程,xutils3也有提供数据库排序方法,下文有介绍,不过有的时候一些复杂的查询语句还是要自己封装一下比较好。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来我就一一介绍xutils3数据库的增删改查。

1:增

/**  * 保存实体类或实体类的List到数据库,  * 如果该类型的id是自动生成的, 则保存完后会给id赋值.  *  * @param entity  * @return  * @throws DbException  */ boolean saveBindingId(Object entity) throws DbException;

/**  * 保存或更新实体类或实体类的List到数据库, 根据id对应的数据是否存在.  *  * @param entity  * @throws DbException  */ void saveOrUpdate(Object entity) throws DbException;

/**  * 保存实体类或实体类的List到数据库  *  * @param entity  * @throws DbException  */ void save(Object entity) throws DbException;

/**  * 保存或更新实体类或实体类的List到数据库, 根据id和其他唯一索引判断数据是否存在.  *  * @param entity  * @throws DbException  */ void replace(Object entity) throws DbException;

这是xutils3给出的注解,看似很详细,但是真当你用起来的时候可能会出现各种不想看到的问题;经过小弟的各种尝试,结论如下:

如果在你建表的时候你的主键设置成自增长,那么你在插入数据的时候直接调replace方法就可以了,但是saveOrUpdate只能达到插入的效果,达不到更新原有数据的效果

如果在你建表的时候你的主键设置成不是自增长,replace方法当然可以插入,saveOrUpdate方法既可以插入也可以达到更新的效果,当然这里要注意的是在你更新的时候你的主键要对应的上。其他几个插入的方法我在实战的时候我并没有使用过,小弟介绍的两个方法已经够自己使用了。

2:删

void delete(Object entity) throws DbException;
这个就没什么好介绍的啦,你想删除数据里的哪条数据,直接把对象放进去就OK了,这里也可以传入一个List 进行批量删除。

3:改

void update(Object entity, String... updateColumnNames) throws DbException;
这里需要注意的是:如果你拿到一个新的对象,你想更新里面所有的字段值,那就直接把对象放进去(你放进去的对象的主键一定要和你本地数据库需要更新德尔那个对象的主键保持一致,如果这个对象没有主键一定需要赋值,不然会抛异常,xutils3所有的数据库操作除了单纯的插入,其他都需要有主键才能进行的,话说sqlite都一样啊,我这里只是友情提示一下),后面的可变长度的参数不赋值就好;如果你只想更新部分字段那你只需要这么操作,这里也可以传入一个List 进行批量更新。

String[] s = {"column2","column3"};
MyApplication.db.update(test1,s);//这样就能达到只更新两个字段值得效果
4:查

<T> Selector<T> selector(Class<T> entityType) throws DbException;
xutils3的查询数据库的操作采用了经典的建造者模式,使用起来非常方便,事例如下:

try {
    List all = MyApplication.db.selector(Test.class).findAll();//查询这张表里面所有的数据,返回一个list
} catch (DbException e) {
    e.printStackTrace();
}
try {
    Test first = MyApplication.db.selector(Test.class).findFirst();//查询这张表里面的第一条数据
} catch (DbException e) {
    e.printStackTrace();
}
try {
    List all = MyApplication.db.selector(Test.class).where("column1","=","value1").and("column2", "=","value2").and("column3", "!=","value3").findAll();//多重条件查询
} catch (DbException e) {
    e.printStackTrace();
}

关于WhereBuilder这个类,是可以写一些更复杂的查询条件,有些条件语句需要用()这个括起来的,这个时候就需要用到WhereBuilder去进行组合语句的构建;

WhereBuilder whereBuilder = WhereBuilder.b("title", "like", "%"+str_screen+"%");
whereBuilder.or("creatnickname","like","%"+str_screen+"%");
List all = MyApplication.db.selector(Test.class).where(whereBuilder).findAll();

排序字段的方法:

MyApplication.db.selector(TeamTask.class).where("status", "=", 0).and("mid", "=",Config.mid).and("tuid","=",Config.tuid).and(whereBuilder).orderBy("time",true).findAll();
这个就是排序time字段,第二个参数是是否DESC,true就是desc,false就是ASC


xutils3还提供了很多有用的接口,比如如果你想在框架上加些源生的sql语句,你可以这么干:

void execNonQuery(SqlInfo sqlInfo) throws DbException;

void execNonQuery(String sql) throws DbException;

Cursor execQuery(SqlInfo sqlInfo) throws DbException;

Cursor execQuery(String sql) throws DbException;
自己写的sql经常会出错,不过没关系,你可以在抓异常里面打断点或log,看下原因即可,其实他抛出的这些接口你查看源码就知道些的其实很简单调的就是源生的sqlite方法
@Override
public void execNonQuery(String sql) throws DbException {
    try {
        database.execSQL(sql);
    } catch (Throwable e) {
        throw new DbException(e);
    }
}
基本的使用大概就这些了,如果小弟还遇到什么有趣的我会再更新的,最后献上神兽镇楼!祝大家生活愉快

/**  *  ┏┓   ┏┓  * ┏┛┻━━━┛┻┓  * ┃       ┃  * ┃   ━   ┃  * ┃ ┳┛ ┗┳ ┃  * ┃       ┃  * ┃   ┻   ┃  * ┃       ┃  * ┗━┓   ┏━┛  *   ┃   ┃神兽保佑  *   ┃   ┃代码无BUG!  *   ┃   ┗━━━┓  *   ┃       ┣┓  *   ┃       ┏┛  *   ┗┓┓┏━┳┓┏┛  *    ┃┫┫ ┃┫┫  *    ┗┻┛ ┗┻┛  */






你可能感兴趣的:(xutils3框架之数据库使用详解!)