java 键入_在Java中键入Safe SQL

java 键入

字符串,字符串,字符串

无论您使用的是JPAMyBatis还是Spring Data JDBC之类的框架,总会最终将SQL语句声明为Java String。
这种方法的问题在于,您必须为每个语句编写测试,以确保它甚至是有效SQL。 没有编译时保证将执行SQL语句。

摆脱弦乐!

嵌入式SQL

我于1995年开始在COBOL中的IBM大型机编程上进行专业软件开发。 为了访问数据库,我们使用了“嵌入式SQL”:

 EXEC SQL  SELECT lastname, firstname  INTO :lastname, :firstname  FROM employee  WHERE id = :id 

关于嵌入式SQL的最酷的事情是,预编译器将检查每个SQL语句,并且仅在编译后的代码有效的情况下对其进行检查。
在下面您可以看到编译步骤。 (来源: http : //www.redbooks.ibm.com/redbooks/pdfs/sg246435.pdf

1-Java字符串

SQLJ

当我在2000年首次遇到Java和JDBC时,我很困惑,没有类似的东西存在。 我发现有一个名为SQLJ的计划始于1997年,但从未成功。 我不知道为什么,也许是因为这对于IDE供应商和预编译器很难集成,而Java对Java来说并不常见。 至少编译步骤类似于嵌入式SQL:

2-Java字符串

在比较JDBC和SQLJ时,我们可以看到与编写的代码量没有太大区别,但是#sql之后的所有内容都是类型安全的,因为预编译器会检查语法,与JDBC一样,其中可能包含一个String任何错误,该错误将在生产后期发生。

然后我找到了jOOQ!

十年前,卢卡斯·埃德(Lukas Eder)发行了jOOQ的第一个版本。 据该网站称,jOOQ是“用Java编写SQL的最简单方法”

让我们尝试使用jOOQ编写与上述相同的查询:

 List<EmployeeDTO> records = create 
          .select(EMPLOYEE.LASTNAME, EMPLOYEE.FIRSTNAME, EMPLOYEE.SALARY) 
          .from(EMPLOYEE) 
          .where(EMPLOYEE.SALARY.between( 80000 , 100000 )) 
          .fetchInto(EmployeeDTO. class ); 

很酷,不是吗? 是的-但是如何运作?

1.代码生成器

jOOQ使用代码生成器从数据库对象生成Java类。

例如,这是jOOQ为表EMPLOYEE生成的类的摘录:

 public class Employee extends TableImpl<EmployeeRecord> { 
     public static final Employee EMPLOYEE = new Employee(); 
     public final TableField<EmployeeRecord, Integer> ID = createField( "ID" , org.jooq.impl.SQLDataType.INTEGER.nullable( false ).identity( true ), this , "" ); 
     public final TableField<EmployeeRecord, String> LASTNAME = createField( "LASTNAME" , org.jooq.impl.SQLDataType.VARCHAR( 50 ).nullable( false ), this , "" ); 
     public final TableField<EmployeeRecord, String> FIRSTNAME = createField( "FIRSTNAME" , org.jooq.impl.SQLDataType.VARCHAR( 50 ).nullable( false ), this , "" ); 
     public final TableField<EmployeeRecord, Integer> SALARY = createField( "SALARY" , org.jooq.impl.SQLDataType.INTEGER, this , "" ); 
     public final TableField<EmployeeRecord, Integer> DEPARTMENT_ID = createField( "DEPARTMENT_ID" , org.jooq.impl.SQLDataType.INTEGER.nullable( false ), this , "" ); 
     public final TableField<EmployeeRecord, Integer> MANAGER_ID = createField( "MANAGER_ID" , org.jooq.impl.SQLDataType.INTEGER, this , "" );  } 

该表和所有列都有常量。 由于这些元数据类,因此无法在数据库中不存在SQL语句中使用类型。 并且由于您可以每次生成元数据,因此如果发生重大更改,数据库模型更改将无法编译您的代码。

在以后的文章中将介绍如何配置生成器以及可能的生成器输入格式。 (敬请关注)

2.领域特定语言

jOOQ的第二部分是DSL(特定于域的语言),它允许用Java编写SQL代码。
与String中SQL相比,DSL迫使我编写有效SQL!

例子

因此,让我们来看更多示例。 示例基于此数据模型:

4-Java字符串

 dsl.insertInto(DEPARTMENT) 
    .columns(DEPARTMENT.NAME) 
    .values( "HR" ) 
    .execute(); 

选择

 dsl.select(DEPARTMENT.NAME) 
     .from(DEPARTMENT) 
     .where(DEPARTMENT.NAME.eq( "IT" )) 
     .fetchOne(); 

更新资料

 dsl.update(DEPARTMENT) 
    .set(DEPARTMENT.NAME, "IT2" ) 
    .where(DEPARTMENT.ID.eq(departmentId)) 
    .execute(); 

删除

 dsl.deleteFrom(EMPLOYEE) 
    .where(EMPLOYEE.ID.eq(employeeId)) 
    .execute(); 

下一步是什么?

那只是一个简短的介绍。 在下一篇博客文章中,我们将更深入地了解jOOQ提供的所有功能。

同时,您可以在此处签出代码: https : //github.com/simasch/jooq-hr

翻译自: https://www.javacodegeeks.com/2019/12/type-safe-sql-in-java.html

java 键入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值