数据表配置

数据库表与字段等信息的配置通过xml文档编写,再通过代码生成器插件生成c++对应的模型和工具类。编写表配置文件时,需要严格遵循相应数据库的xsd文档约束。本篇详细说明了各个xml标记的作用与限制条件,按照文档约束编写创建符合业务的数据库模型。

<dao>标签

根节点<dao>用于选择数据库类型,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="sqlite" namespace="MySpc" alias="dbconfig1">
</dao>
属性 说明 是否可选
prefix 表示数据表前缀,每个表名称前都将添加prefix前缀用于区分其他表(如系统表),在使用QtDao查询时不必关心前缀,在生成sql语句时将自动使用带有前缀的表名。  
db 表示使用的数据库类型,目前只能为3种:sqlite,mysql,sqlserver  
namespace 对每个生成的实体类添加一个命名空间。 可选
alias 为当前配置绑定一个别名,可在多数据连接初始化时进行配置的选择。 可选

<tb>标签

<tb>标签用于配置表属性,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="sqlite">
    <tb name="TestTb" declaremetatype="true" engine="InnoDB">
    </tb>
</dao>
属性 说明 是否可选
name 声明数据库表表名,建议使用大写驼峰命名法,生成的c++模型类类名也使用该名称。  
declaremetatype 将该c++类注册到qt元对象系统,在使用信号槽等功能时传递该自定义类型。同时,该类各个字段注册到qml类型系统,在传递到qml中使用时可以直接修改和访问字段(成员变量)值。 可选
engine mysql特有属性,显式声明mysql数据库的数据表引擎。 可选

<item>标签

<item>标签用于配置数据表字段信息,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="mysql">
    <tb name="TestTb">
        <item name="id" type="bigint" default="-1" autoincrement="true" constraints="primary key" note="主键"/>
        <item name="name" type="varchar" bitsize="100" constraints="not null" jsonkey="json_name" jsontimeformat="yyyy-MM"/>
        <item name="nametmp" type="text" transient="true"/>
        <item name="typedecimal" type="decimal" bitsize="8" decimal-d="4" default="0.3" />
        <item name="myStructType" type="custom" customtype="MyStruct">
    </tb>
</dao>
属性 说明 是否可选
name 声明数据表字段名称,建议使用小写驼峰命名法,生产的c++模型成员变量也使用该名称。  
type 声明字段类型,该类型必须是当前数据库支持的类型,不同数据库有不同的可选类型,见下面类型与默认值说明表描述。  
customtype type值为custom时有效,表示使用自定义类型,该字段的使用见自定义操作篇说明。 可选
default 设置字段和c++模型成员变量默认值,不同数据库有不同程度的默认值支持。同时,当查询单个实例结果时,设置字段默认值是个重要的判断条件,见下面类型与默认值说明表描述。 可选
autoincrement 声明自增长字段。 可选
constraints 为字段添加限制,只能为以下3种:'not null'限制字段不能存储null类型值,'unique'限制字段不可重复,'primary key'声明字段为主键。 可选
bitsize 设置类型宽度,对应字符串类似于varchar(100),浮点数类似于decimal(5,3) 可选
decimal-d 配合bitsize设置浮点数小数位宽度,类似于decimal(5,3),其中bitsize=5, decimal-d=3。 可选
note 设置字段备注,在c++模型成员变量上添加相应注释,对于mysql还将作为comment写入到表结构中。 可选
jsonkey 将c++模型类与json相互转换时显示指定转换的key,默认使用字段名。 可选
jsontimeformat 与json相互转换时,时间日期相关类型显示使用格式化字符串。 可选
transient c++模型临时成员变量,将不参与数据库数据转换,用于保存用户临时数据。 可选
reftb 当前字段作为外键链接到的主表表名称。 可选
refitem 当前字段作为外键链接的目标字段。 可选
refonupdate 当前字段作为外键,其链接的主表字段进行更新时的表现行为。可选的有:'no_action','restrict','set_null','set_default','cascade' 可选
refondelete 当前字段作为外键,其链接的主表字段进行删除时的表现行为。 可选
deferrable 当前字段作为外键,事务操作时是否延迟检查外键约束,目前仅sqlite支持。 可选
refvirtual 虚拟外键引用。 可选

