添加数据

QtDao的增删改操作,可以单独操作实体,也可以使用条件函数作用。使用函数_insert<E>返回一个InsertBuilder<E>对象,再调用build()函数创建Insert<E>对象进行插入数据操作:

template<typename E>
Insert<E> dao::_insert<E>().build()

部分字段数据的填充

插入一条记录时,可以对指定的部分字段设置值,对InsertBuilder<E>使用set函数显式设置对应字段的值。通常情况下,对于没有设置默认值限制为not null的字段,必须显式设置其值。使用如下:

User::Fields field;
dao::_insert<User>()
    .set(field.name = "Alice", field.age = 18)
    .build().insert();

使用该方法插入数据等同于使用以下sql语句:

insert into user (name, age) values ('Alice', 18)

继承EntityField<T>的字段成员,除了与单一值构造条件,也可以使用QList<T>值列表构造条件,这种情况下,对set函数使用可以进行批量插入:

auto names = QStringList() << "Alice" << "Bob";
auto ages = QList<int>() << 18 << 19;

User::Fields field;
dao::_insert<User>()
    .set(field.name = names, field.age = ages)
    .build().insert();

插入一个实体对象

插入一个模型类的实体对象时,直接传入insert()函数即可。插入实体对象与使用set函数方法一致,所有的字段和值会自动填入(自增字段将被忽略),使用如下:

注意:通常情况下,插入一个实体对象时,执行插入后实体的自增长字段结果将被设置回插入的实体对象中。

User alice("Alice", 18, 100);
dao::_insert<User>().build().insert(alice);

同样,插入一个QList<E>列表执行批量插入:

UserList users;
users << User("Alice", 18, 100);
users << User("Bob", 19, 120);
dao::_insert<User>().build().insert(users);

快速插入实体对象

使用insert2()函数快速批量插入对象列表。

UserList users;
users << User("Alice", 18, 100);
users << User("Bob", 19, 120);
dao::_insert<User>().build().insert2(users);

insert()不同的地方是,insert2()不会使用批处理执行,而是使用以下类似语句:

insert into user (name, age, score) values ('Alice', 18, 100),('Bob', 19, 120)

使用快速插入方法时,需要注意对应数据库sql语句长度的限制。

插入或替换

使用insertOrReplace()函数执行‘插入或更新’操作,通常情况下数据表结构中需要有unique限制的字段或unique index索引配合使用。

User::Fields field;
dao::_insert<User>()
    .set(field.name = "Alice", field.age = 18)
    .build().insertOrReplace();

User alice("Alice", 18, 100);
dao::_insert<User>().build().insertOrReplace(alice);

UserList users;
users << User("Alice", 18, 100);
users << User("Bob", 19, 120);
dao::_insert<User>().build().insertOrReplace(users);

插入或忽略

使用insertOrIgnore()函数执行‘插入或忽略’操作,与insertOrReplace()使用一样,在插入冲突时忽略该次插入数据。

User::Fields field;
dao::_insert<User>()
    .set(field.name = "Alice", field.age = 18)
    .build().insertOrIgnore();

User alice("Alice", 18, 100);
dao::_insert<User>().build().insertOrIgnore(alice);

UserList users;
users << User("Alice", 18, 100);
users << User("Bob", 19, 120);
dao::_insert<User>().build().insertOrIgnore(users);

插入或更新

插入或更新使用数据库非标准语法 Upsert,其中sqlite/mysql使用'insert into ... on ... update ...'语法支持,sqlserver使用'merge'语法支持。

template<typename E>
Upsert<E> dao::_insertOrUpdate<E>()
    .set()
    .conflictColumns()
    .updateColumns()
    .filter()
    .build()

当插入一条(或批量插入)数据时,数据库引擎检查到字段冲突时使用update方式更新数据,否则使用insert方式添加数据。通常情况下,字段冲突使用primary keyunique index约束检查。该操作与insert or replace不同的是,字段冲突时insert or replace会删除原有数据再插入新数据。

  • conflictColumns
    设置冲突检查的字段,仅传入字段即可。通常情况下,传入primary keyunique index对应的字段(对象插入模式下,将忽略自增主键)。

  • updateColumns
    设置遇到冲突时需要更新的字段。显示调用该函数指定冲突时更新的字段,忽略时则使用冲突字段之外的其他所有字段。

  • set方式插入数据
    使用方法与insert操作一致,调用set函数传入部分字段进行插入:

User::Fields field;
//假设 name,classes 作为一个unique index
dao::_insert<User>()
    .set(field.name = "Alice", field.classes = "classA", field.age = 18, field.score = 90)
    .conflictColumns(field.name, field.classes)
    .updateColumns(field.score)
    .build().insert();

//省略 updateColumns 则同时更新 age,score
dao::_insert<User>()
    .set(field.name = "Alice", field.classes = "classA", field.age = 18, field.score = 90)
    .conflictColumns(field.name, field.classes)
    .build().insert();

//与 insert 操作一样,可批量插入
auto names = QStringList() << "Alice" << "Bob";
auto classes = QStringList() << "classA" << "classA";
auto ages = QList<int>() << 18 << 19;
auto scores = QList<int>() << 90 << 91;

dao::_insert<User>()
    .set(field.name = names, field.classes = classes, field.age = ages, field.score = scores)
    .conflictColumns(field.name, field.classes)
    .build().insert();
  • 插入实体对象
    insert一样,upsert也提供了insert(E&)/insert(const QList<E>&)插入对象方法:
User::Fields field;
//假设 name,classes 作为一个unique index
User alice("Alice", "classA", 18, 90);
dao::_insert<User>()
    .conflictColumns(field.name, field.classes)
    .updateColumns(field.score)
    .build().insert(alice);

//省略 updateColumns 则同时更新 age,score
dao::_insert<User>()
    .conflictColumns(field.name, field.classes)
    .build().insert(alice);

//批量插入
User bob("Bob", "classA", 19, 91);
auto users = UserList() << alice << bob;

dao::_insert<User>()
    .conflictColumns(field.name, field.classes)
    .build().insert(users);
  • filter
    使用条件更新。当发生冲突时,是否执行update操作额外取决于filter条件的设置。要使用sqlite中的upsert特定表excluded字段,实例化dao::UpsertExcluded<E>::Fields即可,示例如下:
auto names = QStringList() << "Alice" << "Bob";
auto classes = QStringList() << "classA" << "classA";
auto ages = QList<int>() << 12 << 20;
auto scores = QList<int>() << 90 << 91;

User::Fields field;
dao::UpsertExcluded<User>::Fields excluded;

dao::_insert<User>()
    .set(field.name = names, field.classes = classes, field.age = ages, field.score = scores)
    .conflictColumns(field.name, field.classes)
    .filter(excluded.age > field.age)
    .build().insert();

在上面的例子中,若AliceBob数据库中的age都为18,Alice不满足filter条件则忽略本次Update操作。

注意:目前只支持在sqlite中使用,其他数据库忽略该条件的设置。

insert into select

使用dao::_insertIntoSelect可以执行insert into select语句,这时需要使用嵌套子查询实现:

User1::Fields field1;
User2::Fields field2;
dao::_insertIntoSelect<User2>()
    .column(field2.name, field2.age)
    .from(
        dao::_select<User1>()
            .column(field1.name, field1.age)
            .filter(field1.score < 12)
            .build()
    )
    .build().insert();

results matching ""

    No results matching ""