总结一下Java中SQL的九种写法

因为在做持久层工具开发,现总结一下各种SQL的写法,也算是清晰一下自已的思路:

第一种写法
public void someMethod(){
try
Connection conn=...;
conn.setAutoCommit(false);
PreparedStatement pst=...;
ResultSet rs= executeSomeSql("some sql...");
conn.commit();
} catch (SQLException ex) {
doSomething();
} finally {
close(rs);
close(pst);
close(conn)
}
最基础的JDBC用法,从connectin的获取,事务的开启、提交,rs、st、connection的关闭全部照顾到
优点:100%掌控所有细节。
缺点:过分繁琐,不推荐业务开发中使用
支持第一种写法的工具类:JDK自带。

第二种写法
public void someMethod(Connection conn) throws SQLException {
queryRunner.executeSQL(conn, "some sql...",参数1, 参数2...);
}
将connection作为参数传递, 业务方法不再负责connection的关闭。
优点:业务方法可以简化到一条语句,极大简化了编程。
缺点:必须另外有一个总的方法进行导常处理和关闭connection,connection作为业务方法的参数传入是对业务方法的入侵。
支持第二种写法的工具类:DbUtils。

第三种写法
QueryRunner queryRunner=new QueryRunner(dataSource);
public void someMethod() throws SQLException {
queryRunner.executeSQL("some sql...",参数1, 参数2...);
}
不再将connection作为参数传递, 工具类构造时将DataSource实例注入,SQL方法完成后Connection自动关闭。
优点:业务方法可以简化成一条语句,没有connection参数入侵业务方法。
缺点:如没有第三方服务支持,事务不太好控制,SQLException异常的抛出也是一种入侵,还是需要另一个方法来捕获。
代表作:DbUtils。

第四种写法
DbPro dbPro=new DbPro(dataSource);
public void someMethod(){
dbPro.executeSQL("some sql...",参数1, 参数2...);
}
业务方法没有Connection参数传入,也不会抛出SQLException异常,工具类将SqlException转化为运行时异常抛出。
优点:业务方法没有受到入侵(严格来说dbPro变量的存在也是对业务方法的一种极轻度的入侵,影响业务方法的可移植性),无须关心异常,运行时异常通常不必处理,由事务服务捕获并回滚。
缺点:无明显缺点,但是要引入IOC/AOP工具如Spring等,以捕获切面的方式实现对异常处理、事务处理及Connection的关闭的支持。
代表作:Spring-JDBC、DbUtils-Pro

以上是从对connection关闭、异常处理和事务处理的角度来看的,从以下写法将开始研究对SQL本身写法的优化:

第五种写法
DbPro dbPro=new DbPro(dataSource);
public void someMethod(){
dbPro.executeSQL("sql piece1",param0(参数1),"sql piece2", param(参数2),"sql piece3",param(参数3)...);
}
将参数利用ThreadLocal暂存,从而可以将参数织入到SQL的任意位置,详见"一种将SQL包装成PrepraredStatement的方法"([url]http://www.iteye.com/topic/1145415[/url]),
优点:1)如果字段名用Java方法或常量代替,则可以实现让普通的SQL支持重构。
2)参数多的SQL,可以保证占位符与实际参数相邻,利于维护。例如下面这种写法,比起传统的JdbcTemplate将所有参数放在方法未尾传递的方式,在可维护性上要好很多:
DbPro.execute("update user set", //
" username=?", param0("Bill"), //
",age=?", param("23"), //
",address=", question("Tianjing"), //
" where id=", question(5));
缺点:重复的参数也必须重复注入; ThreadLocal变量有可能互相干拢,例如不能在一个SQL方法中嵌套另一个SQL调用;
代表作:DbUtils-Pro (或jSqlBox, 其内核基于DbUtils-Pro)

