zoukankan      html  css  js  c++  java
  • ORM

    File mysql_client.py

    import pymysql

    class MySQLClient:

    def __init__(self):
        # 建立连接
        self.client = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='123',
            database='orm_demo',
            charset='utf8',
            autocommit=True
        )
    
        # 获取游标
        self.cursor = self.client.cursor(
            pymysql.cursors.DictCursor
        )
    
    # 提交查询sql语句并返回结果
    def my_select(self, sql, value=None):
        print('sql:', sql, '
    value:', value)
        self.cursor.execute(sql, value)
        res = self.cursor.fetchall()
        return res
    
    # 提交增加, 修改的sql语句
    def my_execute(self, sql, values):
        try:
            print('<sql>:', sql, '
    <values>:', values)
            self.cursor.execute(sql, values)
        except Exception as e:
            print(e)
    
    # 关闭连接
    def close(self):
        self.cursor.close()
        self.client.close()
    

    File ORM.py

    from mysql_client import MySQLClient

    定义字段类

    class Field:
    def init(self, name, column_type, primary_key, default):
    self.name = name
    self.column_type = column_type
    self.primary_key = primary_key
    self.default = default

    定义整数字段类

    class IntegerField(Field):
    def init(self, name, column_type='int', primary_key=False, default=0):
    super().init(name, column_type, primary_key, default)

    定义字符字段类

    class StringField(Field):
    def init(self, name, column_type='varchar(64)', primary_key=False, default=''):
    super().init(name, column_type, primary_key, default)

    定义元类

    class OrmMetaClass(type):
    def new(cls, class_name, class_bases, class_dict):

        if class_name == 'Models':
            return super().__new__(cls, class_name, class_bases, class_dict)
    
        # 没有表名则默认等于类名
        table_name = class_dict.get('table_name', class_name)
    
        primary_key = None
    
        # 定义一个空字典, 用来存放字段对象
        mappings = {}
    
        for key, value in class_dict.items():
            # 筛选字段对象
            if isinstance(value, Field):
                mappings[key] = value
    
                if value.primary_key:
                    if primary_key:
                        raise TypeError('只能有一个主键!')
    
                    primary_key = value.name
    
        if not primary_key:
            raise TypeError('必须有一个主键!')
    
        # 删除class_dict中和mappings重复的字段属性
        for key in mappings.keys():
            class_dict.pop(key)
    
        # 将表名添加到class_dict中
        class_dict['table_name'] = table_name
        # 将主键添加到class_dict中
        class_dict['primary_key'] = primary_key
        # 将mappings添加到class_dict中
        class_dict['mappings'] = mappings
    
        return super().__new__(cls, class_name, class_bases, class_dict)
    

    定义Models类

    class Models(dict, metaclass=OrmMetaClass):
    def getattr(self, item):
    return self.get(item)

    def __setattr__(self, key, value):
        self[key] = value
    
    # 查询
    @classmethod
    def orm_select(cls, **kwargs):  # kwargs --> {'id': 1}
    
        mysql = MySQLClient()
    
        # select * from User
        if not kwargs:
            sql = 'select * from %s' % cls.table_name
    
            res = mysql.my_select(sql)
    
        else:
            key = list(kwargs.keys())[0]
            value = kwargs.get(key)
    
            sql = 'select * from %s where %s=?' % (cls.table_name, key)
    
            sql = sql.replace('?', '%s')
    
            res = mysql.my_select(sql, value)
            
            mysql.close()
    
            # 返回的是[{}]一个普通的字典(在列表内), 我们把这个字典传入Models类, 让其可以 "对象.属性"
        return [cls(**d) for d in res]  # d是一个字典
    
    # 增加
    def orm_insert(self):
        mysql = MySQLClient()
    
        # 存字段名
        keys = []
        # 存字段值
        values = []
        # 存 "?"
        args = []
    
        for k, v in self.mappings.items():
            # 过滤主键, 因为主键是自增的
            if not v.primary_key:
                # 字段名
                keys.append(v.name)
    
                # 字段值, 没有值则使用默认值
                values.append(
                    getattr(self, v.name, v.default)
                )
    
                # 有几个字段就存放几个"?"
                args.append('?')
    
        sql = 'insert into %s (%s) values (%s)' % (
            self.table_name,
            ','.join(keys),
            ','.join(args)
        )
    
        sql = sql.replace('?', '%s')
        print(sql)
        print(values)
    
        mysql.my_execute(sql, values)
        mysql.close()
    
    # 修改
    def orm_update(self):
        mysql = MySQLClient()
    
        # 存字段名
        keys = []
        # 存字段值
        values = []
        # 主键值
        primary_key = None
    
        for k, v in self.mappings.items():
            if v.primary_key:
                # 获取主键值
                primary_key = v.name + '= %s' % getattr(self, v.name)
    
            else:
                keys.append(v.name + '=?')
                values.append(
                    getattr(self, v.name)
                )
    
        sql = 'update %s set %s where %s' % (
            self.table_name,
            ','.join(keys),
            primary_key
        )
    
        # sql: update table set k1=%s, k2=%s where id=pk
        sql = sql.replace('?', '%s')
    
        mysql.my_execute(sql, values)
        mysql.close()
    

    定义用户类

    class User(Models):
    user_id = IntegerField('user_id', primary_key=True)
    user_name = StringField('user_name')
    password = StringField('password')

    user_obj = User.orm_select(user_id=1)[0] # 查询
    print(user_obj) # {'user_id': 1, 'user_name': 'blake', 'password': '123'}
    user_obj.user_name = 'tom' # 修改user_name
    user_obj.orm_update() # 将修改提交到数据库

  • 相关阅读:
    Struts2再曝高危漏洞(S2-020补丁绕过)
    JavaWeb学习总结(十三)——使用Session防止表单重复提交
    JavaWeb学习总结(十二)——Session
    javaweb学习总结(十一)——使用Cookie进行会话管理
    如何做个好员工(转载)
    剖析云计算中的“共享型数据库”(转载)
    云计算的基本概念(转载)
    javaweb学习总结(十)——HttpServletRequest对象(一)
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    javaweb学习总结(八)——HttpServletResponse对象(二)
  • 原文地址:https://www.cnblogs.com/WQ577098649/p/11808778.html
Copyright © 2011-2022 走看看