Roslyn+T4+EnvDTE项目完全自动化(3) ——生成c++代码
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
推荐这些文章:
Roslyn+T4+EnvDTE项目完全自动化(6) ——自动化项目
(视频演示)
Roslyn分析项目,并自动化代码
需求:
获取项目所有Symbol,类的成员、注释(精确到一个空格)
用元数据,对其进行重构、自动化
...
Roslyn+T4+EnvDTE项目完全自动化(7) ——光标取元素(XPath)
(视频演示)
获取xml XPath
有些很复杂的xml 嵌套多个命名空间,手写 XPath 经常出错,想一步到位
按Alt+C调用GetXPath
生成代码(选择节点)
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("x", "http://schemas.microsoft.com/ado/2009/11/edmx");
namespaceMa...
Roslyn+T4+EnvDTE项目完全自动化(4) ——批量生成参数检查
(视频演示)
类似功能写了几十个,基本上只要项目中重复两次以上,都可以用Roslyn自动化实现
需求:批量生成参数查方法
对类自动生成参数检查代码
对ef类自动识别非空字段,Unicode字段,成参数检查代码
自动翻译字段
public partial class film
{
public void CheckFields()
{
if (title == null)
{
throw new Exception("标题 不能为空!");
...
<!-- 如果引入了bootstarter,就没有必要引入jdbc 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- 引入mybatisplus依赖 --> <dependency> <groupId>com.baomidou<...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="https://www.cnblogs.com/jwzj/p/css/new_file.css" />
<link rel="stylesheet" type="text/css" href="https://www.cnblogs.com/jwzj/p/...
1.目录结构
pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache....
1.背景:使用 jmh 在 idea 上测试多线程
2.发现并没有成功打包,原因是缺乏 jar 相关依赖,加入如下依赖
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3....
1 <!DOCTYPE html>
2 <html lang="en">
3 <head><!-- 头部 -->
4 <meta charset="utf-8" />
5 <title></title>
6 </head>
7 <body><!-- 身体 -->
8 </body>
9 </html>
...
<h4>表头:</h4>
<table border="1">
<tr>
<th>姓名</th>
<th>身份证</th>
<th>电话</th>
</tr>
<tr>
<td>王五</td>
<td>00000000000000</t...
Repeater绑定数据后如何生成分组的数据,比较难这个问题。
问题
Repeater 绑定数据后如何生成这样的数据<ul><li>1</li><li>2</li><li>3</li></ul><ul><li>4</li><li>5</li><li>6</li></ul>每隔三条数据就生成新的UL数据的数量可能是1,6,7。。。不一定的。如果是7条数据的话就生成<ul><li>1</li><li>...
文章链接:https://www.dianjilingqu.com/4022.html
本文章来源于网络,版权归原作者所有,如果本站文章侵犯了您的权益,请联系我们删除,联系邮箱:saisai#email.cn,感谢支持理解。