第六种写法
public void someMethod(){
put0("name","张三");
user.setAddress("BeiJing");
put("user",user);
dbPro.executeSQL("update users set name=#{name}, address=#{user.address}");
或 dbPro.executeSQL(findSQL("someSqlID"));
}
利用模板来统一存放SQL,模板的形式可以为XML、文本或Java字符串、Java Annoation、JVM语言如Groovy甚至Java注释(见[url]https://my.oschina.net/drinkjava2/blog/892309)[/url]),另外使用模板也可用第5种方法介绍过的利用ThreadLocal赋值。
优点:便于统一管理SQL,尤其是一些长SQL
缺点:模板不支持重构,参数的赋值和实际的SQL有时存放在两个文件里,而IDE又不支持导航定位,维护不方便。占位符的存在和赋值要多打几个字。
代表作:MyBatis, BeetlSql, DbUtils-Pro, NamedParameterJdbcTemplate

以下写法开始,引入了ORM概念,从SQL角度来看,ORM也可看成一种写SQL的写法。ORM主要分两大部分:1)Java Bean与数据库表的映射 2)Bean之间关联关系与数据库表关联关系的映射
ORM框架林林总总:
从功能来区分,有些简单到只有Bean到数据表的映射如Memory;有些只支持单向的关联映射如MyBatis/BeetlSql/jSqlBox, 有些是全功能的支持复杂的对象-数据库双向关联关系映射如Hibernate,
从是否支持配置来区分,有些是零配置的(如Memory/jFinal-Dao/DbUtils),映射关系靠命名约定来保证, 有些是固定配置的,一旦配置好就不能再变动(MyBatis/Hibernate/JPA/BeetlSQL)。有些支持运行期动态调整配置(如jSqlBox)。
从配置方式来区分,有写在XML中(MyBatis),有写在注解中(Hibernate/JPA/BeetlSQL),有写在Java方法里(jSqlBox)

第七种写法
public void someMethod(){
Session session = getSessionFromSomeWhere();
User user = new user();
user.setName("张三");
session.save(user);
}
优点:CRUD操作非常方便
缺点:对复杂SQL无能为力;session变量的存在对业务方法是一种轻度入侵,当session的功能设计的很复杂,方法很多时,就变成了重度入侵,严重影响业务方法的可移植性。
代表作:Hibernate, MyBatis, BeetlSql

第八种写法
public void someMethod(){
User user = new user();
user.setName("张三");
user.save();
}
又被称为ActiveRecord模式,业务方法中没有session变量出现,
优点:CRUD操作非常方便, 业务方法更简炼
缺点: 对复杂SQL无能为力;Java8以下要实现这种写法,必须让实体类继承于一个基类,占用了唯一的单继承,这也是一种(大多数情况下无关紧要的)入侵。Java8情况要好一些,只需要声明实现接口即可。
代表作:jFinal-Dao, jSqlBox 以及所有基于ActiveRecord模式的持久层工具

第九类写法
严格来说,这不是一种写法,而是一大类五花八门的写法,它往往是专有的,仅适用于各自的框架,例如Hibernate的HQL语言,Hibernate以及Nutz的用Java方法来代替SQL语法,Spring Boots用方法名代替SQL,各种模板对SQL语法的扩充,jSqlBox的利用ThreadLocal暂存映射配置等,如果你看到什么新奇的SQL写法,都归到这一大类吧,第九类写法并不都优于前面8种写法,只是不太好归类而已,甚至个人认为有些是反模式,如HQL和用Java方法代替SQL语法等。
具体在开发中个人优先推荐使用第5、6、8种写法。

另外文中提到的DbUtils-Pro还处于开发阶段,它是一个继承于DbUtils的小项目,欢迎有兴趣者加入。
【Java代码审计】SQL注入篇 SQL 注入(SQL Injection)是因为程序未能正确对用户的输入进行检查,将用户的输入以拼接的方式带入 SQL 语句中,导致了 SQL 注入的产生。黑客通过 SQL 注入可直接窃取数据库信息,造成信息泄露输入用户可控直接或间接拼入 SQL语句执行因 SQL 注入漏洞特征性较强,在实际的审计过程中我们往往可以通过一些自动化审计工具快速地发现这些可能存在安全问题的代码片,如使用奇安信代码卫士、Fortify 等自动化工具。 阅读详情

