[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.우리는 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, 더 여기에 몇 가지 유용한 클래스를 찾을 수 있습니다.
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
'SQL' 카테고리의 다른 글
[SQL] 기록 횟수> (1)를 찾기위한 SQL 쿼리 (0) | 2020.04.02 |
---|---|
[SQL] MySQL의 동적 피벗 (0) | 2020.04.02 |
[SQL] 어떻게 날짜에 주 수를 변환하는? (0) | 2020.04.02 |
[SQL] MySQL은 : 분할 쉼표는 여러 행으로 구분 된 목록 (0) | 2020.04.02 |
[SQL] 합니까 sqlite3를 외부 키 제약 조건을 지원하지? (0) | 2020.04.02 |