Solon 3.0 新特性:SqlUtils

embedded/2024/12/22 20:59:37/

Solon 3.0 引入了新的 SqlUtils 用于数据库基础操作,SqlUtils 是对 JDBC 较为原始的封装,极为反朴归真。 特性有:

  • 支持事务管理
  • 支持多数据源
  • 支持流式输出
  • 支持批量执行
  • 支持存储过程

一、概述

SqlUtils 是一个轻量的数据库操作框架,简单灵活,易于阅读和维护,支持编写复杂的SQL。对于不适合使用复杂的 ORM 框架,或者需要编写复杂的 SQL 的场景,可以使用 SqlUtils 来操作数据库。

SqlUtils 总体上分为查询操作(query 开发)和更新操作(update 开头)。分别对应 JDBC 的 Statement:executeQuery()Statement:executeUpdate()

二、引入 SqlUtils

  • gradle 依赖
implementation 'org.noear:solon-data-sqlutils'
  • maven 依赖
<dependency><groupId>org.noear</groupId><artifactId>solon-data-sqlutils</artifactId>
</dependency>

三、配置数据源

配置数据源(具体参考:《数据源的配置与构建》)

solon.dataSources:rock!:class: "com.zaxxer.hikari.HikariDataSource"jdbcUrl: jdbc:mysql://localhost:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=truedriverClassName: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456

之后就可以按数据源名注入 SqlUtils 了(带 ! 结尾的数据源名,为默认)

java">@Component
public class DemoService {@Inject //默认数据源名SqlUtils sqlUtils;
}

四、查询操作

查数量:

java">public Long findCount() throws SQLException {return sqlUtils.sql("select count(*) from appx where app_id = ?", id).queryValue();
}

按照主键查数据:

java">public Appx findDataById(Integer id) throws SQLException {return sqlUtils.sql("select * from appx where app_id = ?", id).queryRow().toBean(Appx.class);
}

按照自定义查询条件查数据:

java">public List<Appx> findDataByGroup(Integer group_id) throws SQLException {return sqlUtils.sql("select * from appx where group_id = ?", group_id).queryRowList().toBeanList(Appx.class);
}

以上几种查询方式,都是一行代码就解决的。复杂的查询怎么办?比如管理后台的条件统计,可以先使用构建器:

java">public List<Appx> findDataStat(int group_id, String channel, int scale) throws SQLException {SqlBuilder sqlSpec = new SqlBuilder();sqlSpec.append("select group_id, sum(amount) amount from appx ").append("where group_id = ? ", group_id).appendIf(channel != null, "and channel like ? ", channel + "%");//可以分离控制if(scale > 10){sqlSpec.append("and scale = ? ", scale);}sqlSpec.append("group by group_id ");return sqlUtils.sql(sqlSpec).queryRowList().toBeanList(Appx.class);
}

管理后台常见的分页查询:

java">public Page<Appx> findDataPage(int group_id, String channel) throws SQLException {SqlBuilder sqlSpec = new SqlBuilder().append("from appx  where group_id = ? ", group_id).appendIf(channel != null, "and channel like ? ", channel + "%");//备份sqlSpec.backup();sqlSpec.insert("select * ");sqlSpec.append("limit ?,? ", 10,10); //分页获取列表//查询列表List<Appx> list = sqlUtils.sql(sqlSpec).queryRowList().toBeanList(Appx.class);//回滚(可以复用备份前的代码构建)sqlSpec.restore();sqlSpec.insert("select count(*) ");//查询总数Long total = sqlUtils.sql(sqlSpec).queryValue();return new Page(list, total);
}

构建器支持 ?... 集合占位符查询:

java">public List<Appx> findDataList() throws SQLException {SqlBuilder sqlSpec = new SqlBuilder().append("select * from appx  where app_id in (?...) ", Arrays.asList(1,2,3,4));//查询列表List<Appx> list = sqlUtils.sql(sqlSpec).queryRowList().toBeanList(Appx.class);
}

五、流式查询操作

支持 fetchSize 参数

java">public void findDataAll(Integer group_id) throws SQLException {SqlBuilder sqlSpec = new SqlBuilder().append("select * from appx where group_id = ?", group_id);try (RowIterator iterator = sqlUtils.sql(sqlSpec).queryRowIterator(100)) {while (iterator.hasNext()){Appx app = iterator.next().toBean(Appx.class);//....}}
}

六、插入操作

单条插入:

java">public void addData(int id) throws SQLException {return sqlUtils.sql("insert appx(app_id) values(?)", id).update();
}

单条插入并返回主键:

java">public Long addData(int id) throws SQLException {return sqlUtils.sql("insert appx(app_id) values(?)", id).updateReturnKey();
}

