🔥 Solon 3.0 新特性:SqlUtils
Solon 3.0 引入了新的 SqlUtils 用于数据库基础操作,SqlUtils 是对 JDBC 较为原始的封装,采用了 Utils API 的风格,极为反普归真。 特性有:
- 支持事务管理
- 支持多数据源
- 支持流式输出
- 支持批量执行
- 支持存储过程
一、概述
SqlUtils 是一个轻量的数据库操作框架,采用 Utils API 风格,简单灵活,易于阅读和维护,支持编写复杂的SQL。对于不适合使用复杂的 ORM 框架,或者需要编写复杂的 SQL 的场景,可以使用 SqlUtils 来操作数据库。
二、引入 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=true driverClassName: com.mysql.cj.jdbc.Driver username: root password: 123456
之后就可以按数据源名注入 SqlUtils 了(带 !
结尾的数据源名,为默认)
@Component public class DemoService { @Inject //默认数据源名 SqlUtils sqlUtils; }
四、查询操作
查数量:
public Long findCount() throws SQLException { return sqlUtils.selectValue("select count(*) from appx where app_id = ?", id); }
按照主键查数据:
public Appx findDataById(Integer id) throws SQLException { return sqlUtils.selectRow("select * from appx where app_id = ?", id) .toBean(Appx.class, (r,c) -> BeanUtil.toBean(r.toMap(), c)); }
按照自定义查询条件查数据:
public List<Appx> findDataByGroup(Integer group_id) throws SQLException { return sqlUtils.selectRowList("select * from appx where group_id = ?", group_id) .toBeanList(Appx.class, (r,c) -> BeanUtil.toBean(r.toMap(), c)); }
以上几种查询方式,查询条件中的变量使用的是占位符(SqlUtils 只支持占位符),也比较简单。复杂的查询怎么办?比如管理后台的条件统计,可以先使用构建器:
public List<Appx> findDataStat(int group_id, String channel, int scale) throws SQLException { SqlBuilder builder = new SqlBuilder(); builder.append("select group_id, sum(amount) amount from appx ") .append("where group_id = ? group by group_id", group_id); builder.appendIf(channel != null, " and title channel ?", channel + "%"); if(scale > 10){ builder.append(" and scale = ?", scale); } return sqlUtils.selectRowList(builder.getSql(), builder.getArgs()) .toBeanList(Appx.class, (r, c) -> BeanUtil.toBean(r.toMap(), c)); }
管理后台常见的分页查询:
public List<Appx> findDataStat(int group_id, String channel) throws SQLException { SqlBuilder builder = new SqlBuilder() .append(" from appx where group_id = ?", group_id) .appendIf(channel != null, " and title channel ?", channel + "%"); //备份 builder.backup(); builder.insert("select *"); builder.append(" limit ?,?", 10,10); //分页获取列表 List<Appx> list = sqlUtils.selectRowList(builder.getSql(), builder.getArgs()) .toBeanList(Appx.class, (r, c) -> BeanUtil.toBean(r.toMap(), c)); //回滚(可以复用备份前的代码构建) builder.restore(); builder.insert("select count(*)"); Long total = sqlUtils.selectValue(builder.getSql(), builder.getArgs()); }
五、流式查询操作
支持 fetchSize 参数
public void findDataAll(Integer group_id) throws SQLException { try (RowIterator iterator = sqlUtils.selectRowIterator("select * from appx where group_id = ?", 100, group_id)) { while (iterator.hasNext()){ Appx app = iterator.next().toBean(Appx.class, (r, c) -> BeanUtil.toBean(r.toMap(), c)); //.... } } }
六、插入操作
单条插入:
public void addData(int id) throws SQLException { return sqlUtils.insert("insert appx(app_id) values(?)", id); }
单条插入并返回Key:
public void addData(int id) throws SQLException { return sqlUtils.insertReturnKey("insert appx(app_id) values(?)", id); }
批量插入:
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.executeBatch("insert appx(app_id) values(?)", argsList); }
六、执行操作(更新或删除)
支持事务控制
@Tran public void delData(int id) throws SQLException { sqlUtils.execute("delete from appx where app_id=?", id); } @Tran public void updateData(int id) throws SQLException { sqlUtils.execute("update appx set group_id=? where app_id=?", 2, id); }
七、存储过程操作
查询操作
public Appx findDataById(int id) throws SQLException { return sqlUtils.selectRow("{call findDataById(?)}", id) .toBean(Appx.class, (r,c) -> BeanUtil.toBean(r.toMap(), c)); }
删除操作
public int findDataById(int id) throws SQLException { return sqlUtils.execute("{call delDataById(?)}", id); }
八、总结
通过上述的示例,可以看到基本的数据库操作都可以用 SqlUtils 实现,避免了复杂的ORM框架的使用,切操作要比ORM框架简单灵活的多。Utils API 的风格也更容易编写和阅读。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
开源日报 | Deno 2.0;CSS今天30岁;诺贝尔化学奖也给了程序员;彪悍的Hinton家族;谁也成为不了中国的YouTube
欢迎阅读 OSCHINA 编辑部出品的开源日报,每天更新一期。 # 2024.10.10 今日要闻 开源 JavaScript 运行时 Deno 发布 2.0 版本 开源 JavaScript 和 TypeScript 运行时 Deno 于近日发布了 2.0 版本。作为一个现代化的 JavaScript/TypeScript 工具链,Deno 在上个版本就已经具备了原生 TypeScript 支持、内置的格式化和测试等功能。此次 2.0 版本的亮点在于,Deno 现在可以与 Node.js 生态实现完全的向后兼容。 Deno 2.0 的核心变化是全面支持了 Node.js 和 npm 生态。这意味着现有的 Node.js 应用程序可以平滑地迁移到 Deno 上运行。开发者不仅可以在当前的 Node.js 项目中使用 Deno,还能渐进式地引入 Deno 的各种工具,如使用deno fmt格式化代码等。 TIOBE 10 月榜单:Rust 人气持续上涨,Mojo 崭露头角 首个开源 AI 定义稿候选版发布 开源倡议组织(OSI)经过 2 年的努力,于昨日(10 月 9 日)发布了首个开源...
- 下一篇
高效使用AI,一文掌握提示词的编写原则
ChatGPT问世以后就引爆全网热议,它除了能够聊天,还可以根据所提出的要求进行文字翻译、文案撰写、代码撰写等工作。在 《探秘爆火的ChatGPT:大语言模型是个啥?它到底咋工作的?》 一文中,我已经详细介绍了ChatGPT是什么以及如何运行,我在这里就不赘述了。 其实,ChatGPT在回答时也会词不达意。针对如何解决这一问题,最简单实用的方法就是基于自己的文档构建私有知识库。 ChatGPT大模型拥有结合上下文进行回答的能力,这也是为什么在与AI聊天时,它能够"记忆"用户之前的问题的原因。 除此之外,如果提示词使用得当,我们也能够更加充分利用ChatGPT。Jeremy Grandillon就向我们介绍了5个高级提示词框架: 01 RTF RTF,Role Task Format(角色、任务、格式) Role角色:立角色,为ChatGPT赋予一个特定的角色或视角; Task任务:述任务,在说明需求或任务时要明确、具体; Format格式:定格式,说明ChatGPT在回答时应该遵循什么样的格式。 举例: 假如你是一家软件公司的销售代表(角色),现在你需要为一个新的软件产品写一份销售宣传...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2全家桶,快速入门学习开发网站教程