C++語法復雜,寫一個示例通過T4可生成c++代碼
需求:資料庫,生成c++增,刪,改,查代碼
- 資料生成c++類,包含所有欄位
- 自動識別資料的主鍵Key
- 查詢生成賦值類欄位,型別轉換
- 通過類自動生成sql的where條件
- 類改變一些欄位值,自動生成update sql
- 生成所有欄位列印代碼
class Actor_Entry; //資料庫物體類
class Actor_UpdateEntry;//更新物體類
class Actor //物體增,刪,改,查類
{
public:
bool Select(MYSQL* connect, const std::string& sql, std::vector<Actor_Entry>& out);
bool SelectAll(MYSQL* connect, std::vector<Actor_Entry>& v);
bool Update(MYSQL* connect, const Actor_UpdateEntry& set, const Actor_UpdateEntry& where, const std::string& whereSql);
bool Update(MYSQL* connect, const std::string& whereSql);
bool Insert(MYSQL* connect, Actor_UpdateEntry& v);
bool Delete(MYSQL* connect, const Actor_UpdateEntry& v);
};
class Actor_Entry
{
public:
std::string ToString();
static Actor_Entry& New();//方便拷貝代碼
short int GetKey() const;
// 資料欄位,及型別映射
// 主鍵(自動識別主鍵)
short int Actor_Id;
std::string First_Name;
std::string Last_Name;
std::string Last_Update;
};
//欄位發生改變,自動生成sql
class Actor_UpdateEntry : public Actor_Entry
{
public:
Actor_UpdateEntry();
static Actor_UpdateEntry& New();//方便拷貝代碼
bool IsModified() const;
void ResetModified();
void Set_Actor_Id(const short int value);
bool Actor_Id_Modified;
void Set_First_Name(const std::string& value);
bool First_Name_Modified;
void Set_Last_Name(const std::string& value);
bool Last_Name_Modified;
void Set_Last_Update(const std::string& value);
bool Last_Update_Modified;
};
一個資料庫,不到10s生成7000+行代碼

實作方式:
讀取表結構:
public static IEnumerable<TABLE_SCHEMA_> GetTableSchemaEnumerable(MySqlConnectionStringBuilder builder)
{
using (var conn = GetConnection(builder))
{
var sql =
$"SELECT DISTINCT t.`TABLE_COMMENT`, c.* FROM information_schema.`COLUMNS` as c INNER join INFORMATION_SCHEMA.`TABLES` t on c.`TABLE_NAME`= t.`TABLE_NAME` where c.TABLE_SCHEMA = '{builder.Database}';";
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var obj = new TABLE_SCHEMA_();
obj.TABLE_COMMENT = reader[nameof(obj.TABLE_COMMENT)].DbCast<string>();
obj.TABLE_NAME = reader[nameof(obj.TABLE_NAME)].DbCast<string>();
obj.TABLE_CATALOG = reader[nameof(obj.TABLE_CATALOG)];
obj.TABLE_SCHEMA = reader[nameof(obj.TABLE_SCHEMA)];
obj.TABLE_NAME = reader[nameof(obj.TABLE_NAME)].DbCast<string>();
obj.COLUMN_NAME = reader[nameof(obj.COLUMN_NAME)].DbCast<string>();
obj.ORDINAL_POSITION = reader[nameof(obj.ORDINAL_POSITION)].DbCast<uint>();
obj.COLUMN_DEFAULT = reader[nameof(obj.COLUMN_DEFAULT)];
{
var v = reader[nameof(obj.IS_NULLABLE)];
obj.IS_NULLABLE = "Yes".EqualsByIgnoreCaseEx(v.DbCast<string>());
}
obj.DATA_TYPE = reader[nameof(obj.DATA_TYPE)].DbCast<string>();
obj.CHARACTER_MAXIMUM_LENGTH = reader[nameof(obj.CHARACTER_MAXIMUM_LENGTH)].DbCast<long?>();
obj.CHARACTER_OCTET_LENGTH = reader[nameof(obj.CHARACTER_OCTET_LENGTH)].DbCast<long?>();
obj.NUMERIC_PRECISION = reader[nameof(obj.NUMERIC_PRECISION)];
obj.NUMERIC_SCALE = reader[nameof(obj.NUMERIC_SCALE)];
obj.DATETIME_PRECISION = reader[nameof(obj.DATETIME_PRECISION)];
obj.CHARACTER_SET_NAME = reader[nameof(obj.CHARACTER_SET_NAME)].DbCast<string>();
obj.COLLATION_NAME = reader[nameof(obj.COLLATION_NAME)].DbCast<string>();
obj.COLUMN_TYPE = reader[nameof(obj.COLUMN_TYPE)].DbCast<string>();
obj.COLUMN_KEY = reader[nameof(obj.COLUMN_KEY)].DbCast<string>();
obj.EXTRA = reader[nameof(obj.EXTRA)];
obj.PRIVILEGES = reader[nameof(obj.PRIVILEGES)];
obj.COLUMN_COMMENT = reader[nameof(obj.COLUMN_COMMENT)].DbCast<string>();
obj.GENERATION_EXPRESSION = reader[nameof(obj.GENERATION_EXPRESSION)];
obj.SRS_ID = reader[nameof(obj.SRS_ID)];
yield return obj;
}
}
}
}
}
用t4生成c++代碼:
bool <#= className #>::Insert(MYSQL* connect, <#= tab.ClassName_UpdateEntry #>& v)
{
if(!v.IsModified())
{
return false;
}
std::string f;
std::string values;
<#+
var isOneKey = tab.Keys.Length == 1;//判斷是不是單主鍵
foreach (var field in tab.FieldsSupported)
{
var type = field.Type;
var name = field.Name;
#>
if (v.<#=field.NameModify#>)
{
f += " `<#=field.ColumnName#>`,";
values += std::format(" '{}',", v.<#=field.Name#>);
}
<#+
}
#>
<#+if(isOneKey){//自增主鍵,自動寫入insert的生成的key#>
{
std::string sql = std::format("insert into `<#=tab.TabName#>` ({}) values({});", f.substr(0, f.length() - 1), values.substr(0, values.length() - 1));
int query = mysql_query(connect, sql.c_str());
// if (!query) return false;
}
{
std::string sql = "SELECT LAST_INSERT_ID() as id;";
int query = mysql_query(connect, sql.c_str());
// if (!query) return false;
}
auto res = mysql_use_result(connect);
if(res == nullptr) return false;
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) != nullptr)
{
v.<#=tab.Keys[0].Name#> = Columns::GetInt(row, 0);
break;
}
mysql_free_result(res);
<#+}else{#>
std::string sql = std::format("insert into `<#=tab.TabName#>` ({}) values({});", f.substr(0, f.length() - 1), values.substr(0, values.length() - 1));
int query = mysql_query(connect, sql.c_str());
if (!query) return false;
<#+}#>
return true;
}
(c++代碼多年沒寫,有可能有誤,只是為了測驗T4)
Roslyn+T4+EnvDTE ,基本上可以從一種資料源生成,另一種任意格式文本格式
視頻演示
代碼
提取碼:ynpb
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/402381.html
標籤:C#
上一篇:SVG交集設定顏色
下一篇:(五)React Ant Design Pro + .Net5 WebApi:后端環境搭建-Autofac注入+ 泛型倉儲