批量插入:

java">public void addDataBatch() throws SQLException {List<Object[]> argsList = new ArrayList<>();argsList.add(new Object[]{1});argsList.add(new Object[]{2});argsList.add(new Object[]{3});argsList.add(new Object[]{4});argsList.add(new Object[]{5});sqlUtils.sql("insert appx(app_id) values(?)").updateBatch(argsList);
}

六、更新操作(更新或删除)

支持事务控制

java">@Tran
public void updateData(int id, Appx app) throws SQLException {SqlBuilder sqlSpec = new SqlBuilder();sqlSpec.append("update appx set ")sqlSpec.append("  group_id=?, ", app.group_id)sqlSpec.append("  name=?, ", app.name)sqlSpec.append("  channel=?, ", app.channel)sqlSpec.append("  amount=? ", app.amount)sqlSpec.append("where app_id=? ", id)sqlUtils.sql(sqlSpec).queryRow();
}@Tran
public void delData(int id) throws SQLException {sqlUtils.sql("delete from appx where app_id=?", id).update(); 
}

七、存储过程操作

查询操作

java">public Appx findDataById(int id) throws SQLException {return sqlUtils.sql("{call findDataById(?)}", id).queryRow().toBean(Appx.class);
}

删除操作

java">public int findDataById(int id) throws SQLException {return sqlUtils.sql("{call delDataById(?)}", id).update();
}

八、总结

通过上述的示例,可以看到基本的数据库操作都可以用 SqlUtils 实现,可以避免了复杂的ORM框架的使用。


http://www.ppmy.cn/embedded/126036.html

相关文章

NVIDIA Ampere 架构

全球超强弹性数据中心的核心。 文章目录 前言一、突破性创新1. 第三代 Tensor 核心2. 多实例 GPU (MIG)3. 第三代 NVLink4. 结构化稀疏5. 第二代 RT 核心6. 更聪明、快速的内存二、为规模化部署而优化1. 为各种服务器优化性能2. 统一计算和网络加速3. 密度优化的设计4. 安全部署…

Python:一个列表分割成多个列表

大家在使用Python处理数据时&#xff0c;有时候需要将一个大列表分割成多个小列表&#xff0c;这样可以更加方便地管理和操作数据。执行列表分割的方法主要有使用循环、利用切片操作、借助标准库中的工具如itertools.groupby()以及numpy库的array_split()方法。这些方法各有特点…

从零学编程-C语言-第17天

今天是学习C语言的第17天 时间&#xff1a;2024/10/6 21:16分 使用编译器&#xff1a;vs2019 此贴记录自己的成长 今天学习内容如下 1.自定义类型-结构体 结构体 枚举 联合 //结构体 struct stu {char name[20]; }s1, s2; 这里是全局变量 int main() {struct stu s1,s2 …

简单理解Python代码的重构

版本一&#xff1a; 实现存储用户的名字&#xff1a; remember_me.py #易择365 from pathlib import Path import json username input("请输入你的名字&#xff1a;") path Path(username.json) contents json.dumps(username) path.write_text(contents) print(…

【PostgreSQL】运维篇——定期备份与恢复策略

在数据库管理中&#xff0c;定期备份是确保数据安全性和可恢复性的关键措施。制定一个有效的备份计划可以帮助您在发生数据丢失、损坏或其他灾难性事件时快速恢复数据。 以下是制定定期备份计划的步骤&#xff0c;以及使用pg_dump和其他工具进行数据备份和恢复的详细介绍。 1…

HUAWEI_HCIA_实验指南_Lib1.4_配置通过Telnet登录系统

一、原理概述 Telnet(Telecommunication Network Protocol)起源于ARPANET,是最早的Internet应用之一。 Telnet 通常用在远程登录应用中&#xff0c;以便对本地或远端运行的网络设备进行配置、监控和维护。如网络中有多台设备需要配置和管理&#xff0c;用户无需为每一台设备…

国外电商系统开发-运维系统操作脚本

查看脚本内容&#xff0c;只需要点击即可&#xff1a; 执行脚本&#xff0c;请点击 点击了下一步后&#xff0c;可以输出脚本参数&#xff0c;当然你可以可以不输入&#xff0c;直接下一步就行&#xff1a; 现在&#xff0c;点击【下一步】执行开始出初始化脚本&#xff1a; …

Java每日面试题(java基础)(day17)

目录 JDK/JRE/JVM三者的关系JDK常用的包 和 equals 的区别是什么&#xff1f;Java 中的几种基本数据类型了解么&#xff1f;什么是自动拆装箱&#xff1f;final 关键字中有什么作用&#xff1f;接口和抽象类有什么区别&#xff1f;String, StringBuffer 和 StringBuilder区别St…