Android—Room数据库多表查询(Relationships)

前言

在SQLite数据库中,我们可以指定对象之间的关系,因此我们可以将一个或多个对象与一个或多个其他对象绑定。这就是所谓的一对多和多对多的关系。

既然要多表查询,所以表之间就得有关联。这时候我们就得使用新的注解符@ForeignKey

接下来的内容,就需要上节的内容了

@Entity
public class Company {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String name;
    private int age;
    private String address;
    private double salary;

    public Company(String name, int age, String address, double salary) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.salary = salary;
    }
    //省略了getter/setter方法
}

下面我们再新建一个与之关联的表

@Entity(foreignKeys = @ForeignKey(entity = Company.class,parentColumns = "id",childColumns = "emp_id",onDelete = CASCADE),
        indices = @Index(value={"emp_id"},unique = true))
public class Department {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String dept;
    @ColumnInfo(name = "emp_id")
    private int empId;

    public Department(String dept, int empId) {
        this.dept = dept;
        this.empId = empId;
    }
    //省略了getter/setter方法
}

这里我使用了@ForeignKey关联了company表,主键id,外键emp_id,紧接着使用了indices创建了唯一索引。

下面就是创建Dao

@Dao
public interface CompanyDao {
    @Query("SELECT * FROM company")
    List<Company> getAllCompany();
}
@Dao
public interface DepartmentDao {
    @Query("SELECT * FROM department")
    List<Department> getAllDepartment();
    //使用内连接查询
    @Query("SELECT emp_id,name,dept  from company INNER JOIN department ON Company.id=Department.emp_id")
    List<InnerJoinResult> getDepartmentFromCompany();
}

最后就是创建Database

@Database(entities = {Department.class, Company.class}, version = 1, exportSchema = false)
public abstract class DepartmentDatabase extends RoomDatabase {
    public static final String DB_NAME = "CompanyDatabase.db";
    private static volatile DepartmentDatabase instance;

    public static synchronized DepartmentDatabase getInstance(Context context) {
        if (instance == null) {
            instance = create(context);
        }
        return instance;
    }

    private static DepartmentDatabase create(final Context context) {
        return Room.databaseBuilder(
                context,
                DepartmentDatabase.class,
                DB_NAME).allowMainThreadQueries().build();
    }

    public abstract DepartmentDao getDepartmentDao();

    public abstract CompanyDao getCompanyDao();
}

这里我想大家经过之前的文章介绍都很熟悉了吧。这里就不多解释了,不记得的,请看之前的文章。

具体使用

        List<Company> list = new ArrayList<>();
        Company company = new Company("Paul",32,"California",20000.0);
        list.add(company);
        company = new Company("Allen",25,"Texas",15000.0);
        list.add(company);
        company = new Company("Teddy",23,"Norway",20000.0);
        list.add(company);
        company = new Company("Mark",25,"Rich-Mond",65000.0);
        list.add(company);
        company = new Company("David",27,"Texas",85000.0);
        list.add(company);
        company = new Company("Kim",22,"South-Hall",45000.0);
        list.add(company);
        company = new Company("James",24,"Houston",10000.0);
        list.add(company);

        List<Department> departmentList = new ArrayList<>();
        Department department = new Department("IT Billing",1);
        departmentList.add(department);
        department = new Department("Engineerin",2);
        departmentList.add(department);
        department = new Department("Finance",7);
        departmentList.add(department);

        DepartmentDatabase.getInstance(this)
        .getCompanyDao().insert(list);

        DepartmentDatabase.getInstance(this)
                .getDepartmentDao().insert(departmentList);

这样我们就把需要的数据插入到数据库了,下面我们查询一下,看看有没有插入成功。

查询代码如下:

     List<Company> company = DepartmentDatabase.getInstance(this).getCompanyDao().getAllCompany();
     LogUtil.debug("Company----->" + company.size());
     for (Company result : company) {
           LogUtil.debug("result--->" + result.getName() + " " + result.getAge()+" "+result.getAddress()+" "+result.getSalary());
      }
      List<Department> department = DepartmentDatabase.getInstance(this).getDepartmentDao().getAllDepartment();
      LogUtil.debug("Department----->" + department.size());
      for (Department result : department) {
             LogUtil.debug("result--->" + result.getDept() + " " + result.getEmpId());
      }

这样看来是插入成功了的。。。

好了,下面我们要开始连表查询了。

当我们查询的时候,我们就会遇到一个问题,那就是我们关联两个表查询后的字段是companydepartemnt组合之后的。所以这里我们又需要去再次创建一个Model类。

public class InnerJoinResult {
    @ColumnInfo(name="emp_id")
    private int empId;
    private String name;
    private String dept;
    //这里同样省略了getter/setter方法
}

因为上面我们已经将查询方法写好了,直接调用即可。

 List<InnerJoinResult> company1 = DepartmentDatabase.getInstance(this).getDepartmentDao().getDepartmentFromCompany();
 LogUtil.debug("InnerJoinResult----->" + company1.size());
 for (InnerJoinResult result : company1) {
       LogUtil.debug("result--->" + result.getEmpId() + " " + result.getName() + " " + result.getDept());
  }

查询结果如下,说明我们多表查询成功了:

到这里,多表查询就结束了。未完待续

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码匠的流水账

聊聊NettyConnector的start及shutdown

reactor-netty-0.7.6.RELEASE-sources.jar!/reactor/ipc/netty/NettyConnector.java

881
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4868
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5327
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4064
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2576
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2717
来自专栏落花落雨不落叶

canvas画简单电路图

63111
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2192
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2665

扫码关注云+社区