「 GitHub 开源推荐 」关注优秀开源项目
整理 | 猿胖子
出品 | 猿武场(ID:apesarena)
关注公众号并回复数字「 1024 」加入猿武场微信社群

SQLite ORM 特性介绍

其最大的优点是不需要其他依赖(唯一的依赖:libsqlite3),仅包含自身 library 和头文件即可,其他一些特性:
使用语法直观,支持增删改查外对UNION、EXCEPT和INTERSECT的支持也比较好
兼容 STL ,支持自定义类型绑定
具备序列化和反序列化
支持 ORDER BY 和 LIMIT、OFFSET 以及 GROUP BY DISTINCT
具有 C++ 标准代码风格
支持 SQLite 内存模式
// github 项目地址
https://github.com/fnc12/sqlite_orm

快速创建简单数据模型到数据库的映射
主要体现在有主键和没有主键的(CRUD)对象,并且可以显式指定表名和列名(无需与类的实际命名一致),看一个例子:
struct User{
int id;
std::string firstName;
std::string lastName;
int birthDate;
std::unique_ptr<std::string> imageUrl;
int typeId;
};
struct UserType {
int id;
std::string name;
};
我们一般的数据库创建语句这样写,比如:
// create sql
CREATE TABLE users (id integer primary key autoincrement, first_name text not null, last_name text not null, birth_date integer not null, image_url text, type_id integer not null)
CREATE TABLE user_types (id integer primary key autoincrement, name text not null DEFAULT 'name_placeholder')
那么现在采用ORM 就可以这样创建,如下:
1// start
2
3using namespace sqlite_orm;
4auto storage = make_storage("db.sqlite",
5 make_table("users",
6 make_column("id", &User::id, autoincrement(), primary_key()),
7 make_column("first_name", &User::firstName),
8 make_column("last_name", &User::lastName),
9 make_column("birth_date", &User::birthDate),
10 make_column("image_url", &User::imageUrl),
11 make_column("type_id", &User::typeId)),
12 make_table("user_types",
13 make_column("id", &UserType::id, autoincrement(), primary_key()),
14 make_column("name", &UserType::name, default_value("name_placeholder"))));
是不是容易很多,更方便呢?我们完全可以不必在显式指定映射类型,默认会从创建过程中传递的成员指针推导出来( 例如:&User::id )
要创建一个列就至少传递两个参数:在表中的名称 和映射的类成员指针

我们创建个 User 并将其插入到 User 表中
1// user 对象
2User user{-1, "Jonh", "Doe", 664416000,
3 std::make_unique<std::string>("url_to_heaven"), 3 };
4
5//执行插入操作
6
7auto insertedId = storage.insert(user);
8// insertedId = 8
9cout << "insertedId = " << insertedId << endl;
10user.id = insertedId;
11
12User secondUser{-1, "Alice", "Inwonder", 831168000, {} , 2};
13insertedId = storage.insert(secondUser);
14secondUser.id = insertedId;
接下来通过 ID 获取用户信息
1// get user by id.
2try{
3 auto user = storage.get<User>(insertedId);
4 cout << "user = " << user.firstName << " "
5 << user.lastName << endl;
6}catch(std::system_error e) {
7 cout << e.what() << endl;
8}catch(...){
9 cout << "unknown exeption" << endl;
10}
当然,不用异常处理也可以的
1// get user by id.
2
3if ( auto user = storage.get_pointer<User>(insertedId)){
4 cout << " user = " << user-> firstName << " "
5 << user-> lastName << endl;
6} else {
7 cout << " no id " << insertedId << endl;
8}
更新操作,我们可以通调用 update 更新用户信息
1// 更新用户信息
2user.firstName = "尼古拉斯 赵四" ;
3user.imageUrl = " ./xcaq/20220305151.png "
4storage.update(user);
删除也一样的,只需要传 id 就可以了
1// insertedId:user id
2storage.remove<User>(insertedId)
查询所有用户信息
1// 使用 vector
2auto allUsers = storage.get_all<User>();
3cout << "allUsers (" << allUsers.size() << "):" << endl;
4for(auto &user : allUsers) {
5 cout << storage.dump(user) << endl;
6}
7
8// 使用 vector
9auto allUsersList = storage.get_all<User, std::list<User>>();
10// STL 方式
11for(auto &user : storage.iterate<User>()) {
12 cout << storage.dump(user) << endl;
13}
聚合查询的使用
1// SELECT AVG(id) FROM users
2auto averageId = storage.avg(&User::id);
3// averageId = 4.5
4cout << "averageId = " << averageId << endl;
5
6// SELECT AVG(birth_date) FROM users
7auto averageBirthDate = storage.avg(&User::birthDate);
8// averageBirthDate = 6.64416e+08
9cout << "averageBirthDate = " << averageBirthDate << endl;
10
11
12// SELECT COUNT(*) FROM users
13auto usersCount = storage.count<User>();
14// users count = 8
15cout << "users count = " << usersCount << endl;
16
17// SELECT COUNT(id) FROM users
18auto countId = storage.count(&User::id);
19// countId = 8
20cout << "countId = " << countId << endl;
21
22// SELECT COUNT(image_url) FROM users
23auto countImageUrl = storage.count(&User::imageUrl);
24// countImageUrl = 5
25cout << "countImageUrl = " << countImageUrl << endl;
26
27// SELECT GROUP_CONCAT(id) FROM users
28auto concatedUserId = storage.group_concat(&User::id);
29// concatedUserId = 1,2,3,4,5,6,7,8
30cout << "concatedUserId = " << concatedUserId << endl;
31
32
33// SELECT GROUP_CONCAT(id, "---") FROM users
34auto concatedUserIdWithDashes =
35 storage.group_concat(&User::id, "---");
36// concatedUserIdWithDashes = 1---2---3---4---5---6---7---8
37cout << "concatedUserIdWithDashes = "
38 << concatedUserIdWithDashes << endl;
39
40
41// SELECT MAX(id) FROM users
42if(auto maxId = storage.max(&User::id)){
43 // maxId = 12
44 cout << "maxId = " << *maxId <<endl;
45 (maxId is std::unique_ptr<int>)
46}else{
47 cout << "maxId is null" << endl;
48}
49
50// SELECT MAX(first_name) FROM users
51if(auto maxFirstName = storage.max(&User::firstName)){
52 cout << "maxFirstName = " << *maxFirstName << endl;
53// maxFirstName = Jonh (maxFirstName is std::unique_ptr<std::string>)
54}else{
55 cout << "maxFirstName is null" << endl;
56}
57
58// SELECT TOTAL(id) FROM users
59auto totalId = storage.total(&User::id);
60// totalId is double (always)
61cout << "totalId = " << totalId << endl;
62
63....

克隆仓库代码,使用cmake编译,将编译好的lib引入工程文件或配置系统变量,记得加入头文件
更多特性及使用技巧可以去GitHub项目主页查看,当然你也可以点击下方关注[ 猿武场 ] 公众号回复 “ ORM ” 获取更多相关代码实例哦 !
版权声明:本文来自原创,版权归猿武场作者所有。如需转载,请注明出处。

注公众号并回复数字「 1024 」加入猿武场微信社群
欢迎加入程序员社群,更多技术摘要等你拿走
社群福利:
1. 行业大牛技术手札,知识点汇总;
2. 求职/招聘信息内推;
4. 人际交往,增强技术宅人际交流;
5. 调节繁杂无趣的闲暇时光;
6. 不定期线上周边於线下技术活动沙龙。





