• Android 通过Room操作SQLite数据库


    谷歌推荐使用Room操作数据库,Room在 SQLite 上提供了一个抽象层,在充分利用 SQLite强大功能的同时,能够流畅地访问数据库。

    Room的三个主要组件:

    • 数据库类,用于保存数据库并作为应用持久性数据底层连接的主要访问点。
    • 数据实体,@Entity,表示数据库中的表。
    • 数据访问对象 (DAO),@Dao,提供查询、更新、插入和删除数据的方法。

    build.gradle添加

    dependencies {
        def room_version = "2.4.3"
    
        implementation "android.arch.persistence.room:runtime:$room_version"
        annotationProcessor "android.arch.persistence.room:compiler:$room_version" 
    
        implementation "android.arch.persistence.room:rxjava2:$room_version"
    
        testImplementation "android.arch.persistence.room:testing:$room_version"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1. 创建实体类User

    @Entity(tableName = "users")
    public class User {
        @PrimaryKey
        public int uid;
    
        @ColumnInfo(name = "first_name")
        public String firstName;
    
        @ColumnInfo(name = "last_name")
        public String lastName;
    
    	... get ...
    	... set ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    @Entity实体类,users表的名称,不加默认user
    @ColumnInfo列名
    @PrimaryKey主键
    复合主键
    @Entity(primaryKeys = {“first_name”, “last_name”})


    主键不设置非空约束,报错

    You must annotate primary keys with @NonNull. "xxx" is nullable. SQLite considers this a bug and Room does not allow it. See SQLite docs for details:
    
    • 1
    @NonNull
        @ColumnInfo(name = "first_name")
    
    • 1
    • 2

    2. 创建DAO

    @Dao
    public interface UserDao {
        @Query("SELECT * FROM user")
        List<User> getAll();
    
        @Query("SELECT * FROM user WHERE uid IN (:userIds)")
        List<User> loadAllByIds(int[] userIds);
    
        @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
                "last_name LIKE :last LIMIT 1")
        User findByName(String first, String last);
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        void insertAll(User... users);
    
        @Delete
        void delete(User user);
    
    	@Query("SELECT * FROM user WHERE first_name=:name AND last_name=:names")
        List<DisableInfo> getDisable(String name,String names);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    增,删,改:将实例与表的主键进行匹配
    查询结果将自动映射到对应类型的字段,若未映射将报警告


    删除表内所有数据是query ,而不是delete,留个印
    @Query(“DELETE FROM appinfo”)
    void deleteAll();

    3. 数据库

    抽象类AppDatabase 定义数据库配置,并作为应用对持久性数据的主要访问点,扩展了RommDataBase

    @Database(entities = {User.class}, version = 1, exportSchema = false)
    public abstract class AppDataBase extends RoomDatabase {
    
        public abstract UserDao userDao();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4. 使用

    AppDataBase db = Room.databaseBuilder(getApplicationContext(),
                            AppDataBase.class, "database-name").build();
                    for (int i = 0; i < 10; i++) {
                        User user = new User();
                        user.uid = i;
                        user.firstName = "Shell" + i;
                        user.lastName = "Hub" + i;
                        db.userDao().insertAll( user);
                        List<User> userList = db.userDao().getAll();
                        for(User user1 : userList) {
                            Log.d("mip",""+user1.firstName);
                        }
                    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    为了节约获取数据库的时间和资源,采取单例模式
    简单实现:

    public class Utils {
        private static AppDataBase db = null;
        private static Context context = null;
    
        public static AppDataBase getDb(){
            if( db == null) {
                db = Room.databaseBuilder(context,
                        AppDataBase.class, "database-name").build();
            }
            return db;
        }
    
        public static void setContext(Context context){
            Utils.context = context;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    调用

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Utils.setContext(getApplicationContext());
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    AppDataBase db = Utils.getDb();
                    for (int i = 0; i < 10; i++) {
                        User user = new User();
                        user.uid = i;
                        user.firstName = "Shell" + i;
                        user.lastName = "Hub" + i;
                        db.userDao().insertAll( user);
                        List<User> userList = db.userDao().getAll();
                        for(User user1 : userList) {
                            Log.d("mip",""+user1.firstName);
                        }
                    }
                }
            }).start();
        }
    }
    
    • 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

    路过的大佬们有更好的单例实现请告诉我一下,
    感谢。

  • 相关阅读:
    [第三篇]——CentOS Docker 安装
    现在加入3D游戏建模有没有前景,次世代全流程来啦
    无监督学习——k均值
    MySQL 1、初识数据库
    JUC第六讲:ThreadLocal/InheritableThreadLocal详解
    计算机组成原理学习笔记:BCD码
    企业图档加密系统
    关于string的一些测试
    5.0、C语言——函数
    json和axion结合
  • 原文地址:https://blog.csdn.net/weixin_45369680/article/details/127866214