首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >7天前选择JDBC

7天前选择JDBC
EN

Stack Overflow用户
提问于 2017-04-24 03:30:36
回答 2查看 333关注 0票数 1

我正在创建一个JDBC到一个餐馆数据库程序,在那里用户可以看到过去7天利润的报告。

我不知道如何选择过去的七天,所以这个节目显示了从七天前的总利润。

我想知道我如何做到这一点,我的代码如下所示:

代码语言:javascript
复制
   public static void showSevenDaysAgoSells() {
            double value = 0.0;
            try {       
                System.out.println("----Showing last seven days profit----");
                PreparedStatement stmt = conn.prepareStatement("SELECT sum(total) FROM sells WHERE date > date_from_7_days_ago");
                java.sql.Date date= new java.sql.Date(new java.util.Date().getTime());
                stmt.setObject(1, LocalDate.now(ZoneId.of("America/Caracas")).minusWeeks(1));               
                stmt.executeQuery();
                ResultSet rs = stmt.executeQuery();
                rs.next();
                String sum = rs.getString(1);
                value = Double.parseDouble(sum);
                System.out.println("DAYS" + "\t" +  "TOTAL");
                System.out.println(date+ "\t" + sum);
                } catch(Exception e) {
                e.printStackTrace();
            }
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-24 07:49:50

tl;dr

代码语言:javascript
复制
PreparedStatement stmt = conn.prepareStatement(
    "SELECT sum( total_ ) FROM sells_ WHERE date_ > ? ;"
);

…和…

代码语言:javascript
复制
stmt.setObject(                            // Use JDBC 4.2 method for passing/fetching java.time types.
    1 ,                                    // Specify which placeholder `?` in PreparedStatement (1, 2, 3, etc.). In this case, `1`. 
    LocalDate.now(                         // Get current date (today) in desired/expected time zone. 
        ZoneId.of( "America/Montreal" )
    ).minusWeeks( 1 )                      // Go back in time a week (7 days).
)

?

在string中嵌入变量date_from_7_days_ago。因此,它被视为字符串文本,而不是Java变量的传递值。将该变量名替换为PreparedStatement的问号PreparedStatement占位符。

代码语言:javascript
复制
PreparedStatement stmt = conn.prepareStatement( "SELECT sum( total_ ) FROM sells_ WHERE date_ > ? ;" );

提示:避免使用保留词(如datetotal )命名列和其他数据库标识符。各种SQL数据库总保留一千多个保留字,所以冲突比人们想象的更容易。SQL规范明确承诺不保留任何带有尾下划线的单词。因此,请将所有标识符命名为date_total_等,这样就不必担心冲突了。

避免遗留日期-时间类

这个问题和另一个答案都使用了一些麻烦的旧日期时间类,这些类的设计都很糟糕,令人困惑,并且存在缺陷。它们现在是遗留的,被java.time类所取代。

java.time.LocalDate类表示一个日期纯值,没有一天的时间,也没有时区.

时区

无论是问题还是其他答案,都忽略了时区这个关键问题。

在确定日期时,时区是必需的。在任何特定时刻,全球各地的日期因地区而异。例如,午夜后几分钟在法国巴黎是一个新的一天,而仍然“昨天”在魁北克省

continent/region格式指定continent/region,如America/MontrealAfrica/CasablancaPacific/Auckland。不要使用3-4字母的缩写,如ESTIST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

如果您的业务逻辑需求规定了UTC而不是特定的时区,请使用常量ZoneOffset.UTC

代码语言:javascript
复制
LocalDate today = LocalDate.now( ZoneOffset.UTC ) ;

为了得到七天前(一周),让对象做日期-数学。

代码语言:javascript
复制
LocalDate weekAgo = LocalDate.minusWeeks( 1 );

JDBC

如果您的JDBC驱动程序符合JDBC4.2及更高版本,则可以通过PreparedStatement.setObjectResultSet.getObject直接使用java.time类型。

代码语言:javascript
复制
myPreparedStatement.setObject( … , weekAgo );

并检索:

代码语言:javascript
复制
LocalDate ld = myResultSet.getObject( … , LocalDate.class );

至少这两个用于Postgres的JDBC驱动程序可能已经更新为JDBC4.2,尽管我还没有测试它们是否支持java.time类型。

如果您的JDBC驱动程序不符合要求,那么回到使用java.sql。但要尽可能简短地这样做,立即转换为/从java.time。若要进行转换,请查看添加到旧类中的新方法。在这种情况下,我们将不得不回到使用java.sql.Date时使用valueOftoLocalDate方法。

代码语言:javascript
复制
myPreparedStatement.setObject( … , java.sql.Date.valueOf( weekAgo ) );

并检索:

代码语言:javascript
复制
LocalDate ld = myResultSet.getDate( … ).toLocalDate() ;

关于java.time

java.time框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

尤达-时间项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

在哪里获得java.time类?

  • Java 8Java 9,以及后来的
    • 内置的。
    • 带有捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • java.time的大部分功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter更多

票数 3
EN

Stack Overflow用户

发布于 2017-04-24 06:52:22

代码语言:javascript
复制
    final long OneDayMillis = 86400000l;
    PreparedStatement stmt = conn.prepareStatement("SELECT sum(total) FROM sells WHERE date > ?");
    java.sql.Date date = new java.sql.Date(System.currentTimeMillis()-OneDayMillis*7l);
    stmt.setDate(1, date);

考虑到服务器的当前日期可能与客户端计算机的当前日期不同,因此最好将服务器端日期与SQL语句一起使用,如

代码语言:javascript
复制
SELECT sum(total) FROM sells WHERE date > current_date - integer '7'

没有来自客户端的任何参数绑定。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43579354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档