2024-04-26 02:18:18 发布
网友
我一直在编写一个数据库类,其中有我需要的每个查询的方法。在
这样做,我得到了50多种方法。在
我认为我应该编写一个小类,包含选择、删除、更新、插入等方法,然后直接将查询写到我的方法中。在
哪种方式更好?为什么?我还有别的办法吗?在
为什么不使用查询生成器或ORM呢?https://github.com/kayak/pypika 使用查询生成器获取对查询的控制粒度,并为重复任务获取ORM。在
这确实适用于python和mysql之外的上下文:
您要问的是如何设计数据库适配器,即用于与数据库通信的代码。有许多重要问题需要考虑:
为每个MySQL动词设置方法似乎很有吸引力,因为这样就不必为每个查询类型添加一个新方法,但好处就在这里了。您可能会开始将某些查询复制并粘贴到不同的位置。一旦发生这种情况,要更新查询中的任何内容(表名、列名、联接,甚至是它的工作方式的细节,可能是不同的排序顺序或限制),您必须在您复制到的每个位置修改查询。这很快就失控了。这也意味着你的控制器(假设你没有使用MVC,就把它们看作是调用你编写的这个DB包装器的代码)变成了底层DB实现的tightly coupled。这种脆性使它们更难测试。你需要设置一个数据库来测试它们。在
您当前为每种类型的查询提供方法的方法可能感觉像是更多的代码,但是您所近似的是Repository pattern。这里的想法是,我们将所有与数据库工作方式相关的行为(表名、列名、联接、外键、排序策略、缓存)抽象到几个特定的类中。对于博客文章,可能这是一个BlogPostRepository。对于注释,这可以是CommentRepository。他们会这样做:
BlogPostRepository
CommentRepository
class BlogPostRepository(Repository): def create(self, blog_post): with self._conn.cursor() as c: c.execute('INSERT ...', blog_post.name) # etc. def list(self): return [BlogPost(r) for r in self._conn.query('SELECT * FROM blog_post')]
现在,您的控制器只需将存储库作为一个arg来初始化(许多框架可以使用dependency injection)来简化这一点:
任何其他需要列出博客文章的地方都可以使用相同的代码。随后,如果需要更改列出博客文章的工作方式,只需修改BlogPostRepository中的代码。另外,在测试控制器时,可以传入模拟存储库并断言调用了正确的方法。这样,控制器测试不需要设置数据库(如果更改了数据库,这些测试也需要更改)。在
如果编写SQL查询变得很麻烦,或者您想防止需要更改底层数据库的情况,可以查看ORM。但是如果您选择使用一个,您仍然应该将ORM的使用包装在存储库模式中,这样您的控制器就不会与数据库代码紧密耦合。在
为什么不使用查询生成器或ORM呢?https://github.com/kayak/pypika 使用查询生成器获取对查询的控制粒度,并为重复任务获取ORM。在
这确实适用于python和mysql之外的上下文:
您要问的是如何设计数据库适配器,即用于与数据库通信的代码。有许多重要问题需要考虑:
为每个MySQL动词设置方法似乎很有吸引力,因为这样就不必为每个查询类型添加一个新方法,但好处就在这里了。您可能会开始将某些查询复制并粘贴到不同的位置。一旦发生这种情况,要更新查询中的任何内容(表名、列名、联接,甚至是它的工作方式的细节,可能是不同的排序顺序或限制),您必须在您复制到的每个位置修改查询。这很快就失控了。这也意味着你的控制器(假设你没有使用MVC,就把它们看作是调用你编写的这个DB包装器的代码)变成了底层DB实现的tightly coupled。这种脆性使它们更难测试。你需要设置一个数据库来测试它们。在
您当前为每种类型的查询提供方法的方法可能感觉像是更多的代码,但是您所近似的是Repository pattern。这里的想法是,我们将所有与数据库工作方式相关的行为(表名、列名、联接、外键、排序策略、缓存)抽象到几个特定的类中。对于博客文章,可能这是一个
BlogPostRepository
。对于注释,这可以是CommentRepository
。他们会这样做:现在,您的控制器只需将存储库作为一个arg来初始化(许多框架可以使用dependency injection)来简化这一点:
^{pr2}$任何其他需要列出博客文章的地方都可以使用相同的代码。随后,如果需要更改列出博客文章的工作方式,只需修改
BlogPostRepository
中的代码。另外,在测试控制器时,可以传入模拟存储库并断言调用了正确的方法。这样,控制器测试不需要设置数据库(如果更改了数据库,这些测试也需要更改)。在如果编写SQL查询变得很麻烦,或者您想防止需要更改底层数据库的情况,可以查看ORM。但是如果您选择使用一个,您仍然应该将ORM的使用包装在存储库模式中,这样您的控制器就不会与数据库代码紧密耦合。在
相关问题 更多 >
编程相关推荐