相关推荐

Java的SQL语句的写法小结

Java的strSQL的写法确实有时候让人头疼:有 " +让你搞得不是很明白。其实,分开来看就行。识别每个符号的意思即可。"" 是SQL的字符串。是String类型的。 里主要用来字符串操作的。和数据库的varchar等相对应得。不和int 对应。+ 是用来连接字符串类的 这样你就可以看明白了。

马如林的IT博客 6037

自用 Java 学习(SQL)

SQL概述 了解了数据模型后,接下来我们就学习SQL语句,通过SQL语句对数据库、表、数据进行增删改查操作。 SQL简介 英文:Structured Query Language,简称 SQL 结构化查询语言,一门操作关系型数据库的编程语言 定义操作所有关系型数据库的统一标准 对于同一个需求,每一种数据库操作的方式可能会存在一些不一样的地方,我们称为“方言” 通用语法 SQL 语句可以单行或多行书写,以分号结尾。 MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用

Ke_youmi的博客 1303

用Cloudflare Worker搭建你的私人Gemini Pro API

文章介绍如何通过开源项目gemini-cli-openai将谷歌Gemini模型转换为兼容OpenAI API的服务,解决Gemini CLI的三大使用障碍:网络访问、命令行操作和生态整合问题。部署流程主要包括获取Google OAuth2凭证、配置Cloudflare Worker项目并设置KV存储,最终可在CherryStudio等图形客户端中调用Gemini。该方法利用Cloudflare全球网络实现加速访问,同时保持认证信息安全可控。

Hsiao的二进制生活 1684

SQL基础语法

1 SQL简介 英文:Structured Query Language,简称 SQL 结构化查询语言,一门操作关系型数据库的编程语言 定义操作所有关系型数据库的统一标准 对于同一个需求,每一种数据库操作的方式可能会存在一些不一样的地方,我们称为“方言” 2 通用语法 SQL 语句可以单行或多行书写,以分号结尾。 如上,以分号结尾才是一个完整的sql语句。 MySQL 数据库的 SQL 语句不区分大小写。 注释 单行注释: -- 注释内容 或 #注释内容(MySQL 特有) 注意:使用-..

Sinlair的博客 845

TI官方PSpice for TI安装避坑指南:从申请Key到解决器件搜索栏空白(附详细步骤)

本文详细介绍了PSpice for TI的安装与配置全流程,包括申请Key、解决器件搜索栏空白等常见问题。通过分步指南和实战避坑技巧,帮助工程师高效完成安装并优化性能,确保电路仿真工具的正常使用。

weixin_29299807的博客 1095

SPSS&Mplus—共同方法偏差(Common Method Bias)控制与检验

共同方法偏差(Common Method Bias)的控制方法:程序控制(Procedural)和统计控制(Statistical)。

m0_54401011的博客 1万+

java SQL常用语句总结大全(超详细)

数据库 数据库定义: **数据库:**存储数据的仓库. 其本质是一个文件系统,数据库按照特定的格式将数据存储到文件中,使用者可以对数据库中的数据进行增加,修改,删除及查询操作。 存储位置 优点 缺点 内存 例如: 集合,实体类对象数据是放在内存中 存取速度很快 不能永久的保存,程序停止时,内存释放数据消失 文件 例如: IO流,把数据存在文件中 可以永久操作数据 每种不同类型的文件都有自己存放数据的格式,数据的管理和维护不方便 数据库 数据库按照特定的格式将数据存储起来,通过SQL或

weixin_49382813的博客 5876

Wireshark时间分析实战:精准调试网络延迟与时间同步问题

本文深入探讨了Wireshark在网络延迟与时间同步问题分析中的核心应用。通过实战案例,详细讲解了如何设置时间显示格式、利用时间参考点量化关键路径延迟,以及运用时间平移功能校正错位时间轴。掌握这些时间分析技巧,能帮助网络工程师精准定位隐藏于数据包时序中的性能瓶颈与故障根源。