注意:当使用外键约束时,其链接目标字段需要添加primary key或unique约束以保证唯一性。

<index>标签

<index>标签用于配置数据表索引,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="sqlserver">
    <tb name="TestTb">
        <item name="id" type="bigint" default="-1" constraints="primary key" autoincrement="true" note="自增长主键"/>
        <item name="name" type="varchar" constraints="not null"/>
        <item name="number" type="int" default="0"/>
        <item name="number2" type="int"/>
        <index type="unique nonclustered">
            <field seq="asc">name</field>
            <field seq="desc">number</field>
        </index>
        <index>
            <field>number2</field>
        </index>
        <index allow_row_locks="on" allow_page_locks="off" data_compression="none">
            <field>number</field>
            <field>number2</field>
        </index>
    </tb>
</dao>

<index>可指定type属性,对应sqlite/mysql,可以选择使用'index'(默认)或'unique index',用于指定索引唯一限制,对于sqlserver,可选择使用的有:'clustered''unique clustered''nonclustered'(默认)、'unique nonclustered'同时显式指定唯一与聚集性限制。allow_row_locksallow_page_locksdata_compression属性为sqlserver特有的属性。使用<field>标签指定创建索引用到的字段。

<foreignkey>标签

<foreignkey>标签用于配置组合外键约束,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="sqlserver">
    <tb name="Artist" declaremetatype="true">
        <item name="id" type="long" constraints="primary key" />
        <item name="name" type="text" />
        <item name="size" type="int" />
        <index type="unique index">
            <field>id</field>
            <field>size</field>
        </index>
    </tb>
    <tb name="Customer">
        <item name="id" type="long" default="-1" constraints="primary key" />
        <item name="name" type="text" />
        <item name="pkArtistId" type="long" />
        <item name="pkArtistSize" type="int" />
        <foreignkey reftb="Artist" refonupdate="cascade" refondelete="cascade">
            <field name="pkArtistId" refitem="id"/>
            <field name="pkArtistSize" refitem="size"/>
        </foreignkey>
    </tb>
</dao>

与字段定义为外键时一样,<foreignkey>需要指定链接的主表表名和更新删除时的行为。使用<field>标签定义本表字段(<name>)与主表字段(<refitem>)的链接关系。目前仅支持单表的组合外键约束的定义。与单字段外键约束一样,被引用的外键字段需要保证唯一性,需要创建一个唯一索引。

<constructor>标签

<constructor>标签用于创建c++模型类构造函数,示例:

<?xml version="1.0" encoding="utf-8"?>
<dao prefix="ts_" db="sqlserver">
    <tb name="TestTb">
        <item name="id" type="bigint" default="-1" constraints="primary key" autoincrement="true" note="自增长主键"/>
        <item name="name" type="varchar" constraints="not null"/>
        <item name="number" type="int" default="0"/>
        <item name="number2" type="int"/>
        <constructor>
            <field>name</field>
            <field>number</field>
        </constructor>
    </tb>
</dao>

通常情况下会产生3种默认构造函数:无参构造函数、全参数构造函数,忽略自增主键、无默认值参数构造函数,当默认生成的构造函数无法满足需求时可以显示声明构造函数,此时应该注意无默认值的成员会变成随机值的可能。生成的模型类构造函数如下:

class TestTb {
private:
    //
    qint64 id;
    //
    QString name;
    //
    int number;
    //
    int number2;

public:
    //无参构造函数
    TestTb() {
        id = -1;
        number = 0;
    }

    //全参数构造函数,忽略自增主键
    TestTb(
        const QString& name,
        const int& number,
        const int& number2
    ) : name(name)
    , number(number)
    , number2(number2)
    {
        id = -1;
    }

    //无默认值参数构造函数
    TestTb(
        const QString& name,
        const int& number2
    ) : name(name)
    , number2(number2)
    {
        id = -1;
        number = 0;
    }

    //显示声明构造函数
    TestTb(
        const QString& name,
        const int& number
    ) : name(name)
    , number(number)
    {
        id = -1;
    }
}

