现在公司使用mybatis作为DAL层的框架.

使用起来比较简单,使用xml进行SQL的书写,java代码使用接口执行.

但在写一些简单SQL的时候会显得非常繁琐:

  1. xml和java分离(设计上为了解耦),一些字段是否设置等需要反复查看(虽然可以通过插件直达);
  2. 原生无法热加载,修改xml后需要重启(可以使用三方实现);
  3. xml的动态SQL没有java灵活.

上述这些"缺点"仅仅针对写简单的sql,特别是第一条.

我对一张表的需求是简单的CRUD,那使用xml就会非常麻烦.

最基本的需求:

  • 简单安全的SQL拼接方案;
  • 方便的类型映射.

探索了几个方案,接下来一一介绍.

JOOQ

这是考虑的第一个方案,有个没好的愿景,类型安全的SQL,不用担心出现SQL的语法错误.

但实际使用遇到了比较麻烦的事情,他的codegen.

        <generate>
<pojos>true</pojos>
<daos>true</daos>
<keys>false</keys>
<indexes>false</indexes>
<globalObjectReferences>false</globalObjectReferences>
</generate>

自己加了pojodao,一定会生成Table,Record,洋洋洒洒一堆文件摆在眼前.

因为是互联网企业,业务也在发现会相当不稳定,管理这坨生成的代码会很麻烦,而且不简洁.

当然也有不是用codegen的方式,但最后感觉还是过于庞大,也比之前直接用mybatis更麻烦了.

ActiveJDBC

active record的实践.

总体感觉非常简洁清晰,想起了当初用JFinal的感觉.

当时看了文档就感觉是他了,不需要自己手写SQL,同时兼容多种方言,单测容易用H2替换运行.

但实际使用发现了一个严峻的问题,严峻到不得不放弃他的问题... ...

他需要Instrument的支持.(子类使用父类的静态方法但是要在字节码中改为子类调用(复制了那些方法到子类... ...))

且无论是动态方案还是静态方案都需要修改IDE配置.

这意味着我只要在现有项目里使用就会有一群开发过来揍我

Mybatis SqlBuilder&@SelectProvider

绕了一圈,回到了原点... ...

但这个方案的确是满足了解决了上面3个问题.

org.apache.ibatis.jdbc.SQL本身提供了几个方法方便拼写简单的SQL.

例子如下:

new SQL()
.SELECT(COLUMNS)
.FROM("user AS u")
.INNER_JOIN("user_info AS ui ON u.user_id = ui.user_id")
.WHERE("u.user_type = #{userType}")
.WHERE("u.deleted = 0")
.ORDER("u.user_id")
.toString()
+ " LIMIT #{start},#{num}";

LIMIT要自己拼,因为他不是标准SQL.

接下来接口一样定义,用上对应注解(@UpdateProvider,@InsertProvider,@DeleteProvider)

    @SelectProvider(type = UserProvider.class, method = "getUserByType")
UserInfo getUserByType(@Param("userType") int userType);

JdbcTemplate

使用NamedParameterJdbcTemplate会感觉好一点,占位符可以用:name的形式.

我们spring也一起用,对应的依赖也有.

这个也可行,而且写起来还可以,不过他本身缺少SQL拼接方便的工具,适合写简单没有使用条件分支生成SQL的情况.

这个网上资料很多,这里稍微列一些常用的需求.

根据class自动映射

可以使用BeanPropertyRowMapper,会按照属性进行SQL字段的关联,java的驼峰会变成小写和下划线的形式进行匹配.

例子:

private static final BeanPropertyRowMapper<User> USER_MAPPER = BeanPropertyRowMapper.newInstance(User.class);  

... ...

MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("userId", userId);
List<ServiceApply> applies = mTemplate.query(
"SELECT user_id,user_name,created FROM user WHERE user_id=:userId",
params, USER_MAPPER);

获取插入ID

KeyHolder key = new GeneratedKeyHolder();
mTemplate.update(
"INSERT INTO user(user_name,age) VALUES (:name,:age)",
params, key);
Number keyValue = key.getKey();

批量插入

List<MapSqlParameterSource> batchParams = names
.stream()
.distinct()
.map(e -> new MapSqlParameterSource("name", name))
.collect(Collectors.toList());
mTemplate.batchUpdate(
"INSERT IGNORE INTO user(user_name) VALUES (:name)",
batchParams.toArray(new SqlParameterSource[0]));

参考链接:

https://github.com/shakarelic/mybatis-reload

https://www.jooq.org/

http://javalite.io/activejdbc

https://zh.wikipedia.org/wiki/Active_Record

http://www.mybatis.org/mybatis-3/statement-builders.html

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.html