weixin_29290963的博客 262

Java基础——SQL语句

SQL语句 SQL语句不区分大小写,关键字建议使用大写,必须再后面加分号 单行注释-- ,或#(mysql特有) 多行注释:/* */ 数据库创建出来的默认字符集是utf8 sql分类 分类:DDL(操作数据库、表) DML(增删改表中的数据) DQL(查询表中的数据) DCL(权限和访问) 操作数据库: CRUD create创建 : create 1.创建数据库:create database 数据库名称; 2.创建数据库,判断不存在,再创建: create database if not ex

Anonymous_jsu的博客 3757

SoulX-FlashHead 加速实践,提升3倍。

SoulX-FlashHead 加速实践,提升3倍。

jacke121的专栏 224

YOLOv8-COCO指标转换

本文介绍了将YOLO格式数据集转换为COCO格式并评估模型性能的完整流程。首先需将YOLO格式的标注数据转换为COCO格式,通过修改classes、image_path等参数适配不同数据集。然后使用YOLO模型对验证集进行预测并保存结果为JSON格式。最后通过比较预测结果和转换后的COCO标注文件,使用COCO官方评估指标和TIDE工具进行性能分析,生成包含AP、AR等指标的报告及错误分析图表。整个过程实现了从数据准备到模型评估的完整闭环,为计算机视觉任务提供标准化的性能评估方案。

FJN110的博客 403

Java 实现接口幂等的九种方法

在分布式系统中,接口的幂等性至关重要,它能确保重复请求不会导致意外的副作用。本文深入探讨了 Java 实现接口幂等的九种方法,包括数据库唯一约束、状态机、分布式锁等,并通过详细的代码示例和实际应用场景,帮助读者全面理解和掌握这些方法,以提升系统的稳定性和数据一致性。

喵小狸的博客 2315

手把手教你学 GPU SoC 芯片(9.3)--GPU SOC 功耗和热管理的动态电压和频率调整(DVFS)

通过动态电压和频率调整(DVFS),可以有效地管理GPU SoC的功耗和热管理。合理的DVFS策略不仅可以节省功耗,提高能效,还可以延长设备的使用寿命。

MHD0815的博客 1500

Mybatis中sql的各种写法,项目中的。存储过程写法,创建索引写法

关键是扩大自己的视野,因为有的我真的不知道可以这样写? 比如: 一:if test --可以去掉多余的and <if test = "defaultQuery and sum == false"> AND (sysdate - T.CREATED) &lt; 90 </if> <if test = "limit30 and sum == false">...

little_dream2018的博客 4126

【YOLO26实战全攻略】09——YOLO26多目标跟踪实战宝典:从原理到智慧园区人流统计全流程

多目标跟踪(MOT)是视频分析的核心技术,解决了单帧检测无法关联目标身份的痛点。本文基于YOLO26轻量化检测模型与ByteTrack跟踪算法,从新手视角出发,系统讲解多目标跟踪的核心原理、环境搭建、实操步骤与工程落地。内容涵盖ByteTrack分层关联策略解析、YOLO26集成跟踪的一行代码实现、配置参数调优、区域计数、轨迹数据提取与热力图可视化,最终通过智慧园区人车流量统计虚拟案例,完整呈现从技术原理到实际应用的全流程。本文注重实用价值,所有代码可直接复现,参数配置附带场景化建议,帮助新手快速上手。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 356

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

java、C#中Sql语句传参的写法及意义

Sqlserver这东西没少跟他打交道,刚学开发语言时就已经跟他接触了,不要说很精通,但就语法还算是熟悉,但现在开始写C#,发现很C#多了一种SqlServer的参数传入方式,以往我们常常对要传参的Sql语句都是直接通过拼凑Sql语句的方式来实现,但现在C#为什么要专门做一个Sql参数的类来实现呢,经过查找才知道,这样做是有道理的,一是可以优化SQL语句(在oracle的教程的类似的传参SQL语

