精华内容
下载资源
问答
  • laravel 模型关联关系 一对一关联

    千次阅读 2019-09-29 14:24:45
    Model 模型关联关系 一对一 一对一 hasOne 反向一对一 belongsTo 一对一测试 user table public function up() { Schema::create('users', function (Blueprint $table) { $table->bigIncrements('id...

    Model 模型关联关系 一对一

    • 一对一 hasOne

    • 反向一对一 belongsTo

    • 一对一测试

    • user table

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
    
    • user Model 定义关联关系
    public function userDetail()
    {
        return $this->hasOne(UserDetail::class, 'user_id', 'id');
    }
    
    • user_details table
    public function up()
    {
        Schema::create('user_details', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('user_id')->unique()->comment('关联用户id');
            $table->string('phone')->comment('手机号');
            $table->string('nick_name', 50)->comment('昵称');
            $table->string('image', 200)->comment('图像');
            $table->tinyInteger('user_type')->default(1)->comment('用户类型,默认1,普通用户');
            $table->bigInteger('empirical_value')->default(0)->comment('经验值,默认为0');
            $table->boolean('deteled_at')->default(false)
                ->comment('用户是否注销,默认false,启用状态');
            $table->timestamps();
        });
    }
    
    • user_details model
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
    
    • 通过user模型访问user_details模型数据
    User::where('id', $id)->first()->userDetail;
    

    这里得到全是user_details表的数据,没有user表的数据

    User::where('id', $id)->with('userDetail')->first();
    

    这里得到的就是user表和user_details表的数据,user_details表的数据访问需要
    User::where('id', $id)->with('userDetail')->first()->userDetail['phone']

    通过打印查询的sql,如下:

    • hasOne
    array:2 [0 => array:3 ["query" => "select `id`, `name`, `email` from `users` where `id` = ? limit 1"
        "bindings" => array:1 [0 => "5"
        ]
        "time" => 5.59
      ]
      1 => array:3 ["query" => "select `id`, `user_id`, `phone`, `nick_name` from `user_details` where `user_details`.`user_id` in (5)"
        "bindings" => []
        "time" => 0.69
      ]
    ]
    
    • belongTo
    array:2 [0 => array:3 ["query" => "select * from `user_details` where `id` = ? limit 1"
        "bindings" => array:1 [0 => "5"
        ]
        "time" => 76.86
      ]
      1 => array:3 ["query" => "select * from `users` where `users`.`id` in (5)"
        "bindings" => []
        "time" => 1.45
      ]
    ]
    

    可以看到一对一的关联关系,他们的查询语句是分开查询的,就是得到一个结果之后,然后拿到关联数据再做in的查询,并不是我想象中的做join连表查询。

    • 关联关系中得到指定的字段
    1. 使用select()方法得到的就是当前模型的筛选字段,这个地方不要添加with()关联表的字段

    2. 想要得到with()关联表指定的字段,有三个方法,

    2.1 在定义关联关系时候,使用select()方法固定写死,这样的话,就不灵活。

    2.2 使用with()方法的时候,自定义指定,with()方法可以传递一个字符串或者数组

    2.2.1 传递数组的写法,键是关联模型中定义的方法,值是一个闭包函数,传递一个参数$query,然后链式调用查询方法即可

    $user = User::where('id', $id)->select('id', 'name', 'email')
            ->with(['userDetail' => function($query){
                $query->select('user_id', 'phone', 'nick_name');
            }])
            ->first();
    

    2.2.2 还是传递数组,不过不传递闭包,官方文档

    注意:在使用这个特性时,一定要在要获取的列的列表中包含 id 列。

    $user = User::where('id', $id)->select('id', 'name', 'email')
            ->with(['userDetail:id,user_id,phone,nick_name'])
            ->first();
    

    建议就是:如果没有别的条件限制,那就使用第二种,如果有条件限制那就使用闭包的查询方法


    (github地址)[https://github.com/lijianguo1211/get/blob/master/PHP/PHP-frame/laravel/laravel-relation/Relation%EF%BC%88%E4%B8%80%EF%BC%89.md]

    展开全文
  • 主要实现模型对象到关系数据库数据的映射. 和Java中的JDBC 有异曲同工之处 优点 通过改变数据库模型改变表结构 通过模型类进行数据库的增删改查操作. 只需要面向对象编程, 不需要面向数据库编写代码. 数据库的...

    ORM 全拼 Object-Relation Mapping. 中文意为 对象-关系映射. 主要实现模型对象到关系数据库数据的映射. 和Java中的JDBC 有异曲同工之处

    优点

    • 通过改变数据库模型改变表结构
    • 通过模型类进行数据库的增删改查操作.
    • 只需要面向对象编程, 不需要面向数据库编写代码.
      • 对数据库的操作都转化成对类属性和方法的操作.
      • 不用编写各种数据库的sql语句.
    • 实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
      • 不在关注用的是mysql、oracle…等.
      • 通过简单的配置就可以轻松更换数据库, 而不需要修改代码.

    缺点

    • 相比较直接使用SQL语句操作数据库,有性能损失.
    • 根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.

    关系

    关系的分类

    • 一对一1, 几乎不用
    • 一对多( 或多对一 )
    • 多对多

    SQLALchemy

    • SQLALchemy 实际上是对数据库的抽象,让开发者不用直接和 SQL 语句打交道,而是通过 Python 对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升
    • SQLAlchemy是一个关系型数据库框架,它提供了高层的 ORM 和底层的原生数据库的操作。flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。

    一对多( 或多对一 )

    这里写图片描述

    如图, 一个角色可以有多个用户. 如果用户是管理员角色, 就不能是普通用户; 如果用户是VIP会员, 就不能是普通用户.

    db_model.py

    
    from datetime import datetime 
    from application import db
    
    
    # 设置基类方便管理公共字段
    class BaseModel(object):
        id = db.Column(db.Integer, primary_key=True)  # 主键
        is_del = db.Column(db.Boolean, default=False)  # 默认为False,不删除/显示;当为True时,删除/不显示
        create_time = db.Column(db.DateTime, default=datetime.now)  # 记录的创建时间
        update_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)  # 记录的更新时间
    
    # 多继承,通过列表或者元组继承,坏处:父类属性不提示
    base_db_model = (BaseModel, db.Model)
    
    
    # 角色类
    class Role(db.Model):
        """角色类"""
        __tablename__ = "role"
    
        id = db.Column(db.Integer, primary_key=True)  # 角色id
        name_role = db.Column(db.String(32))  # 角色名称
    
        # 关联引用 Role关联User
        # db.relationship("要关联的数据库模型类", lazy='dynamic')
        list_user = db.relationship("User", lazy='dynamic')
    
    
    # 用户表, 通过拆包base_db_model 多继承
    class User(*base_db_model):
        """用户表"""
        __tablename__ = "user"
    
        name_nick = db.Column(db.String(32), nullable=False)  # 昵称
        password_hash = db.Column(db.String(128), nullable=False)  # 密码
        mobile = db.Column(db.String(128), unique=True, nullable=False)  # 手机号码
    
        id_role = db.Column(db.Integer, db.ForeignKey("role.id"), default=2)  # 角色id
    
    
    
    

    在role 指定了一个单向的关联关系, role 关联user, 那么怎么让user 关联role?如下

    
    class User(*base_db_model):
        """用户表"""
        __tablename__ = "user"
    
        name_nick = db.Column(db.String(32), nullable=False)  # 昵称
        password_hash = db.Column(db.String(128), nullable=False)  # 密码
        mobile = db.Column(db.String(128), unique=True, nullable=False)  # 手机号码
    
        id_role = db.Column(db.Integer, db.ForeignKey("role.id"), default=2)  # 角色id
    
        # 添加关联关系  user关联role
        role = db.relationship("Role", lazy='dynamic') 
    
    

    合并,将两个单向的关联关系合并成一个双向的关系

    
    # 角色类
    class Role(db.Model):
        """角色类"""
        __tablename__ = "role"
    
        id = db.Column(db.Integer, primary_key=True)  # 角色id
        name_role = db.Column(db.String(32))  # 角色名称
    
        # 通过relationship 指定正向引用, backref 指定反向引用 ,构成一个双向的引用关系
        list_user = db.relationship("User", backref="role" , lazy='dynamic')
    
    
    # 用户表, 通过拆包base_db_model 多继承
    class User(*base_db_model):
        """用户表"""
        __tablename__ = "user"
    
        name_nick = db.Column(db.String(32), nullable=False)  # 昵称
        password_hash = db.Column(db.String(128), nullable=False)  # 密码
        mobile = db.Column(db.String(128), unique=True, nullable=False)  # 手机号码
    
        id_role = db.Column(db.Integer, db.ForeignKey("role.id"), default=2)  # 角色id
    
    

      user 表
      这里写图片描述
      role 表
      这里写图片描述

      运行结果

      这里写图片描述
      根据Debug结果

      • 一对多, user 表(多的一方) 定义外键, role 表 (一的一方) 定义关系引用.
      • list_user = db.relationship(“User”, backref=”role” , lazy=’dynamic’)
        • relationship 指定正向关系引用, 在这里是role 向user 的方向, 既一对多的方向
        • backref 指定反向关系引用, 在这里是user 向role 的方向, 既多对一的方向
        • lazy 决定了什么时候SQLALchemy从数据库中加载数据
          • lazy=”subquery”, 默认方式, 子查询方式. 当加载查询对象时, 直接加载关联对象的数据. 如果本次查询不需要关联对象的数据或者关联对象的数据数量庞大, 就造成了浪费或者加载缓慢的问题.
          • lazy=”dynamic”, 动态方式. 不会直接加载关联对象的数据( users ), 只有在使用关联对象数据的时候才会进行加载(users_).
          • lazy=”dynamic”, ‘dynamic’ loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False (不能与多对一 / 一对一关系 和/或 uselist = False一起使用)。

      一个表的两个外键都是同一张表的主键

      这里写图片描述

      如图, 因为用户有角色, 当用户(角色) 发布新闻, 经过编辑(角色) 审核. 通过审核之后, 如果出现什么问题, 责任人是编辑, 而不是用户. 如果有以上的需求就出现了news 表的id_author 和id_charge_editor 字段的外键都是user 表的主键. 数据库是允许这样设计的, 那么SQLAlchemy 中怎样表示这样的关系?

      
      # 一个用户可以发布多篇新闻
      list_news = db.relationship("News", foreign_keys=[News.id_author], backref="author", lazy="dynamic")
      
      # 一个编辑可以编辑多篇新闻
      list_edit_news = db.relationship("News", foreign_keys=[News.id_charge_editor], backref="editor", lazy="dynamic")
      
      
      
      

      和一个表中只有一个外键是另一张表中的主键类似, relationship 指定关系引用, backref 指定反向的关系引用. 区别在于foreign_keys, foreign_keys 指定关系引用作用的于哪个外键, 或者说关系引用作用于主键与哪个外键之间的关联关系.

      多对多

      这里写图片描述

      如图, 用户和评论之间是一个多对多的关系, 一个用户可以给多条评论点赞, 一条评论可以被多个用户点赞. 从图上可以很容易的看出, 多对多是由两个一对多构成的, 并且有一张表存储着是多对多的关系.

      数据库模型

      
      # 评论点赞
      class CommentPraise(*base_db_model):
          """评论点赞"""
      
          __tablename__ = "comment_praise"
      
          id_comment = db.Column(db.Integer, db.ForeignKey("comment.id"))  # 评论id
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
      
      # 评论表
      class Comment(*base_db_model):
          """评论表"""
      
          __tablename__ = "comment"
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
          id_news = db.Column(db.Integer, db.ForeignKey("news.id"))  # 新闻id
          id_parent = db.Column(db.Integer, db.ForeignKey("comment.id"))  # 父评论id
      
          content = db.Column(db.Text, nullable=False)  # 评论内容
          praise_num = db.Column(db.Integer, default=0)  # 点赞数(喜欢数)
      
      
      # 用户表
      class User(*base_db_model):
          """用户表"""
          __tablename__ = "user"
      
          name_nick = db.Column(db.String(32), nullable=False)  # 昵称
          password_hash = db.Column(db.String(128), nullable=False)  # 密码
          mobile = db.Column(db.String(128), unique=True, nullable=False)  # 手机号码
      
          id_role = db.Column(db.Integer, db.ForeignKey("role.id"), default=2)  # 角色id
          last_login = db.Column(db.String(32), default=datetime.now)  # 最后登录时间
          is_login = db.Column(db.Boolean, default=False)  # 是否登录
          gender = db.Column(db.Enum("man", "woman"), default="man")
      
          last_login_ip = db.Column(db.String(64))  # 最后登录ip
          avatar_url = db.Column(db.String(256))  # 头像
          signature = db.Column(db.String(512))  # 个性签名
      
          # 当前用户发布的所有评论
          list_user_comment = db.relationship("Comment", backref="user", lazy="dynamic")
      
          # 当前用户点赞的所有评论
          list_user_praise_comment = db.relationship("Comment", secondary="comment_praise",
                                                     # 当前评论点赞的所有用户
                                                     backref=db.backref('list_praise_comment_user', lazy='dynamic'),
                                                     lazy="dynamic")
      
      

      如上数据库模型, 在user 类中建立与Comment 的一对多关系引用.
      对于多对多的关系

      • 将关联关系放到第三张表中( comment_praise )
      • 在user 或者 comment 中通过relationship 指定关联关系,
      • 通过secondary 指定关联关系存放的地方

      另一种写法

      
      # 通过Table 类得到Table 类的对象association_table 
      association_table = Table('association', Base.metadata,
          Column('left_id', Integer, ForeignKey('left.id')),
          Column('right_id', Integer, ForeignKey('right.id'))
      )
      
      class Parent(Base):
          __tablename__ = 'left'
          id = Column(Integer, primary_key=True)
          children = relationship("Child",
                          # secondary = association_table Table类的对象
                          secondary=association_table,
                          backref="parents")
      
      class Child(Base):
          __tablename__ = 'right'
          id = Column(Integer, primary_key=True)
      
      

      secondary 常见方式是使用Table 类的对象作为值, 也可以使用表名字符串作为值.

      暂时未找到通过Table 作为数据库模型怎样继承基类的方式, 所以暂时算作是一种缺陷. 使用继承db.Model 的方式可以方便继承.

      特殊的多对多

      这里写图片描述

      如图,新闻类型和新闻分类是一个多对多关系, 一个类型可以有多个分类的新闻, 一个分类可以有多个类型的新闻. 刚刚建立这个关系的时候一脸蒙圈, 关系存放在哪里? 单独摘出这一部分瞬间明白了, news 本身就是一个表, 当然可以作为type 与category 的关联关系表了, 不需要额外创建第四张表.

      
      # 新闻类型
      class NewsType(db.Model):
          """新闻类型"""
          __tablename__ = "news_type"
      
          id = db.Column(db.Integer, primary_key=True)  # 新闻类型id
          name_type = db.Column(db.String(32))  # 新闻类型
      
          list_news = db.relationship("News", backref="news_type", lazy='dynamic')
      
          # 当前新闻类型所属于的所有分类
          list_news_category = db.relationship('NewsCategory', secondary="news", 
                                               backref=db.backref('list_news_type', lazy='dynamic'),
                                               lazy='dynamic')
      
      
      # 新闻分类
      class NewsCategory(db.Model):
          """新闻分类"""
      
          __tablename__ = "news_category"
      
          id = db.Column(db.Integer, primary_key=True)  # 新闻类型id
          name_type = db.Column(db.String(32))  # 新闻类型
      
          list_news = db.relationship("News", backref="news_category", lazy='dynamic')
      
      

      按照多对多的规则, 在NewsType 或者 NewsCategory 定义一个双向的关系引用. 这里在NewsType 定义了关系引用, 关联关系存放在News 表中.

      自关联

      一对多( 多对一 )

      这里写图片描述

      一个父评论可以有多个子评论, 评论表的一对多自关联

      
      # 评论表
      class Comment(*base_db_model):
          """评论表"""
      
          __tablename__ = "comment"
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
          id_news = db.Column(db.Integer, db.ForeignKey("news.id"))  # 新闻id
          id_parent = db.Column(db.Integer, db.ForeignKey("comment.id"))  # 父评论id
      
          content = db.Column(db.Text, nullable=False)  # 评论内容
          praise_num = db.Column(db.Integer, default=0)  # 点赞数(喜欢数)
      
          parent = db.relationship("Comment", remote_side="comment.c.id",
                                   backref=db.backref('childs', lazy='dynamic'))
      
      
      

      自关联一对多, 其本质也是一对多, 只不过两端都是一张表, 所以和一对多基本类似.

      • 在一的一方定义关系, 在多的一方定义外键, 两端都是一张表, 所以外键 和 关联关系在同一个数据库模型类里.
      • 在类中定义外键 id_parent = db.Column(db.Integer, db.ForeignKey(“comment.id”)) # 父评论id
      • 在类中定义关系 parent = db.relationship(“Comment”, remote_side=”comment.c.id”,backref=
        db.backref(‘childs’, lazy=’dynamic’))
      • 通过remote_side 指定远端主键
        • remote_side=”comment.c.id” 等价 remote_side=[id]

      多对多

      这里写图片描述

      如图, 一个用户可以有多个粉丝, 一个用户可以被多个人关注, 用户表的多对多自关联

      
      # 用户粉丝表
      class FollowsUser(*base_db_model):
          """用户粉丝表"""
      
          __tablename__ = "user_follows"
      
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
          id_follower = db.Column(db.Integer, db.ForeignKey("user.id"))  # 新闻id
      
      # 用户表
      class User(*base_db_model):
          """用户表"""
          __tablename__ = "user"
      
          name_nick = db.Column(db.String(32), nullable=False)  # 昵称
          password_hash = db.Column(db.String(128), nullable=False)  # 密码
          mobile = db.Column(db.String(128), unique=True, nullable=False)  # 手机号码
      
          id_role = db.Column(db.Integer, db.ForeignKey("role.id"), default=2)  # 角色id
          last_login = db.Column(db.String(32), default=datetime.now)  # 最后登录时间
          is_login = db.Column(db.Boolean, default=False)  # 是否登录
          gender = db.Column(db.Enum("man", "woman"), default="man")
      
          last_login_ip = db.Column(db.String(64))  # 最后登录ip
          avatar_url = db.Column(db.String(256))  # 头像
          signature = db.Column(db.String(512))  # 个性签名
      
          followers = db.relationship('User',
                                      secondary="user_follows",
                                      primaryjoin="user.c.id == user_follows.c.id_user",
                                      secondaryjoin="user.c.id == user_follows.c.id_follower",
                                      backref=db.backref('user', lazy='dynamic'),
                                      lazy='dynamic')
      
      

      自关联多对多, 其本质也是多对多, 只不过两端都是一张表, 所以和多对多基本类似, 同时多对多是两个一对多组成的, 并且是自关联, 所以类似于两个自关联一对多.

      • 需要第三张表存储关联关系 user_follows
      • 两端都是自己需要进行区分, 在自关联多对多中使用primaryjoin 和/或 secondaryjoin 进行区分.
        • primaryjoin 一个SQL表达式,它将用作此子对象与父对象的主要连接,或者在多对多关系中,主对象与关联表的连接. 默认情况下,此值基于父表和子表(或关联表)的外键关系计算。
        • secondaryjoin 一个SQL表达式,将用作关联表与子对象的连接。默认情况下,此值基于关联和子表的外键关系计算。

      关联关系模板

      多表之间

      一对多

      
      class Role(db.Model):
          """角色表"""
          __tablename__ = 'roles'
      
          id = db.Column(db.Integer, primary_key=True) 
          users = db.relationship('User', backref='role', lazy='dynamic')
      
      class User(db.Model):
          """用户表"""
          __tablename__ = 'users'
          id = db.Column(db.Integer, primary_key=True) 
      
      

      多对多

      通过Table 类

      
      tb_student_course = db.Table('tb_student_course',
                                   db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
                                   db.Column('course_id', db.Integer, db.ForeignKey('courses.id'))
                                   )
      
      class Student(db.Model):
          __tablename__ = "students"
          id = db.Column(db.Integer, primary_key=True) 
      
          courses = db.relationship('Course', secondary=tb_student_course,
                                    backref=db.backref('students', lazy='dynamic'),
                                    lazy='dynamic')
      
      class Course(db.Model):
          __tablename__ = "courses"
          id = db.Column(db.Integer, primary_key=True) 
      

      通过Model

      
      # 评论点赞  db SQLAlchemy的实例对象
      class CommentPraise(db.Model):
          """评论点赞"""
      
          __tablename__ = "comment_praise"
      
          id_comment = db.Column(db.Integer, db.ForeignKey("comment.id"))  # 评论id
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
      
      # 评论表
      class Comment(db.Model):
          """评论表"""
      
          __tablename__ = "comment"
      
          id = db.Column(db.Integer, primary_key=True)  
      
      
      # 用户表
      class User(db.Model):
          """用户表"""
          __tablename__ = "user"
      
          id = db.Column(db.Integer, primary_key=True)  
      
          # 当前用户点赞的所有评论
          list_user_praise_comment = db.relationship("Comment", secondary="comment_praise",
                                                     # 当前评论点赞的所有用户
                                                     backref=db.backref('list_praise_comment_user', lazy='dynamic'),
                                                     lazy="dynamic")
      

      自关联

      一对多

      
      class Comment(db.Model):
          """评论"""
          __tablename__ = "comments"
      
          id = db.Column(db.Integer, primary_key=True) 
      
          parent_id = db.Column(db.Integer, db.ForeignKey("comments.id"))
      
          parent = db.relationship("Comment", remote_side=[id],
                                   backref=db.backref('childs', lazy='dynamic'))
      
      

      多对多

      通过Table

      
      tb_user_follows = db.Table(
          "tb_user_follows",
          db.Column('follower_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True),  # 粉丝id
          db.Column('followed_id', db.Integer, db.ForeignKey('info_user.id'), primary_key=True)  # 被关注人的id
      )
      
      class User(db.Model):
          """用户表"""
          __tablename__ = "info_user"
      
          id = db.Column(db.Integer, primary_key=True)   
      
          # 用户所有的粉丝,添加了反向引用followed,代表用户都关注了哪些人
          followers = db.relationship('User',
                                      secondary=tb_user_follows,
                                      primaryjoin=id == tb_user_follows.c.followed_id,
                                      secondaryjoin=id == tb_user_follows.c.follower_id,
                                      backref=db.backref('followed', lazy='dynamic'),
                                      lazy='dynamic')
      
      

      通过Model

      
      
      # 用户粉丝表
      class FollowsUser(db.Model):
          """用户粉丝表"""
      
          __tablename__ = "user_follows"
      
          id_user = db.Column(db.Integer, db.ForeignKey("user.id"))  # 用户id
          id_follower = db.Column(db.Integer, db.ForeignKey("user.id"))  # 新闻id
      
      # 用户表
      class User(db.Model):
          """用户表"""
          __tablename__ = "user"
      
          id = db.Column(db.Integer, primary_key=True)    
      
          followers = db.relationship('User', secondary="user_follows",
                                      primaryjoin="user.c.id == user_follows.c.id_user",
                                      secondaryjoin="user.c.id == user_follows.c.id_follower",
                                      backref=db.backref('user', lazy='dynamic'),
                                      lazy='dynamic')
      
      
      展开全文
    • 表与表之间的关系:hasOne 一对一( $fields, $referenceModel, $referencedFields : 当前表中的字段, 对应关系模型, 对应关系模型中表的字字段 ) hasMany 一对多 ( $fields, $referenceModel, $...

      Model:

      表与表之间的关系:hasOne 一对一( $fields, $referenceModel, $referencedFields : 当前表中的字段, 对应关系模型, 对应关系模型中表的字字段 )

      hasMany 一对多 ( $fields, $referenceModel, $referencedFields : 当前表中的字段, 对应关系模型, 对应关系模型中表的字字段 )

      hasManyToMany 多对多

      belongsTo 多对一( 属于 ) ( $fields, $referenceModel, $referencedFields : 当前表中的字段, 对应关系模型, 对应关系模型中表的字字段 )

      如项目中存在命名空间 则 要在对应的关系中添加alias参数 array( 'alias' => 'namespace' )

      例:多对一

      $this->belongsTo('company_id', 'App\Models\ErpCompanys', 'id', ['alias' => 'ErpCompanys']);
      取得关联表中name信息的phalcon代码:

      public function userCarAction(){
              if($this->request->isPost()){
                  $this->view->disable();
                  $info = ErpCompanyCar::findFirst();
                  $name = $value->ErpCompanys->name;
              }
              
          }

      官方文档地址:https://docs.phalconphp.com/zh/latest/reference/model-relationships.html#relationships-between-models



      展开全文
    • 数据库中的数据表之间的关系包括一对一,一对多,多对多,它们分别使用关键字OneToOneField,ForeignKey,ManyToManyFiled进行定义,之前已经写了一对多,多对多介绍以及使用,准备再找一个时间写一下它们之间的一个...

         数据库中的数据表之间的关系包括一对一,一对多,多对多,它们分别使用关键字OneToOneField,ForeignKey,ManyToManyFiled进行定义,之前已经写了一对多,多对多介绍以及使用,准备再找一个时间写一下它们之间的一个区别,这三种关系中比较让你不好理解的可能就是一对一和一对多的区别了,暂时按下不表

           首先还是举一个比较常见的一对一的关系:银行账户(Account)和联系人(Contact),一个银行账户对应一个联系人,而一个联系人也只对应一个账户

           在models.py创建数据模型:

                这里创建了两个数据模型一个是Account(账户)里面包含三个属性username,password,register_date,另外一个是Contact(联系人)包含了四个属性,address(联系人地址),code(邮编),mobile(联系人手机)以及关联两张表的外键account

             OneToOneField的第一个参数是被关联的模型的名称,第二个参数表示级联删除,这个已经在之前的博客里面讲过了,当Account数据表里面的数据被删除后Contact里面的数据也随着被删除

               接下来执行数据迁移命令,并查看sql语句:

               

          那么一对一关系中如何进行对数据的操作,现在在python  shell中进行演示: 

           这里主要进行的数据的添加和在一对一关系中如何正向查询和反向查询

          数据添加操作:

           from blog.models import Account,Contact

           a1 = Account.objects.create(username='leeyongbard',password='123')

           a1.save()

          c1 = Contact.objects.create(address='zh',code='45000',mobile='15735896033',account=a1)

          c1.save()

          数据表如下:

          

         查询操作:

         正向查询:通过账户查询对应的联系人的信息

        a1.contact.address

        a1.contact.code


      反向查询通过联系人查询账户信息:

        

       删除操作:

      删除账户信息,则对应的联系人信息也会被删除:

      a1.contact.delete()


        

      展开全文
    • Model 模型关联关系 一对多 - 多对一 一对多 hasMany() 一对多反向 belongsTo() 定义关系,一个用户可以发布多篇文章,每一篇文章对应一个用户,用户对文章是一对多,文章对用户就是一对多反向,多对一。 ...
    • 官方文档可能说的不是很详细 因为我们项目构建的时候一般都不是直接在model目录创建文件的,命名空间都会加一层,这种情况用关联模型要注意。...总结:在Phalcon中,关系必须写在模型的 initialize() 方法中, ...
    • 一、概念模型  (1)对象模型:可以双向关联,而且引用的是对象,而不是一个主键!    (2)关系模型:只能多方引用一方,而且引用的只是主键,而不是一整行... (2)一对一关系 (3)多对多关系
    • 在powerdesigner使用概念模型生成逻辑模型一对关系的时候(错误无关关系),本来应该生成的外键在LDM中并没有显示出来。图示如下: 看这个看不出来哪里错误了。但是我还是要把他放上来。看起来没错。那就是内在错...
    • 其中film模型是电影模型,comment是评论模型,评论是针对电影的评论,也就是一条评论只针对一部电影,但是一部电影可以有多个评论,这就是film和comment一对多的关系,在建立数据模型时,一定要搞明白一对多的关系,...
    • 一对一的表关系 实现一对一 主要是对关联的字段进行唯一约束 CREATE TABLE `woman` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `hid` int(10) unsigned DEFAULT ...
    • 1. 一对一的表,两表的属性实际上完全可以合并成一个表,共用一个主键即可; 2. 一对多的表,可以设中间关联表,也可以将关联表并入“多”这头;若设独立关联表,则可引入“多”这头的主键作为其主键,也可另立主键...
    • 数据库中,一对一关系:从表的主键既是外键。 CREATE TABLE hasbend( -- 创建主表 hid INT PRIMARY KEY auto_increment, -- 指定字段 hname VARCHAR(50) ); ALTER TABLE hasbend -- 修改表名 REMOVE TO ...
    • Django 模型种可以定义三种最常见的数据库关联关系:多对一,多对多,一对一。我们先来讲讲多对一关联关系。 1 定义 使用 django.db.models.ForeignKey 类,就可以定义出一个多对一的关联关系。在模型中,添加一个值...
    • 一对一、一对多、多对多模型关系的建立和增删改查要注意的问题 一对一: 1.在维护关系的一方使用:models.OneToOneField(另一个一方模型类名称,on_delete=models.CASCADE) eg: from django.db import models ...
    • 对一关系模型:  · 首先是导包;这个省略不写了,  · 其次写domain类 分为Client Order两个类,因为是多对一的关系,所以外键应该放在Order这个类里; 配置文件:hibernate.cfg.xml ...
    • 迄今为止,我们只是泛泛地讨论了线程。...本节研究三种常用的建立这种关系的方法:多对一模型一对一模型和多对多模型。 多对一模型 图 1 多对一模型 多对一模型(图 1)映射多个用户级线程到一
    • 一对多关系 models.ForeignKey() # 定义在多的类中...一对一关系 models.OneToOneField() # 定义在哪个类中都可以。   一对多关联: 应用名/models.py(模型,定义模型类,models.ForeignKey): from...
    • 模型间的一对关系

      千次阅读 2011-12-30 00:00:55
      模型间的一对关系 //注册用户数据模型User Ext.regModel('User', { fields: [//定义模型字段 {name: 'name', type: 'string'},//用户名称 {name: 'id', type: 'int'}//用户id

    空空如也

    空空如也

    1 2 3 4 5 ... 20
    收藏数 16,757
    精华内容 6,702
    关键字:

    一对一关系模型