zoukankan      html  css  js  c++  java
  • 手撸ORM

     
    ORM即Object Relational Mapping,全称对象关系映射。
    当我们需要对数据库进行操作时,势必需要通过连接数据、调用sql语句、执行sql语句等操作,ORM将数据库中的表,字段,行与我们面向对象编程的类及其方法,属性等一一对应,即将该部分操作封装起来,程序猿不需懂得sql语句即可完成对数据库

    Django's ORM 
    优点:
    1. 易用,学习曲线短 
    2. 和Django紧密集合,用Django时使用约定俗成的方法去操作数据库 
    缺点:
    3. 不好处理复杂的查询,强制开发者回到原生SQL 
    4. 紧密和Django集成,使得在Django环境外很难使用 
     
    peewee 
    优点:
    5. Django式的API,使其易用 
    6. 轻量实现,很容易和任意web框架集成 
    缺点:
    7. 多对多查询写起来不直观 
     
    SQLAlchemy 
    优点:
    8. 企业级 API,使得代码有健壮性和适应性 
    9. 灵活的设计,使得能轻松写复杂查询 
    缺点:
    10. 重量级 API,导致长学习曲线 
    其它:SQLObject 、Storm 、、、、
     
    ORM 池版
    Db_pool
    from DBUtils.PooledDB import PooledDB
    import pymysql
    POOL = PooledDB(
        creator=pymysql,  # 使用链接数据库的模块
        maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
        mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
        maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
        maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
        blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
        maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
        setsession=[],  # 开始会话前执行的命令列表。
        ping=0,
        # ping MySQL服务端,检查是否服务可用。
        host='127.0.0.1',
        port=3306,
        user='root',
        password='123',
        database='youku',
        charset='utf8',
        autocommit=True
    )
    
    import pymysql
    from conf import setting
    from DBUtils.PooledDB import PooledDB
    
    POOL = PooledDB(
        creator=pymysql,  # 使用链接数据库的模块
        maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
        mincached=6,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
        maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
        maxshared=3,
        # 链接池中最多共享的链接数量,0和None表示全部共享。
        blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
        maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
        setsession=[],  # 开始会话前执行的命令列表。
        ping=0,
        # ping MySQL服务端,检查是否服务可用。
    
        host=setting.host,
        port=setting.port,
        user=setting.user,
        password=setting.password,
        database=setting.database,
        charset=setting.charset,
        autocommit=setting.autocommit
    )

    fuckorm

    from youkuServer.orm_pool import Mysql_singleton
    
    class Filepd:
        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 Setclass(Filepd):
        def __init__(self,name=None,column_type='varchar(200)',primary_key=None,default=None):
            super().__init__(name,column_type,primary_key,default)
    
    class Intclass(Filepd):
        def __init__(self,name=None,column_type='int',primary_key=None,default=0):
            super().__init__(name,column_type,primary_key,default)
    
    class Modledsclass(type):
        def __new__(cls, name,based,attrs):
            if name=='Modles':
                return type.__new__(cls,name,based,attrs)
            table_name=attrs.get('table_name',None)
    
            primary_key=None
            mappings=dict()
            for k,v in attrs.items():
                if isinstance(v,Filepd):
                    mappings[k]=v
                    if v.primary_key:
    
                        if primary_key:
                            raise TypeError('主键存在:%s'%k)
                        primary_key=k
            for k in mappings.keys():
                attrs.pop(k)
            if not primary_key:
                raise TypeError('没有主键')
            attrs['table_name']=table_name
            attrs['primary_key']=primary_key
            attrs['mappings']=mappings
            return type.__new__(cls,name,based,attrs)
    
    class Modles(dict,metaclass=Modledsclass):
        def __init__(self,**kwargs):
            super().__init__(**kwargs)
        def __setattr__(self, key, value):
            self[key]=value
    
        def __getattr__(self, item):
            try:
                return self[item]
            except TypeError:
                raise ('没有该属性')
    
        @classmethod
        def select_ont(cls,**kwargs):
            ms=Mysql_singleton.Mysql()
            key=list(kwargs.keys())[0]
            value=kwargs[key]
    
            sql='select * from %s where %s=? '%(cls.table_name,key)
            sql=sql.replace('?','%s')
            re=ms.select(sql,value)
            if re:
                u=cls(**re[0])
                return u
            else:
                return
        @classmethod
        def select_mary(cls,**kwargs):
            ms=Mysql_singleton.Mysql()
            if kwargs:
                key=list(kwargs.keys())[0]
                value=kwargs[key]
    
                sql='select * from %s where %s=?'%(cls.table_name,key)
                sql=sql.replace('?','%s')
                re = ms.select(sql, value)
            else:
                sql = 'select * from %s' % (cls.table_name)
                re = ms.select(sql)
            if re:
                lis_obj = [cls(**r) for r in re]
                return lis_obj
            else:
                return
    
        def update(self):
            ms=Mysql_singleton.Mysql()
            filde=[]
            pr=None
            args=[]
            for k,v in self.mappings.items():
                if v.primary_key:
                    pr=getattr(self,v.name,None)
                    filde.append(v.name + '=?')
                    args.append(getattr(self,v.name,v.default))
    
            sql='update %s set % where %s=%s'%(self.table_name,','.join(filde),self.primary_key,pr)
            sql=sql.replace('?','%s')
            ms.select(sql,args)
        def save(self):
            ms=Mysql_singleton.Mysql()
            filde=[]
            values=[]
            args=[]
            for k,v in self.mappings.items():
                if not v.primary_key:
                    filde.append(v.name)
                else:
                    values.append('?')
                    args.append(getattr(self,v.name,v.default))
            sql='insert into %s (%s) values (%s)'%(self.table_name,','.join(filde),','.join(values))
            sql=sql.replace('?','%s')
            ms.select(sql,args)

    Mysql_singleton

    import pymysql
    from youkuServer.orm_pool import db_pool
    
    class Mysql:
        def __init__(self):
            self.conn=db_pool.POOL.connection()
            self.cursor=self.conn.cursor(cursor=pymysql.cursors.DictCursor)
    
        def close(self):
            self.conn.close()
            self.cursor.close()
    
        def select(self,sql,args=None):
            self.cursor.execute(sql,args)
            rs=self.cursor.fetchall()
            return rs
    
        def execute(self,sql,args):
            try:
                self.cursor.execte(sql,args)
                aff=self.cursor.rowcount
            except BaseException as e:
                print(e)
            return aff

    ORM 单列版

    from youkuServer.orm import Mysql_singleton
    
    class Fileld:
        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 StringFileld(Fileld):
        def __init__(self,name=None,column_type='varchar(200)',primary_key=False,default=None):
            super().__init__(name,column_type,primary_key,default)
    
    
    
    class IntegerFileld(Fileld):
        def __init__(self,name=None,column_type='int',primary_key=False,default=0):
            super().__init__(name,column_type,primary_key,default)
    
    
    class ModlesMetaclass(type):
        def __new__(cls, name,bases,attrs):
    
            if name=='Modles':
                return type.__new__(cls,name,bases,attrs)
            table_name=attrs.get('table_name',None)
            # table_name=attrs['table_name']
    
            primary_key=None
            mappings=dict()
            for k,v in attrs.items():
                if isinstance(v,Fileld):#v 是不是Field的对象
                    mappings[k]=v
                    if v.primary_key:
    
                        #找到主键
                        if primary_key:
                            raise TypeError('主键重复:%s'%k)
                        primary_key=k
    
            for k in mappings.keys():
                attrs.pop(k)
            if not primary_key:
                raise TypeError('没有主键')
            attrs['table_name']=table_name
            attrs['primary_key']=primary_key
            attrs['mappings']=mappings
            return type.__new__(cls,name,bases,attrs)
    
    
    
    
    
    
    
    
    
    class Modles(dict,metaclass=ModlesMetaclass):
        def __init__(self,**kwargs):
            super().__init__(**kwargs)
    
    
        def __setattr__(self, key, value):
    
            self[key]=value
    
        def __getattr__(self, item):
            try:
              return self[item]
            except TypeError:
                raise ('没有该属性')
    
        @classmethod
        def select_one(cls,**kwargs):
            #只查一条
            key=list(kwargs.keys())[0]
            value=kwargs[key]
            #select * from user where id=%s
            sql='select * from %s where %s=?'%(cls.table_name,key)
            #
            sql=sql.replace('?','%s')
            ms=Mysql_singleton.Mysql().singleton()
            re=ms.select(sql,value)
            if re:
                #attrs={'name':'123','password':123}
                #u=User(**attrs)
                #相当于 User(name='123',password=123)
                u=cls(**re[0])
                return u
            else:
                return
    
        @classmethod
        def select_many(cls,**kwargs):
            ms = Mysql_singleton.Mysql().singleton()
            if kwargs:
                key=list(kwargs.keys())[0]
                value=kwargs[key]
                sql = 'select * from %s where %s=?' % (cls.table_name, key)
                #
                sql = sql.replace('?', '%s')
    
                re = ms.select(sql, value)
            else:
                sql = 'select * from %s'%(cls.table_name)
                re = ms.select(sql)
    
            if re:
                lis_obj=[cls(**r) for r in re]
                return lis_obj
            else:
                return
    
        def update(self):
            ms = Mysql_singleton.Mysql().singleton()
            #update user set name=?,password=? where id=1
    
            filed=[]
            pr=None
            args=[]
            for k,v in self.mappings.items():
    
                if v.primary_key:
                    pr=getattr(self,v.name,None)
                else:
                    filed.append(v.name + '=?')
                    args.append(getattr(self,v.name,v.default))
    
            sql = 'update %s set %s where %s =%s'%(self.table_name,','.join(filed),self.primary_key,pr)
            #'update user set name=?,password =? where id =1'
            sql=sql.replace('?','%s')
            ms.execute(sql,args)
        def save(self):
            ms = Mysql_singleton.Mysql().singleton()
            #insert into user (name,passwword) values (?,?)
            filed=[]
            values=[]
            args=[]
            for k,v in self.mappings.items():
                if not v.primary_key:
                    filed.append(v.name)
                    values.append('?')
                    args.append(getattr(self,v.name,v.default))
            sql ='insert into %s (%s) VALUES (%s)'%(self.table_name,','.join(filed),','.join(values))
            sql= sql.replace('?','%s')
            ms.execute(sql,args)

    import pymysql
    
    class Mysql:
        __instense=None
        def __init__(self):
            self.conn=pymysql.connect(
                host='127.0.0.1',
                port=3306,
                user='root',
                password='123',
                charset='utf8',
                database='youku',
                autocommit=True
            )
            self.cursor=self.conn.cursor(cursor=pymysql.cursors.DictCursor)
    
        def close_db(self):
            self.cursor.close()
            self.conn.close()
    
        def select(self, sql, args=None):
            #select * from user where id=%s
    
            self.cursor.execute(sql, args)
            rs = self.cursor.fetchall()
            return rs
    
        def execute(self, sql, args):
            try:
                #update user set name='oo' where id =%s
                self.cursor.execute(sql, args)
                affected = self.cursor.rowcount
                # self.conn.commit()
            except BaseException as e:
                print(e)
            return affected
        @classmethod
        def singleton(cls):
            if not cls.__instense:
    
                cls.__instense=cls()
    
            return  cls.__instense
    
    
    
    
    if __name__ == '__main__':
        ms=Mysql()
        re=ms.select('select * from user where id=%s',1)
        print(re)
  • 相关阅读:
    Java高级架构师(一)第04节:Git基本原理和安装配置使用
    发光边框
    单位px 转换成 rem
    web app 自适应 弹性布局之rem
    移动端UC /QQ 浏览器的部分私有Meta 属性
    常用<meta>标签
    移动端<head>头部 常用<meta>标签
    移动平台对 META 标签的定义
    减去border边框
    伪类共用样式缩写形式
  • 原文地址:https://www.cnblogs.com/maojiang/p/9064879.html
Copyright © 2011-2022 走看看