关联模型

关联模型的定义

ThinkORM支持表的一对一、一对多、多对多关联关系,标准的关联关系定义格式:

例如user.js类中申明的关联关系:

  1. const {relModel, helper} = require('thinkorm');
  2. const Profile = require('./.Profile.js');
  3. const Pet = require('./.Pet.js');
  4. const Group = require('./.Group.js');
  5. const UserGroup = require('./.UserGroup.js');
  6. module.exports = class extends relModel {
  7. init(){
  8. // 模型名称
  9. this.modelName = 'User';
  10. // 是否开启迁移(migrate方法可用)
  11. this.safe = false;
  12. // 数据表字段信息
  13. this.fields = {
  14. id: {
  15. type: 'integer',
  16. pk: true
  17. },
  18. name: {
  19. type: 'string',
  20. index: true,
  21. defaults: ''
  22. },
  23. profile: {
  24. type: 'integer',
  25. index: true,
  26. defaults: 0
  27. },
  28. num: {
  29. type: 'integer',
  30. index: true,
  31. defaults: 0
  32. },
  33. memo: {
  34. type: 'text',
  35. defaults: ''
  36. },
  37. create_time: {
  38. type: 'integer',
  39. defaults: 0
  40. }
  41. };
  42. // 数据验证
  43. this.validations = {
  44. name: {
  45. method: 'ALL', //ADD 新增时检查, UPDATE 更新时检查, ALL 新增和更新都检查,如果属性不存在则不检查
  46. valid: ['required', 'length'],
  47. length_args: 10,
  48. msg: {
  49. required: '姓名必填',
  50. length: '姓名长度必须大于10'
  51. }
  52. }
  53. };
  54. // 关联关系
  55. this.relations = {
  56. Profile: {
  57. type: 'hasone', //关联方式
  58. model: Profile, //子表模型
  59. //field: ['test', 'id'],//关联表字段
  60. fkey: 'profile', //主表外键 (子表主键)
  61. rkey: 'id' //子表主键
  62. },
  63. Pet: {
  64. type: 'hasmany',
  65. model: Pet, //子表模型
  66. //field: ['types','user', 'id'],
  67. fkey: '', //hasmany关联此值没用
  68. rkey: 'user'//子表外键 (主表主键)
  69. },
  70. Group: {
  71. type: 'manytomany',
  72. model: Group, //子表模型
  73. //field: ['name', 'type', 'id'],
  74. fkey: 'userid', //map外键(主表主键)
  75. rkey: 'groupid', //map外键(子表主键)
  76. map: UserGroup//map模型
  77. }
  78. };
  79. }
  80. };

relation属性是一个对象,对象的每一个key都代表着一个关联关系。key对应一个模型类。key的定义必须是准确的模型名。

type

关联关系类型,支持hasone,hasmany,manytomany

type的值不区分大小写,可以是hasone或者HASONE,还可以简写成1,hasmany简写为2,manytomany简写为3

field

field申明了关联模型在查询的时候筛选的字段,例如上述的Profile中field的值为['test','id'],表示关联查询Profile的时候仅返回 test及id两个字段。如果该属性不存在,在关联查询的时候默认返回关联表所有字段

fkey/rkey

fkey/rkey主要定义了关联模型中的主键及外键名,具体含义见上述注释

  1. ### 关联模型的查询
  2. 为提高执行效率,ThinkORM默认不会进行关联查询,即使模型类中已经定义了关联关系,如果需要进行关联查询,则通过Model类的rel方法来打开。
  3. #### rel\(table = false\[, fields])
  4. 类型:非中断方法
  5. 参数:
  6. table 可传入布尔值 truefalse 表示开启或关闭关联查询如果传入的是模型名,则仅关联查询传入的模型(模型类关联多个子表的情况下)
  7. fields: 指定关联查询关联表的筛选字段

.rel(true,{profile: ['name'], pet: ['types']})

  1. 作用:配合查询方法使用,是否开启表关联查询,默认为关闭。
  2. 在本章的开头,定义了UserModel类的关联关系,User模型有2个关联,分别是一对一关联Profile,一对多关联Pet。如果我们在查询中仅需要Profile的关联结果,那么可以在rel方法中传入Profile

UserModel.rel('Profile').find();//注意这里的Profile为模型名,同关联定义的key一致

  1. #### hasone关联查询

UserModel.rel('profile').find();//{"id":1,"title":"test","profile":{"test": "profile", "id": 1}}

  1. #### hasmany关联查询

UserModel.rel('ppet').find();//{"id":1,"title":"test","pet":[{"types": "cat", "user": 1, "id": 1}]}

  1. #### manytomany关联查询

UserModel.rel('group').find();//{"id":1,"title":"test","group":[{"name": "aa", "type": 1, "id": 1}]}`