android Room框架基本使用

1、简介

Room 在 SQLite 上提供了一个抽象层,以便在充分利用SQLite的强大功能的同时,能够流畅地访问数据库。

处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的用例是缓存相关数据。这样,当设备无法访问网络时,用户仍可在离线状态下浏览相应内容。设备重新连接到网络后,用户发起的所有内容更改都会同步到服务器。

  • Room使用DAO查询数据库
  • 默认情况下,为了提高UI性能,Room不允许在主线程中执行查询数据库操作。LiveData在后台线程上异步更新数据。
  • Room 提供SQLite语句编译时检查
  • 自定义的Room类必须是抽象类且必须继承RoomDatabase
  • 通常,在整个APP中,只需要一个Room database实例。

2、room的三个重要组件

  • @Entity: 用来注解实体类, @Database 通过entities属性引用被 @Entity注解的类,并利用该类的所有字段作为表的列名来创建表。
  • @Dao: 用来注解一个接口或者抽象方法,该类的作用是提供访问数据库的方法。在使用 @Database注解的类中必须定一个不带参数的方法,这个方法返回使用 @Dao注解的类。
  • @Database: 用来注解类,并且注解的类必须是继承自RoomDatabase的抽象类。该类主要作用是创建数据库和创建Daos(data access objects,数据访问对象)。

3、使用

导入room库

allprojects {
    repositories {
        maven {url 'https://maven.google.com' }//添加moven
        google()
        jcenter()
        
    }
}
//    导入room库
    def room_version = "1.1.1"
    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation 'android.arch.persistence.room:runtime:room_version'
    annotationProcessor 'android.arch.persistence.room:compiler:room_version'

1、创建实体类

@Entity注解的类,并利用该类的所有字段作为表的列名来创建表。

/**
 * @author: Luuuzi
 * @date: 2020-08-04
 * @description: 1.创建Entity
 */
//@Entity(tableName = "user") 指定表名
@Entity
public class User {
    //主键 autoGenerate = true:自动生成
    @PrimaryKey
    public int uId;
    @ColumnInfo(name = "first_name")
    public String firstName;
    @ColumnInfo(name = "last_name")
    public String lastName;

//    public User(int uId) {
//        this.uId = uId;
//    }

