GreenDao3.2.2建立多表之间的关联

2024-02-28 12:08

本文主要是介绍GreenDao3.2.2建立多表之间的关联,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇文章GreenDao保存List<String>类型数据中,

介绍了如何使用GreenDao保存List<String>类型的数据, 但是在实际开发中经常会遇到List的泛型并不是String类型的,而是另外一种自定义的Bean类类型。 
比如,在上一篇文章中的User代表一个用户,但是在每一个用户中可能会保存一个订单的集合–List. 那么这种情况就需要创建多个表格,并建立关系了。 
这篇文章主要以介绍如何使用ToMany来建立两张表格之间的关系

废话不多说,直接上代码

先创建MyOrder.java

@Entity
public class MyOrder {@Id(autoincrement = true)private Long id;@Property(nameInDb = "date")private String date;@Property(nameInDb = "customId")private Long customId;@Generated(hash = 1011091970)public MyOrder(Long id, String date, Long customId) {this.id = id;this.date = date;this.customId = customId;}@Generated(hash = 191667629)public MyOrder() {}public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public String getDate() {return this.date;}public void setDate(String date) {this.date = date;}public Long getCustomId() {return this.customId;}public void setCustomId(Long customId) {this.customId = customId;}}

其中customId,会用User的主键来当做此表的外键

然后再修改一下之前的User.java, 如下所示:

/*** Created by Danny.姜 on 17/6/20.** @Entity 用于标识这是一个需要Greendao帮我们生成代码的bean* @Id 标明主键,括号里可以指定是否自增* @Property 用于设置属性在数据库中的列名(默认不写就是保持一致)* @NotNull 非空*/@Entity   //  用于标识这是一个需要Greendao帮我们生成代码的bean
public class User {@Id(autoincrement = true)private Long id;@Property(nameInDb = "user_name")@NotNullprivate String name;@Convert(columnType = String.class, converter = StringConverter.class)private List<String> nickNames;@Transientprivate int temp;@ToMany(referencedJoinProperty = "customId")private List<MyOrder> orders;/** Used for active entity operations. */@Generated(hash = 1507654846)private transient UserDao myDao;/** Used to resolve relations */@Generated(hash = 2040040024)private transient DaoSession daoSession;public String getName() {return this.name;}public void setName(String name) {this.name = name;}public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public List<String> getNickNames() {return this.nickNames;}public void setNickNames(List<String> nickNames) {this.nickNames = nickNames;}/*** Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.* Entity must attached to an entity context.*/@Generated(hash = 1942392019)public void refresh() {if (myDao == null) {throw new DaoException("Entity is detached from DAO context");}myDao.refresh(this);}/*** Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.* Entity must attached to an entity context.*/@Generated(hash = 713229351)public void update() {if (myDao == null) {throw new DaoException("Entity is detached from DAO context");}myDao.update(this);}/*** Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.* Entity must attached to an entity context.*/@Generated(hash = 128553479)public void delete() {if (myDao == null) {throw new DaoException("Entity is detached from DAO context");}myDao.delete(this);}/** Resets a to-many relationship, making the next get call to query for a fresh result. */@Generated(hash = 1446109810)public synchronized void resetOrders() {orders = null;}/*** To-many relationship, resolved on first access (and after reset).* Changes to to-many relations are not persisted, make changes to the target entity.*/@Generated(hash = 1892052450)public List<MyOrder> getOrders() {if (orders == null) {final DaoSession daoSession = this.daoSession;if (daoSession == null) {throw new DaoException("Entity is detached from DAO context");}MyOrderDao targetDao = daoSession.getMyOrderDao();List<MyOrder> ordersNew = targetDao._queryUser_Orders(id);synchronized (this) {if(orders == null) {orders = ordersNew;}}}return orders;}/** called by internal mechanisms, do not call yourself. */@Generated(hash = 2059241980)public void __setDaoSession(DaoSession daoSession) {this.daoSession = daoSession;myDao = daoSession != null ? daoSession.getUserDao() : null;}@Generated(hash = 411979277)public User(Long id, @NotNull String name, List<String> nickNames) {this.id = id;this.name = name;this.nickNames = nickNames;}@Generated(hash = 586692638)public User() {}
}

其中orders是List< MyOrder>类型,因此需要建立oMany的关系。 
使用@ToMany(referencedJoinProperty = “customId”)表示在MyOrder表中可以创建多条记录,同时customId是同样的

具体使用

重新整理布局文件:

<?xml version="1.0" encoding="utf-8"?>
<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><EditTextandroid:id="@+id/editUserName"android:hint="please input user name"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/editUserNickName1"android:hint="please input user name"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/editUserNickName2"android:hint="please input user name"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:text="创建数据库"android:onClick="createDatabase"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:text="插入数据"android:onClick="insert"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:text="查询数据"android:onClick="query"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:text="查询所有"android:onClick="queryAllOrders"android:layout_width="match_parent"android:layout_height="wrap_content" /><ListViewandroid:id="@+id/listView"android:layout_width="match_parent"android:layout_height="match_parent"></ListView></LinearLayout>
</ScrollView>

修改MainActivity.java如下:

public class MainActivity extends AppCompatActivity {private DaoMaster daoMaster;private DaoSession daoSession;private UserDao userDao;private EditText editName;private ListView listView;private ArrayAdapter<String> adapter;private List<String> list = new ArrayList<>();private EditText editNickName1;private EditText editNickName2;private MyOrderDao orderDao;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editName = ((EditText) findViewById(R.id.editUserName));editNickName1 = ((EditText) findViewById(R.id.editUserNickName1));editNickName2 = ((EditText) findViewById(R.id.editUserNickName2));listView = ((ListView) findViewById(R.id.listView));adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, list);listView.setAdapter(adapter);}public void createDatabase(View view) {DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "user.db");daoMaster = new DaoMaster(helper.getWritableDb());daoSession = daoMaster.newSession();userDao = daoSession.getUserDao();orderDao = daoSession.getMyOrderDao();}public void insert(View view) {User user = new User();user.setName(editName.getText().toString());List<String> nickNames = new ArrayList<>();String nickName1 = editNickName1.getText().toString();String nickName2 = editNickName2.getText().toString();nickNames.add(nickName1);nickNames.add(nickName2);user.setNickNames(nickNames);long insertID = userDao.insert(user);if (insertID >= 0) {Toast.makeText(this, "插入 User 成功", Toast.LENGTH_SHORT).show();insertOrders(insertID);} else {Toast.makeText(this, "插入User 失败", Toast.LENGTH_SHORT).show();}}private void insertOrders(long userId) {MyOrder myOrder1 = new MyOrder(null, new Date() + "", userId);MyOrder myOrder2 = new MyOrder(null, new Date() + "", userId);long orderId1 = orderDao.insert(myOrder1);long orderId2 = orderDao.insert(myOrder2);if (orderId1 >= 0 && orderId2 >= 0) {Toast.makeText(this, "插入 MyOrder 成功", Toast.LENGTH_SHORT).show();}}public void query(View view) {List<User> users = userDao.queryBuilder().list();list.clear();for (User user : users) {String name = user.getName();List<String> nickNames = user.getNickNames();for (String nickName : nickNames) {Log.e("TAG", "query " + name + " : " + nickName);}list.add(user.getName());}adapter.notifyDataSetChanged();}public void queryAllOrders(View view) {List<User> users = userDao.loadAll();for (User user : users) {List<MyOrder> orders = user.getOrders();for (MyOrder order : orders) {Log.e("TAG", "get user " + user.getName() + " order " + order.getDate());}}}
}

解释一下:在insert方法中当插入User数据成功之后会拿到一个插入的ID,然后拿着这个ID,向MyOrder表格中插入两条MyOrder的数据。

运行成功之后,看一下数据库中的数据内容如下: 

 

可以看到在user.db中会创建USER和MY_ORDER两张表格

USER表格内容如下: 

 

在USER表格中存在两条记录,ID分别是1,2 名字依次是danny, jiang

MY_ORDER表格内容如下: 

 

因为有两条User的记录,每一个User又有两条Order的记录。 因此在MY_ORDER表格中存在4条记录主键是1,2,3,4 但是customId只有1和2

GreenDao另外一个强大的地方就在于建立多表关联之后, 查询数据也会方便很多。

我们知道在User中保存了List< MyOrder>的集合, 那我在查处所有的User集合之后,在这些User数据集合中会有MyOrder的数据吗?? 答案是肯定的 
在queryAllOrders方法中我查询的事UserDao中的数据,但是通过此UserDao还是能获取MyOrder的信息,打印log如下所示: 

具体使用方式,可以参考GreenDaoDemos : GreenDaoDemos

这篇关于GreenDao3.2.2建立多表之间的关联的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/755459

相关文章

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

Python实现PDF与多种图片格式之间互转(PNG, JPG, BMP, EMF, SVG)

《Python实现PDF与多种图片格式之间互转(PNG,JPG,BMP,EMF,SVG)》PDF和图片是我们日常生活和工作中常用的文件格式,有时候,我们可能需要将PDF和图片进行格式互转来满足... 目录一、介绍二、安装python库三、Python实现多种图片格式转PDF1、单张图片转换为PDF2、多张图