복붙노트

[SQL] 삽입 및 인출 java.time.LocalDate는 H2와 같은 SQL 데이터베이스에서 /에 객체

SQL

삽입 및 인출 java.time.LocalDate는 H2와 같은 SQL 데이터베이스에서 /에 객체

어떻게 삽입과 같은 H2 데이터베이스 엔진으로 SQL 데이터베이스에 JDBC를 통해 같은 LOCALDATE 같은 java.time 유형을 가져올 수?

PreparedStatement의 ::하여 setDate와의 ResultSet :: GETDATE를 사용하는 기존 방법은 기존의 java.sql.Date 유형에 대해 작동합니다. 나는이 귀찮은 오래된 날짜 - 시간 클래스를 사용하지 않도록합니다.

JDBC 드라이버를 통해 java.time 유형을 보내기위한 현대적인 방법은 무엇입니까?

해결법

  1. ==============================

    1.우리는 JDBC를 통해 java.time 객체를 교환하는 두 가지 경로가 있습니다

    우리는 JDBC를 통해 java.time 객체를 교환하는 두 가지 경로가 있습니다

    같은 java.util.Date, java.util.Calendar에, 및 java.sql.Date과 관련 java.sql의 클래스와 같은 기존의 날짜 - 시간의 수업은 끔찍한 엉망입니다. 잘못 설계된 해킹 방식과 내장, 그들은 결함, 번잡하고 혼란을 입증했다. 가능하면 그들을 피하십시오. 이제 java.time 클래스에 의해 대체.

    (2017-03 현재) H2를위한 내장 JDBC 드라이버는 JDBC 4.2을 준수 나타납니다.

    준수 드라이버는 이제 java.time 유형을 알고 있습니다. 그러나 방법의 정렬이 아니라 setLocalDate / getLocalDate를 추가하는 대신, JDBC위원회의 setObject /으로 getObject 메소드를 추가했다.

    데이터베이스에 데이터를 전송하려면 된 PreparedStatement에 java.time의 개체를 전달 :: setObject를합니다. 당신의 통과 인수의 Java 형은 드라이버가 감지하고 적절한 SQL 유형으로 변환됩니다. 자바 LOCALDATE은 SQL 날짜 형식으로 변환됩니다. 이러한 매핑의 목록은 JDBC 유지 보수 릴리스 4.2 PDF 문서의 부 (22)를 참조하십시오.

    myPreparedStatement.setObject ( 1 , myLocalDate ); // Automatic detection and conversion of data type.
    

    데이터베이스에서 데이터를 검색하려면, ResultSet의 ::으로 getObject를 호출한다. 오히려 결과 개체 개체를 캐스팅보다 우리는 여분의 인수, 우리가 받게 될 데이터 유형의 클래스를 전달할 수 있습니다. 예상 클래스를 지정하여, 우리는 형 안전 점검 및 IDE 및 컴파일러에 의해 확인 얻을 수 있습니다.

    LocalDate localDate = myResultSet.getObject ( "my_date_column_" , LocalDate.class ); 
    

    여기에 삽입하고, H2 데이터베이스에 LOCALDATE 값을 선택하는 방법을 보여주는 전체 작업 예제 응용 프로그램입니다.

    package com.example.h2localdate;
    
    import java.sql.*;
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.util.UUID;
    
    /**
     * Hello world!
     */
    public class App {
        public static void main ( String[] args ) {
            App app = new App ( );
            app.doIt ( );
        }
    
        private void doIt ( ) {
            try {
                Class.forName ( "org.h2.Driver" );
            } catch ( ClassNotFoundException e ) {
                e.printStackTrace ( );
            }
    
            try (
                Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:trash_me_db_" ) ;
                Statement stmt = conn.createStatement ( ) ;
            ) {
                String tableName = "test_";
                String sql = "CREATE TABLE " + tableName + " (\n" +
                    "  id_ UUID DEFAULT random_uuid() PRIMARY KEY ,\n" +
                    "  date_ DATE NOT NULL\n" +
                    ");";
                stmt.execute ( sql );
    
                // Insert row.
                sql = "INSERT INTO test_ ( date_ ) " + "VALUES (?) ;";
                try ( PreparedStatement preparedStatement = conn.prepareStatement ( sql ) ; ) {
                    LocalDate today = LocalDate.now ( ZoneId.of ( "America/Montreal" ) );
                    preparedStatement.setObject ( 1, today.minusDays ( 1 ) );  // Yesterday.
                    preparedStatement.executeUpdate ( );
                    preparedStatement.setObject ( 1, today );                  // Today.
                    preparedStatement.executeUpdate ( );
                    preparedStatement.setObject ( 1, today.plusDays ( 1 ) );   // Tomorrow.
                    preparedStatement.executeUpdate ( );
                }
    
                // Query all.
                sql = "SELECT * FROM test_";
                try ( ResultSet rs = stmt.executeQuery ( sql ) ; ) {
                    while ( rs.next ( ) ) {
                        //Retrieve by column name
                        UUID id = rs.getObject ( "id_", UUID.class );  // Pass the class to be type-safe, rather than casting returned value.
                        LocalDate localDate = rs.getObject ( "date_", LocalDate.class );  // Ditto, pass class for type-safety.
    
                        //Display values
                        System.out.println ( "id_: " + id + " | date_: " + localDate );
                    }
                }
    
            } catch ( SQLException e ) {
                e.printStackTrace ( );
            }
        }
    }
    

    실행하면.

    H2를 들어, 위의 코드는 당신이 가지고 추천하는 도로입니다. 그러나 참고로, JDBC 4.2 아직 준수하지 않는 다른 데이터베이스, 나는 어떻게 java.time과 java.sql의 유형 사이 간단히 변환에 당신을 표시 할 수 있습니다. 변환 코드의이 종류는 내가 아래 표와 같이 확실히 H2에서 실행 있지만 이렇게하면 지금 우리는 간단한 방법은 위 가지고 바보입니다.

    데이터베이스에 데이터를 보내려면, 오래된 클래스에 추가 된 새로운 방법을 사용하여 java.sql.Date 객체에 LOCALDATE을 변환합니다.

    java.sql.Date mySqlDate = java.sql.Date.valueOf( myLocalDate );
    

    그런 다음 PreparedStatement의 ::하여 setDate 메서드에 전달합니다.

    preparedStatement.setDate ( 1, mySqlDate );
    

    데이터베이스에서 검색하려면, java.sql.Date 객체를 얻기 위해 ResultSet의 :: GETDATE를 호출한다.

    java.sql.Date mySqlDate = myResultSet.getDate( 1 );
    

    그런 다음 즉시 LOCALDATE을 변환합니다. 당신은 가능한 한 짧게과 java.sql의 개체를 처리해야합니다. 단지 java.time 유형을 사용하여 모든 비즈니스 로직과 다른 작업을 수행.

    LocalDate myLocalDate = mySqlDate.toLocalDate();
    

    여기 H2 데이터베이스에 java.time 형태를 가지는 java.sql 유형의 사용을 보여주는 전체 예제 응용 프로그램입니다.

    package com.example.h2localdate;
    
    import java.sql.*;
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.util.UUID;
    
    /**
     * Hello world!
     */
    public class App {
        public static void main ( String[] args ) {
            App app = new App ( );
            app.doIt ( );
        }
    
        private void doIt ( ) {
            try {
                Class.forName ( "org.h2.Driver" );
            } catch ( ClassNotFoundException e ) {
                e.printStackTrace ( );
            }
    
            try (
                Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:trash_me_db_" ) ;
                Statement stmt = conn.createStatement ( ) ;
            ) {
                String tableName = "test_";
                String sql = "CREATE TABLE " + tableName + " (\n" +
                    "  id_ UUID DEFAULT random_uuid() PRIMARY KEY ,\n" +
                    "  date_ DATE NOT NULL\n" +
                    ");";
                stmt.execute ( sql );
    
                // Insert row.
                sql = "INSERT INTO test_ ( date_ ) " + "VALUES (?) ;";
                try ( PreparedStatement preparedStatement = conn.prepareStatement ( sql ) ; ) {
                    LocalDate today = LocalDate.now ( ZoneId.of ( "America/Montreal" ) );
                    preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today.minusDays ( 1 ) ) );  // Yesterday.
                    preparedStatement.executeUpdate ( );
                    preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today ) );  // Today.
                    preparedStatement.executeUpdate ( );
                    preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today.plusDays ( 1 ) ) );  // Tomorrow.
                    preparedStatement.executeUpdate ( );
                }
    
                // Query all.
                sql = "SELECT * FROM test_";
                try ( ResultSet rs = stmt.executeQuery ( sql ) ; ) {
                    while ( rs.next ( ) ) {
                        //Retrieve by column name
                        UUID id = ( UUID ) rs.getObject ( "id_" );  // Cast the `Object` object to UUID if your driver does not support JDBC 4.2 and its ability to pass the expected return type for type-safety.
                        java.sql.Date sqlDate = rs.getDate ( "date_" );
                        LocalDate localDate = sqlDate.toLocalDate ();  // Immediately convert into java.time. Mimimize use of java.sql types.
    
                        //Display values
                        System.out.println ( "id_: " + id + " | date_: " + localDate );
                    }
                }
    
            } catch ( SQLException e ) {
                e.printStackTrace ( );
            }
        }
    }
    

    재미의 또 다른 시도 할 수 있습니다. 연결을 얻는에서 데이터 소스 구현을 사용하여이 시간. 그리고 이번에는 ISO 8601, -999999999-01-01 억 약 년 전을위한 일정 LocalDate.MIN을 시도.

    package work.basil.example;
    
    import java.sql.*;
    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.util.UUID;
    
    public class LocalDateMin
    {
        public static void main ( String[] args )
        {
            LocalDateMin app = new LocalDateMin();
            app.doIt();
        }
    
        private void doIt ()
        {
            org.h2.jdbcx.JdbcDataSource ds = new org.h2.jdbcx.JdbcDataSource();
            ds.setURL( "jdbc:h2:mem:localdate_min_example_db_;DB_CLOSE_DELAY=-1" );
            ds.setUser( "scott" );
            ds.setPassword( "tiger" );
    
            try (
                    Connection conn = ds.getConnection() ;
                    Statement stmt = conn.createStatement() ;
            )
            {
                String tableName = "test_";
                String sql = "CREATE TABLE " + tableName + " (\n" +
                        "  id_ UUID DEFAULT random_uuid() PRIMARY KEY ,\n" +
                        "  date_ DATE NOT NULL\n" +
                        ");";
                stmt.execute( sql );
    
                // Insert row.
                sql = "INSERT INTO test_ ( date_ ) " + "VALUES (?) ;";
                try ( PreparedStatement preparedStatement = conn.prepareStatement( sql ) ; )
                {
                    LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
                    preparedStatement.setObject( 1 , LocalDate.MIN );  // MIN =
                    preparedStatement.executeUpdate();
                }
    
                // Query all.
                sql = "SELECT * FROM test_";
                try ( ResultSet rs = stmt.executeQuery( sql ) ; )
                {
                    while ( rs.next() )
                    {
                        //Retrieve by column name
                        UUID id = rs.getObject( "id_" , UUID.class );  // Pass the class to be type-safe, rather than casting returned value.
                        LocalDate localDate = rs.getObject( "date_" , LocalDate.class );  // Ditto, pass class for type-safety.
    
                        //Display values
                        System.out.println( "id_: " + id + " | date_: " + localDate );
                    }
                }
    
            } catch ( SQLException e )
            {
                e.printStackTrace();
            }
        }
    }
    

    java.time 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 java.util.Date, 캘린더, 및 SimpleDateFormat에로 번잡 한 기존 레거시 날짜 - 시간의 수업을 대신하다.

    Joda 타임 프로젝트는 현재 유지 관리 모드에서 java.time 클래스로 마이그레이션을 조언한다.

    더 많은 내용은 오라클 자습서를 참조하십시오. 그리고 많은 예제와 설명은 스택 오버플로를 검색 할 수 있습니다. 사양은 JSR 310입니다.

    어디 java.time 클래스를 얻기 위해?

    ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가를위한 시험장이다. 당신은 같은 간격, YearWeek, YearQuarter, 더 여기에 몇 가지 유용한 클래스를 찾을 수 있습니다.

  2. from https://stackoverflow.com/questions/43039614/insert-fetch-java-time-localdate-objects-to-from-an-sql-database-such-as-h2 by cc-by-sa and MIT license