Java 生成带有可选起始日期和截止日期的SQL where子句
我正在寻找最短的Java 生成带有可选起始日期和截止日期的SQL where子句,java,sql,Java,Sql,我正在寻找最短的if语句(或其他语句)来构建一个SQL查询,以支持各种情况: 给定“从”日期,没有“到”日期 给定“截止”日期,无“起始”日期 考虑到“从”和“到”日期 没有“从”或“到”日期 缺少“从”或“到”日期表示空值。根据语句的输出,将向类型化查询动态添加一个特定的where子句 如果,我可以用一个嵌套的解决它,但它看起来很难看。有什么建议吗?在创建SQL语句时,您不仅有查询字符串,还有准备好的变量。您将希望同时向这两个对象添加。比如: StringBuilder sql = new S
if
语句(或其他语句)来构建一个SQL查询,以支持各种情况:
where
子句
如果,我可以用一个嵌套的
解决它,但它看起来很难看。有什么建议吗?在创建SQL语句时,您不仅有查询字符串,还有准备好的变量。您将希望同时向这两个对象添加。比如:
StringBuilder sql = new StringBuilder();
List<Object> variables = new ArrayList<>();
sql.append("SELECT <columns> FROM <tables> WHERE 1");
if (fromDate != null) {
sql.append(" AND date >= ?");
variables.add(fromDate);
}
if (toDate != null) {
sql.append(" AND date <= ?");
variables.add(toDate);
}
我通常使用StringBuilder构建where子句
StringBuilder sql = new StringBuilder();
StringBuilder sqlWhere = new StringBuilder();
ArrayList<Object> params = new ArrayList<Object>();
if (fromDate != null) {
sqlWhere.append(" fromDate >= ? ");
params.add( fromDate );
}
if (toDate != null) {
sqlWhere.append(" toDate <= ? " + (parms.size() > 0 ? " and " : "") );
params.add( toDate );
}
if ( sqlWhere.size() > 0 ) {
sql.append(" where ").append( sqlWhere.toString() );
}
StringBuilder sql=new StringBuilder();
StringBuilder sqlWhere=新的StringBuilder();
ArrayList params=新的ArrayList();
if(fromDate!=null){
sqlWhere.append(“fromDate>=?”;
参数添加(起始日期);
}
如果(toDate!=null){
太长了,读不下去了。
使用Three Ten Extra中的LocalDateRange
类,以及StringBuilder::append
调用中的三元语句
StringBuilder sql = new StringBuilder();
sql.append( "SELECT * \n" );
sql.append( "FROM event_ \n" );
sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" ); // If the range is unbounded, meaning no beginning AND no ending.
sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" ); // "not before" is a short way of saying "is equal to or later".
sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
sql.append( range.isUnboundedEnd() ? "" : "stop_ < ? \n" ); // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
sql.append( "; \n" );
这是我们的SQL查询构建代码
部分不开始<?
是表示“等于或更高”的简短方式。我喜欢这种语法与结尾的另一部分的对称性:“其中x不在开始之前,y在结束之前”
用开始包含和结束独占来定义时间跨度的逻辑称为半开放。这种方法通常是处理日期-时间最明智的方法。使用这种方法,时间跨度可以整齐地彼此相邻,没有间隙
StringBuilder sql = new StringBuilder();
sql.append( "SELECT * \n" );
sql.append( "FROM event_ \n" );
sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" ); // If the range is unbounded, meaning no beginning AND no ending.
sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" ); // "not before" is a short way of saying "is equal to or later".
sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
sql.append( range.isUnboundedEnd() ? "" : "stop_ < ? \n" ); // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
sql.append( "; \n" );
当以开始和结束运行时
范围=2021-01-23/2021-02-17
sql=
选择*
来自事件(u)
哪里
不启动?
和
停止?
;
当只从开始运行时
范围=2021-01-23/+9999999-12-31
sql=
选择*
来自事件(u)
哪里
不启动?
;
当只以结尾运行时
范围=-9999999-01-01/2021-02-17
sql=
选择*
来自事件(u)
哪里
停止?
;
当没有开始也没有结束的时候
范围=-9999999-01-01/+99999999-12-31
sql=
选择*
来自事件(u)
;
你能发布你的代码吗?这样我们就可以看到它看起来有多难看了。@kingdom将澄清作为对你的问题的编辑,而不是评论。如果你正在生成SQL代码,那么就这样说。正如前面所建议的,发布一些代码可能会有所帮助。我必须坚持使用项目库,因此没有jOOQ:(
for(int index = 1; index <= params.size() : index++) {
ps.setObject( index, obj );
}
StringBuilder sql = new StringBuilder();
sql.append( "SELECT * \n" );
sql.append( "FROM event_ \n" );
sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" ); // If the range is unbounded, meaning no beginning AND no ending.
sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" ); // "not before" is a short way of saying "is equal to or later".
sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
sql.append( range.isUnboundedEnd() ? "" : "stop_ < ? \n" ); // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
sql.append( "; \n" );
LocalDate start = LocalDate.of( 2021 , Month.JANUARY , 23 );
LocalDate end = LocalDate.of( 2021 , Month.FEBRUARY , 17 );
LocalDateRange range = LocalDateRange.of( start , end ); // Both beginning and ending.
// LocalDateRange range = LocalDateRange.ofUnboundedEnd( start ); // Beginning only.
// LocalDateRange range = LocalDateRange.ofUnboundedStart( end ); // Ending only.
// LocalDateRange range = LocalDateRange.ofUnbounded(); // Neither beginning nor ending.
Objects.requireNonNull( range );
StringBuilder sql = new StringBuilder();
sql.append( "SELECT * \n" );
sql.append( "FROM event_ \n" );
sql.append( range.equals( LocalDateRange.ofUnbounded() ) ? "" : "WHERE \n" ); // If the range is unbounded, meaning no beginning AND no ending.
sql.append( range.isUnboundedStart() ? "" : "NOT start_ < ? \n" ); // "not before" is a short way of saying "is equal to or later".
sql.append( range.isUnboundedStart() || range.isUnboundedEnd() ? "" : "AND \n" );
sql.append( range.isUnboundedEnd() ? "" : "stop_ < ? \n" ); // Half-open approach where beginning is *inclusive* while the ending is *exclusive*.
sql.append( "; \n" );
System.out.println( "range = " + range );
System.out.println( "sql = \n" + sql );