数据库类型与默认值说明

Sqlite

字段类型 c++类型
int int
long qint64
real qreal
text QString
blob QByteArray
variant QVariant

默认值示例:

数值类型

<!-- sql:id integer default -1 -->
<!-- c++:int id = -1; -->
<item name="id" type="int" default="-1">

<!-- sql: id integer default null -->
<!-- c++: qint64 id = qint64(); -->
<item name="id" type="long" default="null">

<!-- sql: num real default 0.1 -->
<!-- c++: qreal num = 0.1; -->
<item name="num" type="real" default="0.1">

<!-- sql: num real default null -->
<!-- c++: qreal num = qreal(); -->
<item name="num" type="real" default="null">

字符串/字节数组类型

<!-- sql: str text default 'abc' -->
<!-- c++: QString str = "abc"; -->
<item name="str" type="text" default="abc">

<!-- sql: str text default null -->
<!-- c++: QString str = QString(); -->
<item name="str" type="text" default="null">

<!-- sql: str text default 'null' -->
<!-- c++: QString str = QString("null"); -->
<item name="str" type="text" default='"null"'>

<!-- sql: str text default '' -->
<!-- c++: QString str = QString(); -->
<item name="str" type="text" default="empty">

<!-- sql: str text default 'string' -->
<!-- c++: QString str = QString("string"); -->
<item name="str" type="text" default='QString("string")'>

<!-- blob 默认值等同于 text, c++类型 QString->QByteArray -->

variant类型

variant类型使用blob存储QVariant类型的数据,其声明的字段支持QVariant可存储的大部分类型,读取与写入通过QVariant隐式转换,因此通过variant字段可以存储不同的类型的数据,但仅限于sqlite支持的类型,使用自定义类型时可参考自定义操作篇说明。

<!-- 默认值仅初始化QVariant,sql默认值null -->
<item name="num" type="variant" default="100"/>
<item name="str" type="variant" default='"string"'/>
<item name="t" type="variant" default="QTime::currentTime()"/>
<item name="dat" type="variant" default="QDateTime::currentDateTime()"/>

Mysql

字段类型 c++类型
tinyint char
smallint short
mediumint/int int
bigint qint64
float/double/decimal qreal
time QString
date QDate
datetime/timestamp QDateTime
char QChar
varchar QString
tinytext/text/
mediumtext/longtext
QString
tinyblob/blob/
mediumblob/longblob
QByteArray

默认值示例:

数值/字符串/字节数组类型

sqlite默认值示例

时间/日期类型

<!-- time -->

<!-- sql: typeTime time default '120:59:59' -->
<!-- c++: QString typeTime = "120:59:59"; -->
<item name="typeTime" type="time" default='120:59:59'>

<!-- sql: typeTime time default null -->
<!-- c++: QString typeTime = QTime::currentTime().toString("HH:mm:ss"); -->
<item name="typeTime" type="time" default='QTime::currentTime().toString("HH:mm:ss")'>

<!-- sql: typeTime time default null -->
<!-- c++: QString typeTime = QTime::currentTime().toString("HH:mm:ss"); -->
<item name="typeTime" type="time" default='now'>

<!-- sql: typeTime time default null -->
<!-- c++: QString typeTime = QString(); -->
<item name="typeTime" type="time" default='null'>


<!-- date -->

<!-- sql: typeDate date default '2020-01-01' -->
<!-- c++: QDate typeDate = QDate::fromString("2020-01-01"); -->
<item name="typeDate" type="date" default='2020-01-01'>

<!-- sql: typeDate date default null -->
<!-- c++: QDate typeDate = QDate::currentDate(); -->
<item name="typeDate" type="date" default='QDate::currentDate()'>

<!-- sql: typeDate date default null -->
<!-- c++: QDate typeDate = QDate::currentDate(); -->
<item name="typeDate" type="date" default='now'>

<!-- sql: typeDate date default null -->
<!-- c++: QDate typeDate = QDate(); -->
<item name="typeDate" type="date" default='null'>


<!-- datetime/timestamp -->

