zoukankan      html  css  js  c++  java
  • 自定义ORM框架

    ORM: Object Relational Mapping---对象关系映射

    类名---表名, 一个对象的某个属性值---某个记录, 一个对象的属性值---一条记录, 对象.属性---字段

    • 存储对象 --> dict --> Json --> Mysql
    • Mysql --> Jason --> dict --> 获取对象
    1. 一个对象中的所有属性名和属性值映射成一个字典中的keys和values
    2. 将映射字典序列化成json格式
    3. 将json格式数据编码传输到服务器
    4. 在服务器将二进制数据解码并反序列化存入mysql数据库中

    自定义元类

    '''
    自定义元类:
        继承type类, 重写__new__方法, 控制类在创建时自动对类的名称空间中的属性进行相应的操作, 包括:
            1. 一个表类的名称空间中必须要有一个表名的属性---模型表类除外
            2. 一个表类的名称空间中的所有字段属性中, 必须有且仅有一个字段的主键为True
            3. 将一个表类的名称空间中的所有字段属性放入一个独立字典中, 与名称空间中的其他属性区分开, 
               从而方便获取字段属性的属性名, 因其与字段对象中的字段名同名, 故等价于方便了字段名的获取
    '''
    
    
    # 自定义元类
    class OrmMeta(type):
        # 参数"mcs"为自定义的元类, 由"msc"来创建一个空类
        def __new__(mcs, cls_name, cls_bases, cls_dic):
    
            # 过滤掉"TableModel"类, 将其正常创建
            if cls_name == 'TableModel':
                return type.__new__(mcs, cls_name, cls_bases, cls_dic)
    
            # 保证一个表必定有一个表名
            table_name = cls_dic.get('table_name')
            if not table_name:
                cls_dic['table_name'] = cls_name
    
            # 定义一个字典存储一个表类中的所有字段对象
            field_obj_dic = {}
    
            # 保证有且仅有一个主键
            count = 0
            for key, value in cls_dic.items():  # 遍历表类的名称空间
                if isinstance(value, FieldBase):  # 过滤掉非字段对象的数据
                    field_obj_dic[key] = value  # 添加字段对象至字典
                    if value.primary_key:  # 判断主键是否存在
                        primary_key_name = key  # 记录主键的字段名
                        count += 1  # 对主键总数计数
    
            if count > 1:
                raise TypeError('只能有一个主键值!')  # 主键个数大于1报错
            if count == 0:
                key = list(field_obj_dic)[0]
                primary_key_name = field_obj_dic.get(key).field_name  # 没有主键默认将第一个字段名设为主键
    
            # 剔除类的名称空间中的字段对象数据, 节省内存空间
            for key in field_obj_dic.keys():
                cls_dic.pop(key)
    
            # 给类的名称空间添加主键
            cls_dic['primary_key_name'] = primary_key_name
    
            # 给类的名称空间添加包含一个表中的所有字段对象的字典
            cls_dic['field_obj_dic'] = field_obj_dic
    
            return type.__new__(mcs, cls_name, cls_bases, cls_dic)
    

    定义表模型类

    # 定义表模型类
    class TableModel(dict, metaclass=OrmMeta):
        # 通过"对象.属性名 = 属性值"的方式往字典对象中存储数据
        def __setattr__(self, key, value):
            self[key] = value
    
        # 通过"对象.属性名"的方式从字典对象中获取数据
        def __getattr__(self, item):
            return self.get(item)
    
    
    # 创建用户表类, 每个字段属性组合对应的字段对象
    class UserTable(TableModel):
        # 表名
        table_name = 'user_info'
    
        # 每个字段属性
        user_id = IntegerField('user_id', primary_key=True)
        user_name = StringField('user_name')
        user_pwd = StringField('user_pwd')
    
    
    # 创建电影表类
    class MovieTable(TableModel):
        movie_id = IntegerField('movie_id', primary_key=True)
        movie_name = StringField('movie_name')
        movie_pwd = StringField('movie_pwd')
    
    
    user1 = UserTable(user_id=1, user_name='tank', user_pwd='123')
    print(UserTable.__dict__)
    
  • 相关阅读:
    C# Socket编程
    C# Socket编程
    Android基础入门教程
    Android基础入门教程
    SQL Server查询事务
    SQL Server查询事务
    SQL事务用法begin tran,commit tran和rollback tran的用法
    SQL事务用法begin tran,commit tran和rollback tran的用法
    SQL Server Insert操作中的锁
    SQL Server Insert操作中的锁
  • 原文地址:https://www.cnblogs.com/-406454833/p/11807176.html
Copyright © 2011-2022 走看看