    public User(int uId, String firstName, String lastName) {
        this.uId=uId;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "User{" +
                "uId=" + uId +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

2、创建接口定义访问数据库的方法

@Dao
public interface UserDao {
    //查询表里面所有数据
    @Query("SELECT * FROM user")
    List<User> getAll();

    //通过id去查询
    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> findAllByIds(int[] userIds);
    
    //模糊查询:查找字段first_name包含指定内容的字段
    @Query("SELECT * FROM user WHERE first_name LIKE '%'|| (:str)||'%'")
    List<User> getLike(String str);
    
    //插入
    @Insert
    void insetAll(List<User> users);

    //插入
    @Insert
    void inset(User user);

    //删除(根据主键去删除)
    @Delete
    void delete(User user);

    /**
     * 批量删除
     * @param users
     * @return 删除条数
     */
    @Delete
    int deletes(List<User> users);
    /**
     * 单条更新
     *
     * @param user 更新内容,根据uId去修改
     * @return 更新成功条数,更新一条,返回1 更新2条返回2
     */
    @Update
    int update(User user);

    /**
     * 批量更新
     *
     * @param users 更新内容,根据uId去修改
     * @return 更新成功条数,更新一条,返回1 更新2条返回2
     */
    @Update
    int updates(List<User> users);
}

3、创建访问数据库的对象

该类主要作用是创建数据库和创建Daos(data access objects,数据访问对象)

/**
 * @author: Luuuzi
 * @date: 2020-08-04
 * @description: 3.SQLite数据库之上的数据库层,负责处理以前使用SQLiteOpenHelper处理的普通任务。
 * exportSchema = false:去除警告 version版本号:版本号要>=1
 */
@Database(entities = {User.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

调用

注意:通常,在整个APP中,只需要一个Room database实例(一般设置成单例)

/**
 * @author: Luuuzi
 * @date: 2020-08-04
 * @description: room的使用
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    static final String tag = MainActivity.class.getSimpleName();
    private EditText et_first_name;
    private EditText et_last_name;
    private EditText et_first_name2;
    private EditText et_last_name2;
    private TextView tv_content;
    AppDatabase db;
    private EditText et_uid1;
    private EditText et_uid2;
    private EditText et_uid3;
    private EditText et_last_name3;
    private EditText et_first_name3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建db对象,用于操作数据(通常,在整个APP中,只需要一个Room database实例。)
        db = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "database-name")//database-name:数据库文件名称
                .allowMainThreadQueries()//允许在主线程中查询
                .build();

        et_first_name = findViewById(R.id.et_first_name);
        et_last_name = findViewById(R.id.et_last_name);
        et_uid1 = findViewById(R.id.et_uid1);
        et_first_name2 = findViewById(R.id.et_first_name2);
        et_last_name2 = findViewById(R.id.et_last_name2);
        et_uid2 = findViewById(R.id.et_uid2);
        et_first_name3 = findViewById(R.id.et_first_name3);
        et_last_name3 = findViewById(R.id.et_last_name3);
        et_keyword = findViewById(R.id.et_keyword);
        et_uid3 = findViewById(R.id.et_uid3);
        tv_content = findViewById(R.id.tv_content);

        findViewById(R.id.btn_add).setOnClickListener(this);
        findViewById(R.id.btn_delete).setOnClickListener(this);
        findViewById(R.id.btn_inquiry).setOnClickListener(this);
        findViewById(R.id.btn_inquiry2).setOnClickListener(this);
        findViewById(R.id.btn_updata).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_add:
                User user = new User(Integer.parseInt(et_uid1.getText().toString()), et_first_name.getText().toString(), et_last_name.getText().toString());
                db.userDao().inset(user);
                break;
            case R.id.btn_delete:
//                User user2 = new User(Integer.parseInt(et_uid2.getText().toString()), et_first_name2.getText().toString(), et_last_name2.getText().toString());
//                db.userDao().delete(user2);
                //测试批量删除
                User user44 = new User(4, "da", "da");
                User user55 = new User(5, "而且", "哦");
                User user58 = new User(58, "而且", "dfa");
                ArrayList<User> users2 = new ArrayList<>();
                users2.add(user44);
                users2.add(user55);
                users2.add(user58);
                int deletes = db.userDao().deletes(users2);
                Log.i(tag, "删除条数:" + deletes);
                break;
            case R.id.btn_updata:
//                User user3 = new User(Integer.parseInt(et_uid3.getText().toString()), et_first_name3.getText().toString(), et_last_name3.getText().toString());
//                db.userDao().update(user3);
                //测试批量更新
                Log.i(tag, "批量更新");
                User user4 = new User(2, "你飞而去好", "嘿嘿");
                User user5 = new User(3, "发儿", "是的");
                User user6 = new User(4, "你大法", "已看");
                ArrayList<User> users = new ArrayList<>();
                users.add(user4);
                users.add(user5);
                users.add(user6);
                int update = db.userDao().updates(users);
                Log.i(tag, "更新结果:" + update);
                break;
            case R.id.btn_inquiry:
                List<User> all = db.userDao().getAll();
                StringBuffer stringBuffer = new StringBuffer();
                for (User u : all) {
                    stringBuffer.append("").append(u).append(",").append("\n");
                }
                tv_content.setText(stringBuffer);
                break;
            case R.id.btn_inquiry2://模糊查询
                List<User>= db.userDao().getLike(et_keyword.getText().toString());
                StringBuffer stringBuffer2 = new StringBuffer();
                for (User u :) {
                    stringBuffer2.append("").append(u).append(",").append("\n");
                }
                tv_content.setText(stringBuffer2);
                break;
        }
    }
}

4、其他用法

1、关于查询

模糊查询查询可以用like或glob,具体用法

  • LIKE
    LIKE用来匹配通配符指定模式的文本值。如果搜索表达式与模式表达式匹配,LIKE 运算符将返回真(true),也就是 1。这里有两个通配符与 LIKE 运算符一起使用,百分号(%)代表零个、一个或多个数字或字符。下划线(_)代表一个单一的数字或字符。这些符号可以被组合使用。
1、查找字段A以AAA开头的任意值
  select * from table_name where 字段A like 'AAA%'
2、查找字段A任意位置包含AAA的任意值
  select * from table_name where 字段A like '%AAA%'
3、查找字段A第二位和第三位为 AA 的任意值
  select *from table_name where 字段A like '_AA%'
4、查找字段A以 A 开头,且长度至少为 3 个字符的任意值
  select * from table_name where 字段A like 'A_%_%'
5、查找字段A以 A 结尾的任意值
  select *from table_name where 字段A like '%A'
6、查找字段A第二位为 A,且以 B 结尾的任意值
  select *from table_name where 字段A like '_A%B'
7、查找字段A长度为 5 位数,且以 A 开头以 B 结尾的任意值(A,B中间三个下划线)
  select *from table_name where 字段A like 'A___B'
  • GLOB
    SQLite 的 GLOB 运算符是用来匹配通配符指定模式的文本值。如果搜索表达式与模式表达式匹配,GLOB 运算符将返回真(true),也就是 1。与 LIKE 运算符不同的是,GLOB 是大小写敏感的,对于下面的通配符,它遵循 UNIX 的语法。
    星号(*)代表零个、一个或多个数字或字符。问号(?)代表一个单一的数字或字符。这些符号可以被组合使用。
1、查找字段A以AAA开头的任意值
  select * from table_name where 字段A GLOB 'AAA*'
2、查找字段A任意位置包含AAA的任意值
  select * from table_name where 字段A GLOB '*AAA*'
3、查找字段A第二位和第三位为 AA 的任意值
  select *from table_name where 字段A GLOB '?AA*'
4、查找字段A以 A 开头,且长度至少为 3 个字符的任意值
  select * from table_name where 字段A GLOB 'A?*?*'
5、查找字段A以 A 结尾的任意值
  select *from table_name where 字段A GLOB '*A'
6、查找字段A第二位为 A,且以 B 结尾的任意值
  select *from table_name where 字段A GLOB '?A*B'
7、查找字段A长度为 5 位数,且以 A 开头以 B 结尾的任意值(A,B中间三个下划线)
  select *from table_name where 字段A GLOB 'A???B'

在room中,真接写 LIKE '% :key %'或者 “LIKE '%”+:key+“% '"都有问题,正确写法如下:
@Query("SELECT * FROM tb_use WHERE Name LIKE ‘%’ || :name || ‘%’)

//模糊查询:查找字段first_name包含指定内容的字段
@Query("SELECT * FROM user WHERE first_name LIKE '%'|| (:str)||'%'")
List<User> getLike(String str);

注意:用双竖杠去拼接,而不是加号

在SQL中的SELECT语句中,可使用一个特殊的操作符来拼接两个列。根据你所使用的DBMS,此操作符可用加号(+)或两个竖杠(||)表示。在MySQL和MariaDB中,必须使用特殊的函数。
说明:是+还是||?
Access和SQL Server使用+号。DB2、Oracle、PostgreSQL、SQLite和Open Office Base使用||。详细请参阅具体的DBMS文档。
看来SQL的知识点也要懂点啊!

项目地址

参考

使用 Room 将数据保存到本地数据库
关于Room数据库,拼写模糊查找的语句遇到问题
Room使用过程中遇到的问题记录

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android RoomAndroid Jetpack中的一个持久性库,用于在SQLite数据库上提供抽象层。它简化了与数据库的交互,并提供了一种更健壮和类型安全的方式来处理数据。 以下是使用Android Room框架的一些步骤: 1. 添加依赖项:在项目的build.gradle文件中添加以下依赖项: ```groovy dependencies { implementation "androidx.room:room-runtime:2.2.5" annotationProcessor "androidx.room:room-compiler:2.2.5" } ``` 2. 创建实体类:使用`@Entity`注解创建一个实体类,该类将映射到数据库中的表。可以使用`@PrimaryKey`注解指定主键,使用`@ColumnInfo`注解指定列名等。 ```java @Entity(tableName = "users") public class User { @PrimaryKey public int id; @ColumnInfo(name = "name") public String name; // 其他属性和方法... } ``` 3. 创建DAO接口:使用`@Dao`注解创建一个数据访问对象(DAO)接口,该接口定义了对数据库进行操作的方法。可以使用`@Query`注解执行自定义查询,使用`@Insert`注解插入数据,使用`@Update`注解更新数据等。 ```java @Dao public interface UserDao { @Query("SELECT * FROM users") List<User> getAllUsers(); @Insert void insertUser(User user); // 其他方法... } ``` 4. 创建数据库:使用`@Database`注解创建一个抽象类,该类扩展自`RoomDatabase`,并定义了数据库的版本号和包含的实体类。可以使用`getInstance()`方法获取数据库的实例。 ```java @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); // 其他方法... } ``` 5. 初始化数据库:在应用程序的入口点或需要访问数据库的地方,使用以下代码初始化数据库: ```java AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "my-database").build(); ``` 6. 执行数据库操作:通过DAO接口的方法执行数据库操作。例如,插入一个用户: ```java User user = new User(); user.id = 1; user.name = "John"; db.userDao().insertUser(user); ``` 这样,你就可以使用Android Room框架来管理和操作数据库了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值