当前位置:   article > 正文

安卓Room框架初使用_安卓room框架不打印sql

安卓room框架不打印sql

Room框架介绍

Room在·SQLite上提供了抽象层,以便于更加流畅的访问数据库,对数据库进行操作。主要由Database,Entity,Dao这三部分组成:

Database(数据库)

包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。简单来说,就是通过这个类构造的对象,调用抽象方法构造的Dao对象去对数据库中的表进行增删改查。需注意以下写法:

  • 1 Database类要用@Database标注,并且通过entities指定与之相关联的表的一个类。
  • 2 它是一个抽象类,里面有一个反回Dao对象的一个抽象方法。
  • 3 对数据库的升级可以在这里面定义。
    示例代码:
    @Database(entities = {User.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
    }
  • 1
  • 2
  • 3
  • 4

Entity:表示数据库中的表。

示例代码:

    @Entity(tableName = "users")
    public class User {
        @PrimaryKey
        public int uid;

        @ColumnInfo(name = "first_name")
        public String firstName;
        
        @ColumnInfo(name = "last_name")
        public String lastName;
    }
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1 用@Entity表示这是一个用于与数据库中的表对应的一个类。里面需定义字段名。如果想改变列名, @ColumnInfo(name = " ")来定义。这里面可以定义setter和getter方法,方便去操作这张表。可以(tableName = “users”)来标识表的名字。
  • 2 必须有主键标识的一个字段,哪怕只有一个字段。
表的复杂写法:

-1 默认情况下,Entity类里面的字段都会生成相应的类,如果不想产生相应的类,需用@Ignore标注,
代码如下:

   @Entity
    public class User {
        @PrimaryKey
        public int id;
        @Ignore
        Bitmap picture;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 2 如果表的结构是复合组件,须使用 @Entity(primaryKeys = {“主键1”, “主键2”})。
  • 3 外键的写法:
    @Entity(foreignKeys = @ForeignKey(entity = User.class,
                                      parentColumns = "id",
                                      childColumns = "user_id"))
    public class Book {
        @PrimaryKey public int bookId;
        
        public String title;
        
        @ColumnInfo(name = "user_id") public int userId;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其中entity = User.class表示要引用的外键的类, parentColumns = "id"表示外键在要引用的类里面的列名, childColumns = "user_id"表示在这个表中对应的列名。

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
        void insertAll(User... users);

        @Delete
        void delete(User user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

需注意以下:

  • 1用@Query定义sql语言,紧接着下面写java方法代码,如果sql语言里要引用方法里面的形参,需用:加形参。
  • 2 有些方法是已经定义好的,不需要写sql代码,例如Delete,Update等。
  • 3 需注意反回类型。例如getALL的返回类型要用List<>接收。

具体使用(附Demo)

添加依赖

需在app目录下的build.gradle的dependencies中添加如下代码:

     def room_version = "2.2.3"

      implementation "androidx.room:room-runtime:$room_version"
      annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

      // optional - Kotlin Extensions and Coroutines support for Room
      implementation "androidx.room:room-ktx:$room_version"

      // optional - RxJava support for Room
      implementation "androidx.room:room-rxjava2:$room_version"

      // optional - Guava support for Room, including Optional and ListenableFuture
      implementation "androidx.room:room-guava:$room_version"

      // Test helpers
      testImplementation "androidx.room:room-testing:$room_version"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这样做完常会出现一个Kotlin的jar包不能够安装的问题,会导致build时会超时,完成不了,导致Room不能够使用,解决办法:在于app同级的build.gradle中的allprojects里的repositories里如下写法:

allprojects {
    repositories {
        maven{url "https://kotlin.bintray.com/kotlinx/"}
        google()
        jcenter()
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

数据库的建立

采用单例模式反回数据库对象。相关代码:

@Database(entities = {User.class},version = 1)
public abstract class AppDatabase extends RoomDatabase {
    private static final String DB_NAME ="uers.db";
    private static volatile AppDatabase instance;

    static synchronized AppDatabase getInstance(Context context){
        if(instance==null){
            instance=create(context);
        }
        return instance;
    }
    private static  AppDatabase create(final Context context){
        return Room.databaseBuilder(context, AppDatabase.class, DB_NAME)
                //.addMigrations(MIGRATION_1_2)  //数据库升级,可以对数据库进行更改
                .build();
    }

 public abstract UserDao userDao();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这样反回一个数据库对象,生成了一个指定名字的数据库。

数据库的升级

在上述代码中加入以下代码:

    static final Migration MIGRATION_1_2=new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
 //对数据库结构进行修改的操作
        }
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

MIGRATION_1_2表示从第一个版本到第二个版本,对应的Migration(1,2)。
可以在文件中查看数据库的变化情况:
在app目录下的app目录下的build.gradle中加入如下代码:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
                //指定数据库schema导出的位置
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以在schemas目录中看到一个json文件,里面就有相关记录。

表结构的修改

表结构的修改是写在数据库升级里面的。
示例一个对数据库中表的结构修改且不丢失数据的操作。

            //对数据库的表结构进行修改,而不丢失数据
            database.execSQL("create table temp_user("+
                    "id integer primary key not null,"+
                    "first_name TEXT,"+"last_name text)"); //创建表
            database.execSQL("insert into temp_user(id,first_name,last_name)"+
                    "select id,first_name,last_name from user"); //从原先表中导入数据
            database.execSQL("drop table user");  //删除表
            database.execSQL("alter table temp_user rename to user");//重命名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Entity代码

@Entity
public class User {
    @PrimaryKey
    public int uid;

    @ColumnInfo(name="first_name")
    public String firstName;

    @ColumnInfo(name="last_name")
    public String lastName;

    public User() {}

    @Ignore
    public User(int uid, String firstName, String lastName) {
        this.uid = uid;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}
  • 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

这个类的写法须遵循javabeans的写法,值得注意的就是要有一个空的构造方法,如果有其他的构造方法
需要用 @Ignore来标识。

Dao代码

@Dao
public interface UserDao {
    @Query("select * from user")
    List<User> getAll();

    @Query("select * from user where first_name like :first and " +
    "last_name like :last limit 1")
    User findByName(String first,String last);

    @Query("select * from user where uid= :id")
    User findById(int id);

    @Update
    void update(User user);
    @Insert
    void insert(User user);

    @Delete
    void delete(User user);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

表的增删改查操作

用了recycleView来显示数据库中的内容。注意几点:

  • 1 对数据库的操作需在子线程中完成
  • 2 对UI的更新需在UI线程中完成或者通过其他方式延迟操作。
    完整代码如下:
package com.app.roomdemo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView_show;
    EditText editText_id;
    EditText editText_first;
    EditText editText_last;
    private Button button_put;
    private Button button_insert;
    private Button button_delete;
    private Button button_change;
    private Button button_search;
    private UserDao userDao;
    ArrayList<User> userList =new ArrayList<>();
    private int id;
    private String first;
    private  String last;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AppDatabase db =AppDatabase.getInstance(getApplicationContext());
        userDao = db.userDao();
        initView();
        initrecycleView(true);
        Log.e("MainActivity","setAdapter");
        View.OnClickListener mylistener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.put:
                        put();
                        break;
                    case R.id.change:
                        change(MainActivity.this);
                        break;
                    case R.id.search:
                        search(MainActivity.this);
                        break;
                    case R.id.delete:
                        delete(MainActivity.this);
                        break;
                    case R.id.insert:
                        insert( MainActivity.this);
                        break;
                    default:
                        break;
                }
            }
        };
        button_put.setOnClickListener(mylistener);
        button_search.setOnClickListener(mylistener);
        button_insert.setOnClickListener(mylistener);
        button_delete.setOnClickListener(mylistener);
        button_change.setOnClickListener(mylistener);
    }
    //删除操作
    private void delete(final Context context) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user=new User(id,first,last);
                userDao.delete(user);
                initrecycleView(true);
            }
        }).start();
}
//插入操作
    private void insert(final Context context) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user=new User(id,first,last);
                userDao.insert(user);
                initrecycleView(true);
            }
        }).start();
    }
    //按Id搜索操作
    private void search(final Context context) {
       initrecycleView(false);
    }
    //更新操作
    private void change(final Context context) {
        new Thread(new Runnable() {
            @Override
            public void run() {
            User user= new User(id,first,last);
            userDao.update(user);
            initrecycleView(true);
            }
        }).start();
    }
    //数据提交
    private void put(){
		if(!editText_id.getText().toString().isEmpty()){
			        id=Integer.parseInt(editText_id.getText().toString());
        first=editText_first.getText().toString();
        last=editText_last.getText().toString();
		}
    }
    //显示所有的内容
    private ArrayList<User> show(final Boolean is_show_all){
        new Thread(new Runnable() {
            @Override
            public void run() {
                if(is_show_all){
                    userList=new ArrayList<User>();
                    userList=(ArrayList<User>) userDao.getAll();
                }
                else{
                    userList=new ArrayList<User>();
                    User user=new User();
                    user=userDao.findById(id);
					if(user!=null)
                    userList.add(user);
                }
            }
        }).start();
       return userList;
    }
    //初始化各组件对象
    private void initView() {
        recyclerView_show=(RecyclerView)findViewById(R.id.recyclerView_show);
        button_put=(Button)findViewById(R.id.put);
        button_search=(Button)findViewById(R.id.search);
        button_change=(Button)findViewById(R.id.change);
        button_insert=(Button)findViewById(R.id.insert);
        button_delete=(Button)findViewById(R.id.delete);
        editText_id=(EditText)findViewById(R.id.id);
        editText_first=(EditText)findViewById(R.id.first);
        editText_last=(EditText)findViewById(R.id.last);
    }
    //执行更新UI操作
    private void  initrecycleView(Boolean is_show_all){
          userList=show(is_show_all);
        new Handler(this.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                LinearLayoutManager layoutManager=new LinearLayoutManager(MainActivity.this);
                recyclerView_show.setLayoutManager(layoutManager);
                UserAdapter adapter=new UserAdapter(MainActivity.this,userList);
                recyclerView_show.setAdapter(adapter);
            }
        });

    }
}

  • 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
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171

由于使用了延迟更新UI,则执行操作可能不会马上见效。

Adapter及相关布局文件就不提供了,提供在educoder上。

执行效果

操作前:
在这里插入图片描述
插入操作:
在这里插入图片描述
更改操作:
在这里插入图片描述

删除操作:
在这里插入图片描述

总结

Room框架比较直接,且功能分配明确,十分简洁
再者,一定记住数据库操作要在子线程中完成,还有插入操作时,如果没有指定冲突的方法时,如果插入的数据主键已经存在数据库里面的某个项,那么会直接闪退。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/477712
推荐阅读
相关标签
  

闽ICP备14008679号