在我目前编写的应用程序中,我处理了很多MySql数据库。我知道我这样做是错误的,所以你不需要告诉我,但我该如何正确地做到这一点?同样,从.Net应用程序处理MySql数据库的正确做法是什么。
我在下课时使用的课程如下:
using System;
using MySql.Data.MySqlClient;
namespace WhateverProjectImWorkingOn
{
class MySql
{
public string myConnectionString = String.Format("SERVER={0}; DATABASE={1}; UID={2}; PASSWORD={3}", "8.8.8.8", "foobar", "foo", "barr");
public string Select(string mySqlQuery)
{
MySqlConnection connection = new MySqlConnection(myConnectionString);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
command.CommandText = mySqlQuery;
connection.Open();
Reader = command.ExecuteReader();
string thisrow = "";
while (Reader.Read())
{
for (int i = 0; i < Reader.FieldCount; i++)
{
thisrow += Reader.GetValue(i).ToString();
}
}
Reader.Close();
connection.Close();
return thisrow;
}
public void Update(string mySqlQuery)
{
MySqlConnection mangoConnection = new MySqlConnection(myConnectionString);
MySqlCommand command = mangoConnection.CreateCommand();
command.CommandText = mySqlQuery;
mangoConnection.Open();
MySqlDataReader reader = command.ExecuteReader();
mangoConnection.Close();
}
}
}
我实例化该类,然后使用Select方法选择数据:
MySql mySql = new MySql();
string whateverIWant = mySql.Select("Select `MyValue` From `FooBarr` Where `Foo` = 'Barr'");
我像这样运行更新查询:
mySql.Update("UPDATE `tblFooBarr` SET `acme`='Foo' WHERE `tnt`='barr';");
在开始之前,是的,我为自己的草率代码彻底感到羞耻,但是如果你能帮助我改进,我将非常感激!
由于
答案 0 :(得分:6)
首先,我要在MySql数据库和代码之间建立一个接口。这将您的应用程序与MySql数据库类分离;像这样的东西:
public interface IDbProvider : IDisposable
{
void Open();
void BeginTransaction();
IDataReader ExecuteReader(string query);
int ExecuteNonReader(string query);
int GetLastInsertId();
void Commit();
void Rollback();
void Close();
}
在特定于MySql的IDbProvider
实现中,您应该从ConfigurationManager.ConnectionStrings
集合中获取连接字符串,而不是对其进行硬编码。
接下来,您可以将查询放在自定义配置部分中,该部分会从您的代码中获取硬编码,特定于MySql语法的查询,如下所示:
<queries>
<SelectFoo>
<![CDATA
Select `MyValue` From `FooBarr` Where `Foo` = '{value}'
]>
</SelectFoo>
</queries>
...然后使用自定义配置提供程序通过枚举和库类将这些查询公开给您的应用程序,这将您的应用程序与使用SQL的知识分离开来:
public enum AvailableQuery
{
SelectFoo
}
public class QueryLibrary
{
private readonly AvailableQueryConfigSection _availableQueries;
public QueryLibrary()
{
this._availableQueries =
(AvailableQueryConfigSection)
ConfigurationManager.GetSection("queries");
}
public string GetQuery(AvailableQuery query)
{
// return query from availableQueries
}
}
最后,您可以使用repository类来使用QueryLibrary
来获取要发送到IDbProvider
的查询,以便它可以返回对象或执行更新,从而将应用程序与数据库:
public class FooRepository
{
public Foo GetFooByValue(string value)
{
string query = this._queryLibrary
.GetAvailableQuery(AvailableQuery.SelectFoo)
.Replace("{value}", value); // <- or better still, use parameters
using (IDataReader reader = this._dbProvider.ExecuteReader(query))
{
// Or get the values out of the reader here and pass them into
// a constructor instead of passing in the reader itself:
return new Foo(reader);
}
}
}
显然有一堆错误处理,依赖注入设置和其他内容,但希望这应该给你一个结构来开始:)
答案 1 :(得分:3)
这里没有特定的MySQL。如果您正在处理多个DBMS,那么一种方法是使用.net db接口IDbCommand,IDbConnection等。
将连接字符串放在app.config或其他类似的地方。
代码中的原始SQL,不好吗?你可以看看实体框架,LinQToSQL,一个基于存储过程的设计,但是有一个去,学习,看看有什么适合。很多原始SQL的真正问题是你的代码与你的后端有着千丝万缕的联系。管理它的诀窍是“把它放在一个地方”。一个'model'.dll,每个类中有一个接口。一旦上课处理每个表等。不要乱丢你的代码库。因为您重命名了订单表,所以在您的整个代码库中进行拖网操作,这就是禁止编号。
为什么在Update()方法中使用阅读器??? Command有一个方法。
正如@Hans所说的那样,在整个地方都有潜在的资源泄漏。
答案 2 :(得分:0)
扩展TrueWill的评论:
YourObjectMap : ClassMap<YourObject>
列出构造函数中的数据库键,关系等或使用Auto mapping - 如果您还没有/太复杂的数据库根据您的并发需求,处理会话类型,锁定,事务等