如何更简单方便地执行SQL操作?的更多相关文章

  1. Mybatis-plus 实体类新增属性,使用实体类执行sql操作时忽略该属性 注解

    @TableField(exist = false) 注解加载bean属性上,表示当前属性不是数据库的字段,但在项目中必须使用,这样在新增等使用bean的时候,mybatis-plus就会忽略这个,不 ...

  2. EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

    一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文 ...

  3. 三种执行SQL语句的的JAVA代码

    问题描述: 连接数据库,执行SQL语句是必不可少的,下面给出了三种执行不通SQL语句的方法. 1.简单的Statement执行SQL语句.有SQL注入,一般不使用. public static voi ...

  4. MySQL执行sql查询并上传至远程服务器

    最近项目中有需要做一个shell脚本,可以对一个数据库执行sql操作,并将结果转为txt,筛选结果用tab隔开,保存至一个远程服务器上,以供其他人用Excel读取用txt中的内容. MySQL中将结果 ...

  5. 使用Hive或Impala执行SQL语句,对存储在HBase中的数据操作

    CSSDesk body { background-color: #2574b0; } /*! zybuluo */ article,aside,details,figcaption,figure,f ...

  6. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据操作(二)

    CSSDesk body { background-color: #2574b0; } /*! zybuluo */ article,aside,details,figcaption,figure,f ...

  7. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据操作

    http://www.cnblogs.com/wgp13x/p/4934521.html 内容一样,样式好的版本. 使用Hive或Impala执行SQL语句,对存储在Elasticsearch中的数据 ...

  8. 追踪SQL Server执行delete操作时候不同锁申请与释放的过程

    一直以为很了解sqlserver的加锁过程,在分析一些特殊情况下的死锁之后,尤其是并发单表操作发生的死锁,对于加解锁的过程,有了一些重新的认识,之前的知识还是有一些盲区在里面的.delete加锁与解锁 ...

  9. C#参数化执行SQL语句,防止漏洞攻击本文以MySql为例【20151108非查询操作】

    为什么要参数化执行SQL语句呢? 一个作用就是可以防止用户注入漏洞. 简单举个列子吧. 比如账号密码登入,如果不用参数, 写的简单点吧,就写从数据库查找到id和pw与用户输入一样的数据吧 sql:se ...

随机推荐

  1. MBR分区操作-增加、扩展、删除

    MBR分区操作-增加.扩展.删除 GPT分区参考 http://www.blogjava.net/haha1903/archive/2011/12/21/366942.html l  fdisk 显示 ...

  2. navicat连接centos7上mysql:2003-Can't connect to MySQL server (10060)

    问题解决步骤: 1.参考http://jingyan.baidu.com/article/95c9d20dac9040ec4f75617a.html,发现是防火墙未关闭: 2.关闭并禁止firewal ...

  3. AspNet Core 下利用普罗米修斯+Grafana构建Metrics和服务器性能的监控 (无心打造文字不喜勿喷谢谢!)

    概述 Prometheus的主要特点 组件 结构图 适用场景 不适用场景 安装node_exporter,系统性能指数收集(收集系统性能情况) 下载文件 解压并复制node_exporter应用程序到 ...

  4. 广搜迷之RE及迷之WA

    最近做广搜的时候天天迷之RE,经过dalao@口昭寿指点,我把string数组换成了char二维数组就AC了,(然而我并不知道为什么) 传送门  <——以这个题为例 #include <b ...

  5. java精确计算、精确计算工具类

    java精确计算 package org.aisino.erp.webservice.dzfp.util; import java.math.BigDecimal; public class Math ...

  6. 2018-2019网络对抗技术 20165220 Exp4 恶意代码分析

    实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systracer套件. ...

  7. Android中View的绘制流程(专题讲解)

    Android中的UI视图有两种方式实现:.xml文件(实现代码和UI的分离)和代码实现. Android的UI框架基本概念: 1. Activity:基本的页面单元,Activity包含一个Wind ...

  8. thrift小试--C++

    [转自]http://blog.csdn.net/poechant/article/details/6618284# Thrift可以实现C++.Java.Python等多种语言的自动生成,此处以C+ ...

  9. NOIP2000普及组 T1计算器的改良

    主要考字符串处理,把等式从等号中间断开,左边的区域为left,右边的区域为right. 开四个数组分别用来存储区域left和right中未知数的系数,区域left和right中的常数 先处理区域lef ...

  10. Luogu 3758 [TJOI2017]可乐(有向图邻接矩阵幂的意义 矩阵快速幂)

    题目描述 加里敦星球的人们特别喜欢喝可乐.因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的1号城市上.这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆.它每一秒都会随机 ...