精华内容
下载资源
问答
  • OrmLite数据库

    2017-06-16 15:36:05
    Android开发涉及到的数据库采用的是轻量级的SQLite3,一搬会选择第三方,而这里我选择ORMLite数据库,在开发中数据库表的设计往往不是一开始就非常完美,可能在应用版本开发迭代中,表的结构也需要调整,最常见的...

    一:升级

    概述

    Android开发涉及到的数据库采用的是轻量级的SQLite3,一搬会选择第三方,而这里我选择ORMLite数据库,在开发中数据库表的设计往往不是一开始就非常完美,可能在应用版本开发迭代中,表的结构也需要调整,最常见的就是修改表里的字段(新增字段),那么在版本升级的时候往往要保留用户之前的数据,这时候就涉及到数据库升级的问题了。

    数据库升级

    数据库升级,主要有以下这几种情况:

    1. 删除表。
    2. 增加表。
    3. 修改表。 
      1. 增加表字段
      2. 删除表字段

    增加表和删除表问题不大,因为它们都没有涉及到数据的迁移问题,增加表只是在原来的基础上CRTATE TABLE,而删除表就是对历史数据不需要了,那只要DROP TABLE即可。那么修改表呢?

    其实,很多时候,程序员为了图个方便,最简单最暴力的方法就是,将原来的表删除了然后重新创建新的表,这样就不用考虑其他因素了。但这样对于用户来说,体验是非常不好的,比如:用户当前下载列表正在下载文件,此时进行更新,而新版本有个更新点是升级了下载列表的数据库表,那么用户更新完之后发现下载列表变空了,那么用户看到辛辛苦苦下载的99%文件.avi没来,那不崩溃了,这种体验是非常不好的,分分钟就卸载你的应用。

    那么数据库表升级时,数据迁移就显得非常重要了,那么如何实现呢?

    表升级,数据迁移

    现在开发,为了效率,都会使用第三方,本文数据库方面是基于ORMLite的,所以接下来讨论的都是基于此。

    1 -> 2 -> 3 
    A A+ A 
    B B- B 
    C C C+ 
    上表的意思是:版本升级从版本号1升级到2再升级到3,1->2->3,期间表ABC的变化,‘+’表示该表增加了字段,‘-’表示该表删除了字段,例如1升级到2,表A增加了字段,表B删除了字段,表C没有发生变化。

    首先,我们要先理解SQLiteOpenHelper中

    /**
         * Called when the database is created for the first time. This is where the
         * creation of tables and the initial population of the tables should happen.
         *
         * @param db The database.
         */
        public abstract void onCreate(SQLiteDatabase db);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    /**
         * Called when the database needs to be upgraded. The implementation
         * should use this method to drop tables, add tables, or do anything else it
         * needs to upgrade to the new schema version.
         * @param db The database.
         * @param oldVersion The old database version.
         * @param newVersion The new database version.
         */
        public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    什么时候调用。文档说得很清楚了,onCreate()是数据库第一次创建的时候调用,而onUpgrade()是当数据库版本升级的时候调用。

    首先,先简单的创建A、B、C三个类,并使用OrmLite注解来创建表

    A.class

    import com.j256.ormlite.field.DatabaseField;
    import com.j256.ormlite.table.DatabaseTable;
    
    @DatabaseTable(tableName = "tb_a")
    public class A {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    B.class

    import com.j256.ormlite.field.DatabaseField;
    import com.j256.ormlite.table.DatabaseTable;
    
    @DatabaseTable(tableName = "tb_b")
    public class B {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
        @DatabaseField
        public String age;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    C.class

    import com.j256.ormlite.field.DatabaseField;
    import com.j256.ormlite.table.DatabaseTable;
    
    @DatabaseTable(tableName = "tb_c")
    public class C {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建自己的Helper的MySqliteHelper.class

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
    import com.j256.ormlite.support.ConnectionSource;
    import com.j256.ormlite.table.TableUtils;
    import java.sql.SQLException;
    
    public class MySqliteHelper extends OrmLiteSqliteOpenHelper{
        private final static String DATABASE_NAME="test.db";
        private final static int DATABASE_VERSION = 1;
    
        private static MySqliteHelper mInstance;
    
        public MySqliteHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    
        public static MySqliteHelper getInstance(Context context) {
            if (mInstance == null) {
                mInstance= new MySqliteHelper(context);
            }
            return mInstance;
        }
        @Override
        public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
            try {
                TableUtils.createTableIfNotExists(connectionSource,A.class);
                TableUtils.createTableIfNotExists(connectionSource,B.class);
                TableUtils.createTableIfNotExists(connectionSource,C.class);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
    
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    创建数据操作的Dao

    import android.content.Context;
    import com.j256.ormlite.dao.Dao;
    import java.sql.SQLException;
    
    public class ADao {
        private Dao<A,Integer> dao;
        public ADao(Context context){
            try {
                dao = MySqliteHelper.getInstance(context).getDao(A.class);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    BDao、CDao,也类似。 
    运行程序,进行Dao操作,此时就创建数据库test.db,进而执行onCreate()创建表。

    import android.app.Application;
    import android.test.ApplicationTestCase;
    import android.test.suitebuilder.annotation.MediumTest;
    
    import com.helen.andbase.demolist.db.A;
    import com.helen.andbase.demolist.db.ADao;
    
    
    public class ApplicationTest extends ApplicationTestCase<Application> {
        public ApplicationTest() {
            super(Application.class);
        }
    
        @MediumTest
        public void testDao(){
            ADao aDao = new ADao(getContext());
            A a = new A();
            a.name="a";
            aDao.add(a);
    
            BDao bDao = new BDao(getContext());
            B b = new B();
            b.name="a";
            b.age ="18";
            bDao.add(b);
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    这里写图片描述

    将其拷出来,查看数据库。这里使用SQLiteExpertPers进行查看

    这里写图片描述

    这里写图片描述 
    如上图表已创建。接着我们进行数据库升级,将版本号DATABASE_VERSION变为2,表A新增字段age,表B删除字段age,C不变

    @DatabaseTable(tableName = "tb_a")
    public class A {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
        @DatabaseField
        public String age;
    }
    
    @DatabaseTable(tableName = "tb_b")
    public class B {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
    }
    
    @DatabaseTable(tableName = "tb_c")
    public class C {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    简单暴力的解决方法是:

    @Override
        public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
            if(oldVersion < 2){//暂不说明为何要这么判断
                try {
                    TableUtils.dropTable(connectionSource,A.class,true);
                    TableUtils.dropTable(connectionSource,B.class,true);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            onCreate(db,connectionSource);
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    先将旧的表删除再创建新的表,这是最简单暴力的,但前面提过这不是我们想要的结果。

    将代码改下,

    @Override
        public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
            if(oldVersion < 2){//暂不说明为何要这么判断
                DatabaseUtil.upgradeTable(db,connectionSource,A.class,DatabaseUtil.OPERATION_TYPE.ADD);
            }
            onCreate(db,connectionSource);
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    主要的代码就是封装的DatabaseUtil.class这个类

    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    import com.j256.ormlite.misc.JavaxPersistence;
    import com.j256.ormlite.support.ConnectionSource;
    import com.j256.ormlite.table.DatabaseTable;
    import com.j256.ormlite.table.TableUtils;
    
    import java.util.Arrays;
    
    public class DatabaseUtil {
        public static final String TAG = "DatabaseUtil.java";
        /**数据库表操作类型*/
        public enum OPERATION_TYPE{
            /**表新增字段*/
            ADD,
            /**表删除字段*/
            DELETE
        }
        /**
         * 升级表,增加字段
         * @param db
         * @param clazz
         */
        public static <T> void upgradeTable(SQLiteDatabase db,ConnectionSource cs,Class<T> clazz,OPERATION_TYPE type){
            String tableName = extractTableName(clazz);
    
            db.beginTransaction();
            try {
    
                //Rename table
                String tempTableName = tableName + "_temp";
                String sql = "ALTER TABLE "+tableName+" RENAME TO "+tempTableName;
                db.execSQL(sql);
    
                //Create table
                try {
                    sql = TableUtils.getCreateTableStatements(cs, clazz).get(0);
                    db.execSQL(sql);
                } catch (Exception e) {
                    e.printStackTrace();
                    TableUtils.createTable(cs, clazz);
                }
    
                //Load data
                String columns;
                if(type == OPERATION_TYPE.ADD){
                    columns = Arrays.toString(getColumnNames(db,tempTableName)).replace("[","").replace("]","");
                }else if(type == OPERATION_TYPE.DELETE){
                    columns = Arrays.toString(getColumnNames(db,tableName)).replace("[","").replace("]", "");
                }else {
                    throw new IllegalArgumentException("OPERATION_TYPE error");
                }
                sql = "INSERT INTO "+tableName +
                        " ("+ columns+") "+
                        " SELECT "+ columns+" FROM "+tempTableName;
                db.execSQL(sql);
    
                //Drop temp table
                sql = "DROP TABLE IF EXISTS "+tempTableName;
                db.execSQL(sql);
    
                db.setTransactionSuccessful();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                db.endTransaction();
            }
        }
    
    
        /**
         * 获取表名(ormlite DatabaseTableConfig.java)
         * @param clazz
         * @param <T>
         * @return
         */
        private static <T> String extractTableName(Class<T> clazz) {
            DatabaseTable databaseTable = clazz.getAnnotation(DatabaseTable.class);
            String name ;
            if (databaseTable != null && databaseTable.tableName() != null && databaseTable.tableName().length() > 0) {
                name = databaseTable.tableName();
            } else {
                /*
                 * NOTE: to remove javax.persistence usage, comment the following line out
                 */
                name = JavaxPersistence.getEntityName(clazz);
                if (name == null) {
                    // if the name isn't specified, it is the class name lowercased
                    name = clazz.getSimpleName().toLowerCase();
                }
            }
            return name;
        }
    
        /**
         * 获取表的列名
         * @param db
         * @param tableName
         * @return
         */
        private static String[] getColumnNames(SQLiteDatabase db,String tableName){
            String[] columnNames = null;
            Cursor cursor = null;
            try {
                cursor = db.rawQuery("PRAGMA table_info("+tableName+")",null);
                if(cursor != null){
                    int columnIndex = cursor.getColumnIndex("name");
                    if(columnIndex == -1){
                        return null;
                    }
    
                    int index = 0;
                    columnNames = new String[cursor.getCount()];
                    for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
                        columnNames[index] = cursor.getString(columnIndex);
                        index++;
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(cursor != null) {
                    cursor.close();
                }
            }
            return columnNames;
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130

    upgradeTable方法里采用的是数据库事务,利用事务的原子特性,保证所有的SQL能全部执行完成。主要思路是:首先将原来的表进行改名称rename table(临时表),接着创建新的表create table,再者将旧表内的数据迁移到新表内,最后drop table删除临时表。

    表的增加字段和删除字段,在迁移数据的时候,主要区别在于字段的来源不同。比如:A表新增了age字段,这时候columns变量的获取是根据旧表来的,这是构造的sql语句是

    sql = "INSERT INTO tb_a (id,name) SELECT id,name FROM tb_a_temp";
    • 1
    • 1

    而B表是删除age字段的,columns变量的获取是根据新表来的,其构造的sql语句是

    sql = "INSERT INTO tb_b (id) SELECT id FROM tb_b_temp";
    • 1
    • 1

    再次执行ApplicationTest->testDao

    @MediumTest
        public void testDao(){
            ADao aDao = new ADao(getContext());
            A a = new A();
            a.name="a";
            a.age = "20";
            aDao.add(a);
    
            BDao bDao = new BDao(getContext());
            B b = new B();
            b.name="b";
            bDao.add(b);
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    再查看下数据 

    可以看到表A、表B的历史数据还是存在的。

    然后我们再将数据库升级到版本号为3,这时候要考虑到用户的多种情况,从1->3,从2->3这两种情况,但不是每次升级都重复之前的操作的,比如用户1之前已经从1升级到2了,这次是要从2升级到3,而用户2,一直用的是老版本1,他觉得,嗯,这次这个版本升级的内容不错,决定升级了,那么他是从1直接升级到3的,所以他们两者经历的版本不一样,数据库升级的策略也会有所不用,那就要区分开来考虑了。

    这次的升级是将表C添加了sex字段

    import com.j256.ormlite.field.DatabaseField;
    import com.j256.ormlite.table.DatabaseTable;
    
    @DatabaseTable(tableName = "tb_c")
    public class C {
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
        @DatabaseField
        public String sex;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    然后在onUpgrade进行逻辑判断

     @Override
        public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
            if(oldVersion < 2){
                DatabaseUtil.upgradeTable(db,connectionSource,A.class,DatabaseUtil.OPERATION_TYPE.ADD);
                DatabaseUtil.upgradeTable(db,connectionSource,B.class,DatabaseUtil.OPERATION_TYPE.DELETE);
            }
            if(oldVersion < 3){
                DatabaseUtil.upgradeTable(db,connectionSource,C.class,DatabaseUtil.OPERATION_TYPE.ADD);
            }
            onCreate(db,connectionSource);
        }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这样,如果你是从1升级到3,那么两个if语句都会执行,而如果是从2升级到3,那么只有if(oldVersion < 3)这个分支会执行。最后,如果只是新增全新的表D,那么只要在onCreate内多写句TableUtils.createTableIfNotExists(connectionSource, D.class);就可以啦,不要忘记版本号要+1~

    总结

    本文讨论的数据迁移,是基于新旧两个表之间逻辑性不强,不牵涉到业务情景的情况下。比如,表A新增的字段user_id为用户id,这个字段是用来标记数据来源于哪个用户的,检索的时候,user_id是用于检索条件的,那么由于旧数据转移到新表中user_id默认是空的,这时候旧数据可能相当于不起作用了,虽然可以通过设置默认值,但其需要根据具体业务场景进行设置,因此就失去其灵活性了。

    展开全文
  • ORMlite数据库

    2019-10-11 20:52:24
    ORMlite基本使用依赖表类构造表具体实现 基本使用 依赖 implementation 'com.j256.ormlite:ormlite-android:5.0' implementation 'com.j256.ormlite:ormlite-core:5.0' 表类 @DatabaseTable(tableName = "t_user")...

    基本使用

    依赖

    implementation 'com.j256.ormlite:ormlite-android:5.0'
    implementation 'com.j256.ormlite:ormlite-core:5.0'
    

    表类

    @DatabaseTable(tableName = "t_user")class UserDb {
    
        @DatabaseField(generatedId = true) var id: Int = 0
        @DatabaseField(columnName = "name")  var name: String? = null
        @DatabaseField(columnName = "phone") var phone: String? = null
        
    }
    

    构造表

    class TakeoutOpetHelper(val context: Context) : OrmLiteSqliteOpenHelper(context,"takeout_kotlin.db",null,1){
        override fun onCreate(database: SQLiteDatabase?, connectionSource: ConnectionSource?) {
            TableUtils.createTable(connectionSource,UserDb::class.java)
        }
    
        override fun onUpgrade(
            database: SQLiteDatabase?,
            connectionSource: ConnectionSource?,
            oldVersion: Int,
            newVersion: Int
        ) {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
    
    
    }
    

    具体实现

    
                    //缓存到数据库中
                    val takeoutOpetHelper =  TakeoutOpetHelper(loginActivity)
                    val userDao : Dao<UserDb,Int> = takeoutOpetHelper.getDao(UserDb::class.java)
                    val userdb = UserDb()
                    userdb.name = “张三”
                    userdb.phone =123456789//添加
    				userDao.create(userdb)
    
    展开全文
  • Ormlite数据库

    2019-02-23 09:55:00
    1. Ormlite是什么? Android原生操作数据库的方式是这样的: 首先定义一个类继承SQLiteOpenHelper,重写onCreate和onUpdate 后续对数据库的增删改查以及创建和销毁都需要操作相对比较底层的sql语句,难以记忆又...

    1. Ormlite是什么?

    • Android原生操作数据库的方式是这样的: 
    • 首先定义一个类继承SQLiteOpenHelper,重写onCreate和onUpdate
    • 后续对数据库的增删改查以及创建和销毁都需要操作相对比较底层的sql语句,难以记忆又容易出错
    • 而且操作sql语句代码量多,sql语句的逻辑比较繁琐
    • 而Java是面向对象的语言,有没有一种方式可以让我们不去关心sql语句的编写,直接面向对象;我们操作对象就间接操作了数据库。那么orm数据库框架就是帮助我们完成这个事,并且能够将javabean和数据库的表映射起来,javabean的字段就是表的字段。这就是为什么叫o(对象)r(关系)m(映射)的原因。
    • Ormlite就是一个orm数据库框架之一。

    2. 为什么选择Ormlite?

    Andorid平台的orm数据库框架有很多:比如greenDao,DBFlow,Relm等,甚至xutil,afinal;每个orm框架各有优缺点,而Ormlite使用起来非常容易上手,效率也还不错,所以我们选择它作为学习的对象。试想想,如果一个类库光配置就需要搞一天,你还会有心情用它么?

    3. Ormlite如何使用?

    • 准备工作:引入相关jar包
    • 首先,定义类继承OrmLiteSqliteOpenHelper:
    public class MyDbhepler extends OrmLiteSqliteOpenHelper {
        private static final String TAG = "MyDbhepler";
    
        public MyDbhepler(Context context) {
            super(context, "ngyb.db", null, 1);
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
            try {
                Log.e(TAG, "onCreate: ");
                TableUtils.createTable(connectionSource, Student.class);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int i, int i1) {
    
        }
    }
    • 其次,编写javabean,通过注解配置和表的映射关系:
    @DatabaseTable(tableName = "student")
    public class Student {
        public Student() {
            //javabean 一定要创建一个无参数的构造
        }
    
        public Student(String name) {
            this.name = name;
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @DatabaseField(generatedId = true)
        public int id;
        @DatabaseField
        public String name;
        @DatabaseField
        public int age;
    
        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    • 最后,调用dao类的对应方法,直接操作对象,即可完成增删改查:
            MyDbhepler myDbhepler = new MyDbhepler(getApplicationContext());
            try {
                Dao<Student, Integer> dao = myDbhepler.getDao(Student.class);
                Log.e(TAG, "onCreate: ");
                dao.create(new Student("ngyb", 18));
    //            Student student = dao.queryForId(0);
                Student student = dao.queryForAll().get(0);
                if (student != null) {
                    student.name = "ltz";
                    student.age = 23;
                    dao.update(student);
                }
                //            dao.deleteById(3);
                List<Student> students = dao.queryForAll();
                for (Student student1 : students) {
                    Log.e(TAG, "onCreate: " + student1.toString());
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

     

    }

     

    转载于:https://www.cnblogs.com/nangongyibin/p/10421708.html

    展开全文
  • Android Ormlite数据库使用,包含基本的增删改差操作,比起SQLite更加简单,没有频繁的数据库,查询语言,不了解的小伙伴可以先了解一下Ormlite数据库的简介http://www.jianshu.com/p/05782b598cf0
  • ormlite数据库的简单应用
  • ormLite数据库框架jar包

    2017-09-16 15:59:28
    ormLite数据库jar包,里面有4个文件,ormlite-android-4.48.jar、ormlite-android-5.0.jar、ormlite-core-4.48.jar、ormlite-core-5.0.jar
  • 在android中使用数据库,这里用的是Ormlite数据库。更加符合android的编码形式,用起来方便简单
  • OrmLite 数据库使用大全

    千次阅读 2018-04-23 08:58:34
    本文介绍OrmLite数据库表的使用以及在项目中选择他的原因。 1. 选用 OrmLite 数据库的原因 目前用的最多的就是GreenDAO 和 OrmLite 了,两者各有优缺点。 GreenDAO 性能高,号称Android最快的关系型...

    本文介绍OrmLite的数据库表的使用以及在项目中选择他的原因。

    1. 选用 OrmLite 数据库的原因

    目前用的最多的就是GreenDAO 和 OrmLite 了,两者各有优缺点。

    GreenDAO

    性能高,号称Android最快的关系型数据库;内存占用较小;支持数据库加密;

    OrmLite

    通过注解和反射将对象映射到数据库中的表,效率上相对来说,低些(实测,感觉还可以);相对GreenDAO 使用起来比较方便;

    两者都是ORM(对象关系数据库);下面是从其他网站上盗用的一张图

    这里写图片描述

    2. 如何使用

    2.1. 下载jar包

    可以到官网去下载ormlite的jar包 下载地址
    我这里使用的是ormlite-core-5.0.jar 和 ormlite-android-5.0.jar

    2.2. 创建数据库管理类(DatabaseHelper.java)
    final class DatabaseHelper extends OrmLiteSqliteOpenHelper {
    
        private static final String TABLE_NAME = SDCardUtils.getDbPath();
        // any time you make changes to your database objects, you may have to increase the database version
        private static final int DATABASE_VERSION = 6;
    
        private static final Class<?>[] tableClasses = new Class[]{
            Account.class
        };
    
    
        private Map<String, Dao> daos = new HashMap<String, Dao>();
    
        private static DatabaseHelper instance;
    
    
        private DatabaseHelper(Context context) {
            super(context, TABLE_NAME, null, DATABASE_VERSION);
        }
        /** context:上下文对象   
          * DATABASE_NAME:数据库名称
          * factory:游标工厂  
          * DATABASE_VERSION:数据库版本号
          */
        public DatabaseHelper(Context context, String databaseName, SQLiteDatabase.CursorFactory factory, int databaseVersion, File configFile) {
            super(context, TABLE_NAME, null, DATABASE_VERSION);
        }
    
    
        /**
         * 单例获取该Helper
         * @return return
         */
        public static synchronized DatabaseHelper getInstance() {
            if (instance == null) {
                synchronized (DatabaseHelper.class) {
                    if (instance == null) {
                        instance = new DatabaseHelper(MainApp.getInstance());
                    }
                }
            }
            return instance;
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
            try {
                for (Class<?> clazz : tableClasses) {
                    TableUtils.createTable(connectionSource, clazz);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int i, int i1) {
            try {
                for (Class<?> clazz : tableClasses) {
                    TableUtils.dropTable(connectionSource, clazz,true);
                }
                onCreate(sqLiteDatabase,connectionSource);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        public synchronized Dao getDao(Class clazz) {
            Dao dao = null;
            String className = clazz.getSimpleName();
            if (daos.containsKey(className)) {
                dao = daos.get(className);
            }
            if (dao == null) {
                try {
                    dao = super.getDao(clazz);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                daos.put(className, dao);
            }
            return dao;
        }
     }
    2.3. 创建表结构(相应的实体类Account.java)
    @DatabaseTable(tableName = "accounts")
    public class Account {
    
        @DatabaseField(id = true)
        private String name;
        @DatabaseField
        private String password;
    
        public Account() {
            // ORMLite needs a no-arg constructor 
        }
        public Account(String name, String password) {
            this.name = name;
            this.password = password;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }

    注解

    @DatabaseTable: 表明是一张表,表明默认为类名小写,也可以通过 tableName 指定 @DatabaseTable(tableName = "AccountTable")
    @DatabaseField: 表明是表中的一个字段,默认为变量名小写,也可以通过columnName 指定@DatabaseField(columnName=""|generatedId=true|foreign=true|foreignColumnName="")分别可指定表中字段名、该字段是否为主键、是否为外键、关联表的外键名; 也可以这样指定主键 @DatabaseField(id = true)

    变量含义
    这里写图片描述

    2.4. 创建DAO(相应的实体类AccountDAO.java)

    AccountDAO 中通过相应的Dao 条用 update create delete query 方法操作数据库,也可以拿到相应的updateBuilder deleteBuilder queryBuilder 之后再操作数据库;两种方法的区别是拿到相应的Builder 可以添加更多的条件。
    创建DAO的开销比较大,尽量将DAO重复利用。DaoManager具有缓存功能,可以将创建的DAO缓存下来,避免重复创建,因此尽量使用DaoManager创建DAO。

    public class AccountDAO {
        private static volatile AccountDAO instance;
    
        private AccountDAO() {
        }
    
        public static AccountDAO getInstance() {
            if (instance == null) {
                synchronized (AccountDAO.class) {
                    if (instance == null) {
                        instance = new AccountDAO();
                    }
                }
            }
            return instance;
        }
    
    
        public void update(Account account) {
            try {
                getDao().update(account);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        public void addAccount(Account account) {
            try {
                getDao().create(account);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
    
        public void deleteAccount(List<Account> accountList) {
            try {
                getDao().delete(accountList);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
        public Account queryById(String id) {
            Account ret = null;
            try {
                ret = getDao().queryForId(id);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return ret;
        }
    
        public Dao<Account, Object> getDao() {
            return DatabaseHelper.getInstance().getDao(Account.class);
        }
    
    }

    其他常用方法

    1.getDao().createOrUpdate(account): 在操作数据库时,会根据account的id查询,如果存在则执行 update 方法,否则执行create 方法;
    2.getDao().queryForFirst():
    3.getDao().queryForSameId():
    4.getDao().queryForEq():
    5.getDao().updateRaw():

    2.5. 使用

    之后就可以直接在需要调用的地方拿到DAO实例,在调用相应的工具方法对数据库进行增删改差操作就可以了。

    WEHRE子句

    在SQL语句中,经常会用到where语句,where 进行条件筛选。dao.queryBuilder.()where()方法返回一个where对象,where中提供了很多方法来进行条件筛选,下边逐个讲where中的方法。

    查询语句
    eq(=)

    方法 :eq(columnName,value) 等于(=)equals
    使用示范:DatabaseHelper.getDao().queryBuilder().where().eq(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id = 2

    it(<)

    方法 :lt(columnName,value) 小于(<) less than
    使用示范:DatabaseHelper.getDao().queryBuilder().where().lt(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id < 2

    gt(>)

    方法 :gt(columnName,value) 大于(>) greater than
    使用示范:DatabaseHelper.getDao().queryBuilder().where().gt(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id > 2

    ge(>=)

    方法 :ge(columnName,value) 大于等于(>=)greater-than or equals-to
    使用示范:DatabaseHelper.getDao().queryBuilder().where().ge(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id >= 2

    le(<=)

    方法 :le(columnName,value) 小于等于(<=)less than or equals-to
    使用示范:DatabaseHelper.getDao().queryBuilder().where().le(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id <= 2

    ne(<>)

    方法 :ne(columnName,value) 不等于(<>)not-equal-to
    使用示范:DatabaseHelper.getDao().queryBuilder().where().ne(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE id <> 2

    in(匹配相应的结果集)

    方法 :in(columnName,object…) 在指定列中匹配object数组所对应的值,返回匹配到的结果行集合,
    in还有几个重载方法.
    使用示范:DatabaseHelper.getDao().queryBuilder().where().in(“id”, 1,2).query();
    对应SQL:SELECT * FROM t_account WHERE id IN (1,2 )

    notIn(in 取到的相反集合)

    方法 :notIn(columnName,object…) 在指定列中匹配object数组所对应的值,返回没有匹配到的结果行集合,notIn还有几个重载方法
    使用示范:DatabaseHelper.getDao().queryBuilder().where().notIn(“id”,1,2).query();
    对应SQL:SELECT * FROM t_account WHERE id NOT IN (1 ,2 )

    like(含有相应的字符的结果集)

    方法 :like(columnName,pattern) 使用%通配符来匹配,指定行数据,返回匹配到的结果
    使用示范:DatabaseHelper.getDao().queryBuilder().where().like(“LastName”, “A%”).query(); 匹配A开头的LastName
    DatabaseHelper.getDao().queryBuilder().where().like(“LastName”, “%s”).query(); 匹配s结尾的LastName
    DatabaseHelper.getDao().queryBuilder().where().like(“LastName”, “%art%”).query(); 匹配中间为art的LastName
    对应SQL:SELECT * FROM t_account WHERE LastName LIKE ‘A%’

    between(指定字段在响应的范围内)

    方法 :between(columnName,low,high) 获取指定范围内的结果
    使用示范:DatabaseHelper.getDao().queryBuilder().where().between(“id”, 1, 2).query(); 获取id是1到2之间的结果
    对应SQL:SELECT * FROM t_account WHERE id BETWEEN 1 AND 2

    and or (并且 和 或 的关系)

    and() or() where子句或操作
    使用示范:DatabaseHelper.getDao().queryBuilder().where().eq(“id”, 1).or().eq(“id”, 2).query();
    使用示范:DatabaseHelper.getDao().queryBuilder().where().eq(“id”, 1).and().eq(“id”, 2).query();
    对应SQL:SELECT * FROM t_account WHERE (id = 1 OR id = 2 )
    对应SQL:SELECT * FROM t_account WHERE (id < 3 AND id > 1 )

    ORDER BY(根据指定列名排序,降序,升序)

    使用示范:DatabaseHelper.getDao().queryBuilder().orderBy(“id”, false).query(); //参数false表示降序,true表示升序。
    对应SQL:SELECT * FROM t_account ORDER BY id DESC(降序)

    Having

    等同于sql中的Having,针对分组数据,进行聚合函数(SUM, COUNT, MAX, AVG)运算。
    使用示范:mPersonList = mDao.queryBuilder().groupBy(“City”).having(“SUM(id)>4”).query()
    对应SQL:SELECT * FROM t_person GROUP BY City HAVING SUM(id)>4

    DISTINCT (过滤指定列不重复数据行,重复的只返回一次。)

    使用示范:DatabaseHelper.getDao().queryBuilder().selectColumns(“City”).distinct().query();
    对应SQL:SELECT DISTINCT t_account FROM t_person

    countOf(返回查询结果的总数)

    使用示范:DatabaseHelper.getDao().queryBuilder().countOf()
    对应SQL:SELECT COUNT(*) FROM t_account

    offset Limit

    offset跳过指定的行数
    limit限制获取指定行数
    使用示范:mDao.queryBuilder().offset(2).limit(2).query(); 可以用来分页
    对应SQL:SELECT * FROM t_account LIMIT 2 OFFSET 2

    3. ORMLite进行联合查询

    之前的操作都是在单一的表中进行操作的,开发中也经常遇到表与表之间存在关联的, 下面介绍多表之间的操作

    User表

    
    @DatabaseTable(tableName = "User")
    public class UserBean
        @DatabaseField(columnName = INTOID, generatedId = true)
            private Long id;
    
            @DatabaseField(columnName = ACTID, foreign = true)
            private String actId;
        }

    Account 表

    @DatabaseTable(tableName = "Account")
    public class AccountBean {
            @DatabaseField(columnName = ACTID, generatedId = true)
            private String actId;
        }

    具体操作:

    QueryBuilder<User, Object> userQb = userDao.queryBuilder();
    userQb.where().ge("id", 10);
    QueryBuilder<Account, Object> accountQb = accountDao.queryBuilder();
    // join with the order query
    List<Account> results = accountQb.join(userQb).query();
    展开全文
  • 二次封装好的Ormlite数据库,支持三种不同类型的数据库创(自动创表、SD卡下创表、android默认数据库创表),使用非常方便。
  • 一个方便实用的OrmLite数据库框架,支持一键集成。
  • 简单的使用ORMLite数据库
  • Android中OrmLite数据库的使用操作和步骤: 1,OrmLite数据库可以让开发者不写sql的情况完成dao开发。 2,Orm:Object Relation Mapping,对象关系模型映射。即通过javaBean的特殊配置。完成类与表名,变量与列名的...
  • OrmLite数据库的使用(包含一对多的关系)
  • 一个方便实用的OrmLite数据库框架,支持一键集成。 关于我 特征 支持通过@DataBase进行数据库配置。 支持自动生成数据库管理仓库DataBaseRepository 。 支持自动搜索所有的数据库表类,并自动创建数据库表。 支持...
  • OrmLite数据库的使用方法 第一步:导入架包 1、将orm的两个支持包放入project视图下的你的工程的lib目录里(这两个JAR包网上都有,GitHub上最新) 2、添加依赖:在file文件目录下的...
  • 一个方便实用的OrmLite数据库框架,支持一键集成。 关于我 特征 支持通过@DataBase进行数据库配置。 支持自动生成数据库管理仓库DataBaseRepository。 支持内部存储和外部存储两种数据库。 支持自定义...
  • ormlite 数据库资源

    2014-08-05 07:58:44
    ormo工具开发 是不错的 数据库存储 详情 请查看
  • 一个方便实用的OrmLite数据库框架,支持一键集成。 关于我 特征 支持通过@DataBase进行数据库配置。 支持自动生成数据库管理仓库DataBaseRepository。 支持内部存储和外部存储两种数据库。 支持自定义...
  • Android快速开发OrmLite数据库封装详解

    千次阅读 2016-03-11 17:59:32
    Android移动开发之数据库——OrmLite详解随着开源框架的广泛,对于Android开发者越来越有优势,极大的提高了开发效率和开发...使用第三方框架OrmLite数据库开发Android移动应用程序; 2.不再使用SQL语句实现增删查改,
  • ORMLite 数据库封装的使用最近在做一个市政抄表机,录入用户水汽表数据到DB里面的,这个封装是同事封装的,封装的很好,文档也很详细,所以计入一下.方便下次使用.使用步骤:##ORM使用基础工作: 1、下载 ORMLite Jar ...
  • 利用 ORMLite 数据库,ViewPager 等实现简易的登陆界面
  • ormlite数据库使用demo

    2016-12-28 21:10:52
    http://blog.csdn.net/qq_30651537/article/details/53914023
  • 二次封装好的Ormlite数据库,支持三种不同类型的数据库创(自动创表、SD卡下创表、android默认数据库创表),使用非常方便.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • Android ormlite 数据库

    2018-11-21 16:48:00
    这里记录ormlite的原因:有很多效率更高的数据库 比如greendao,但是使用中会有很多问题,比如greendao是自动化build的,而且需要改gradle中的配置,这就可能影响当前项目的使用。当时有个项目使用jni, ...
  • ormlite数据库的使用

    2018-01-13 14:16:43
    目前android数据库开发框架有:OrmLite,LitePal,greeenDao,SugerOrm。 最近使用ormLite写了个小应用,现在来介绍下ormLite的用法: 1.一个数据库对应一个LiteOrm的实例,首先要自定义一个实体类,要在JavaBean...
  • OrmLite数据库框架,Picasso框架,Okio框架,OKHttp框架

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,034
精华内容 413
关键字:

ormlite数据库