同一天空下 3357

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

SQL写法技巧

SQL书写技巧 特殊SQL的写法

JIU-W的博客 1840

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

oracle和mysql的sql写法区别

oracle和mysql的sql写法区别 批量插入 mybatis映射中可以通过标签来实现Oracle的批量插入、更新和删除 标签中主要有以下属性: collection、item、index、open、separate、close collection:该属性必须指定,指代Dao层接口传递的数据类型,主要有三种: ①:list集合类型;collection=”list“ ②:array数组类型...

qq_41513129的博客 1327

MyBatis中SQL写法总结

最近MyBatis使用较多,在这里简单总结一下MyBatis的sql写法 说简单⼀点mybatis就是写原⽣sql,官⽅都说了 mybatis 的动态sql语句是基于OGNL表达式的。可以⽅便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下⼏类: if 语句 (简单的条件判断) choose (when,otherwize) ,相当于java 语⾔中的 switch ,与 jstl 中的choose 很类似. trim (对包含的内容加上 prefix,或者 suff

不想搞技术的的cc不是好cc 5519

掌握Mybatis动态SQL写法,告别根据不同条件拼接SQL语句的痛苦

掌握Mybatis动态 SQL 的写法,告别根据不同条件拼接 SQL 语句的痛苦 本文基于Mybatis官方文档 ,根据我自己的学习情况进行整理记录。 一、前言 MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQ...

qq_40151840的博客 2915

MybatisPlus 自定义SQL写法

1. UserMapper.java 定义一个方法。2. UserMapper.xml 编写sql语句。3. 业务层 编写wrapper并调用dao层方法。注:${ew.customSqlSegment}可以看到,where条件已经注入到sql语句里。ew 是固定写法,也可以写成。为固定写法,代表业务层传入的wrapper语句。传参wrapper时,需要写。4. 控制台输出SQL语句。

xin909xin的博客 402

jpa 原生SQL写法

当你的抽象类继承了JpaRepository类时,就会拥有一些基本的增删改查操作。但是,很多时候只有这些简单的功能是不够的的,jpa也支持原生SQL和实体类SQL进行自定义查询。 简单例子: @Query(value = "select name,author,price from Book b where b.price>?1 and b.price<?2") List<Book> findByPriceRange(long price1, long price2); Li

weixin_40910372的博客 1万+

高效 MyBatis SQL 写法一

MyBatis动态SQL优质写法分享,包括forEach循环、模糊查询、choose多条件判断、selectKey主键生成和if动态条件,提升代码可读性和维护性,减少错误,适用于多种开发场景。

我码玄黄的博客 1414

java里面xml sql写法

java .xml 写法 有一些运算符,xml不支持 例 大于 和小于 或者 <> 等于在xml里面不支持, 我们需要用一些符号和 代码来标明,让电脑认识它们 < ! [ CDATA [ 在这个位置书写所需要的运算符 ] ] > 模糊查询 concat ( '%' , #{ 所带入的参数 } , '%' ) 在xml里面有时候我们需要对一段数据进行匹配, 但是所需要匹配的数据的数据源是一个集合,这个 时候我们需要对sql的一个循环遍历 longs 传入的集合名字 itm表示

个人随手笔记 2490

多种MyBatis写法(数据库操作)

多种MyBatis写法(数据库操作)

weixin_46619605的博客 1548

10 种超赞的 MyBatis SQL写法!

如果传递的是一个List,则mybatis会封装为一个list为key,list值为object的map,如果是array,则封装成一个array为key,array的值为object的map,如果自己封装呢,则colloection里放的是自己封装的map里的key值。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。使用时比较灵活, new一个这样的实体类,我们需要限制那个条件,只需要附上相应的值就会where这个条件,相反不去赋值就可以不在where中判断。

weiye2012的博客 1120
上一篇: 一种利用注释让Java支持多行字符串的方法
下一篇: 历时一年开发,Java持久层工具jSqlBox第一个正式版本发布
Drinkjava2
博客等级 码龄11年 9粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值