<!-- sql: typeDatetime datetime default '2020-01-01 12:59:58.233' -->
<!-- c++: QDateTime typeDatetime = QDateTime::fromString("2020-01-01 12:59:58.233"); -->
<item name="typeDatetime" type="datetime" default='2020-01-01 12:59:58.233'>

<!-- sql: typeDatetime datetime default null -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="datetime" default='QDateTime::currentDataTime()'>

<!-- sql: typeDatetime datetime default null -->
<!-- c++: QDateTime typeDatetime = QDateTime(); -->
<item name="typeDatetime" type="datetime" default='null'>

<!-- sql: typeDatetime datetime default CURRENT_TIMESTAMP -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="timestamp" default='now'>

<!-- sql: typeDatetime datetime default CURRENT_TIMESTAMP(3) -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="timestamp" default='CURRENT_TIMESTAMP(3)'>

<!-- sql: typeDatetime datetime default CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="timestamp" default='CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)'>

<!-- sql: typeDatetime datetime default null ON UPDATE CURRENT_TIMESTAMP(3) -->
<!-- c++: QDateTime typeDatetime = QDateTime(); -->
<item name="typeDatetime" type="timestamp" default='null ON UPDATE CURRENT_TIMESTAMP(3)'>

SqlServer

字段类型 c++类型
tinyint uchar
smallint short
int int
bigint qint64
float/double/decimal/
numeric/real
qreal
time QTime
date QDate
datetime/datetime2/
datetimeoffset
QDateTime
timestamp QByteArray
char/varchar/
varchar(max)/nchar/nvarchar/
nvarchar(max)/text/ntext
QString
bit bool
binary/varbinary/
varbinary(max)
QByteArray
sql_variant QVariant
uniqueidentifier/xml QByteArray

默认值示例:

数值/字符串/字节数组类型

sqlite默认值示例

时间/日期类型

<!-- time -->

<!-- sql: typeTime time default '12:59:59.6789' -->
<!-- c++: QTime typeTime = QTime::fromString("12:59:59.6789"); -->
<item name="typeTime" type="time" default='12:59:59.6789'>

<!-- sql: typeTime time default null -->
<!-- c++: QTime typeTime = QTime::currentTime(); -->
<item name="typeTime" type="time" default='QTime::currentTime()'>

<!-- sql: typeTime time default getdate() -->
<!-- c++: QTime typeTime = QTime::currentTime(); -->
<item name="typeTime" type="time" default='now'>

<!-- sql: typeTime time default null -->
<!-- c++: QTime typeTime = QTime(); -->
<item name="typeTime" type="time" default='null'>


<!-- date -->

<!-- sql: typeDate date default '2020-01-01' -->
<!-- c++: QDate typeDate = QDate::fromString("2020-01-01"); -->
<item name="typeDate" type="date" default='2020-01-01'>

<!-- sql: typeDate date default null -->
<!-- c++: QDate typeDate = QDate::currentDate(); -->
<item name="typeDate" type="date" default='QDate::currentDate()'>

<!-- sql: typeDate date default getdate() -->
<!-- c++: QDate typeDate = QDate::currentDate(); -->
<item name="typeDate" type="date" default='now'>

<!-- sql: typeDate date default null -->
<!-- c++: QDate typeDate = QDate(); -->
<item name="typeDate" type="date" default='null'>


<!-- datetime/datetime2/datetimeoffset -->

<!-- sql: typeDatetime datetime default '2020-01-01 12:59:58.233' -->
<!-- c++: QDateTime typeDatetime = QDateTime::fromString("2020-01-01 12:59:58.233"); -->
<item name="typeDatetime" type="datetime" default='2020-01-01 12:59:58.233'>

<!-- sql: typeDatetime datetime default null -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="datetime" default='QDateTime::currentDataTime()'>

<!-- sql: typeDatetime datetime default null -->
<!-- c++: QDateTime typeDatetime = QDateTime(); -->
<item name="typeDatetime" type="datetime" default='null'>

<!-- sql: typeDatetime datetime default getdate() -->
<!-- c++: QDateTime typeDatetime = QDateTime::currentDataTime(); -->
<item name="typeDatetime" type="timestamp" default='now'>

results matching ""

    No results matching ""