$ JDBC笔记
$ 概念
$ Schema
在MySQL中schema
和database
是同义词,在SQL语句中可以把关键字database
替换为关键字schema
。但是在Oracle, DB2等数据库中有所不同。
参考:
- Difference Between Schema / Database in MySQL (opens new window)
- 数据库中的Schema是什么? (opens new window)
- What is a Database Schema? (opens new window)
- Database-specific Catalog and Schema Considerations (opens new window)
- ALL_TABLES - Catalog Views - Oracle to SQL Server Migration (opens new window)
- List All Tables In Oracle Database Query (opens new window)
- System Tables and Views (opens new window)
- ORACLE系统表大全 (opens new window)
$ Connection接口
$ Timeout
Connection.setNetworkTimeout()
参考:
$ 切换Database
使用jdbc接口而不要执行USE <databasename>
语句:
Connection.setCatalog();
原因:
- 数据库无关性
- driver可能需要执行一些其他操作
注意:
- 不会影响已经存在的或者prepared的statement
参考:
- Java, how to change current database to another? (opens new window)
- 5.3 Configuration Properties for Connector/J (opens new window)
$ 查询
$ 查询元数据
Oracle获取列comment:
OracleConnection oraCon = (OracleConnection)con;
oraCon.setRemarksReporting(true);
DatabaseMetaData dmt = con.getMetaData();
colRs = dmt.getColumns(null, "dbo", 'Student', null);
while (colRs.next()) {
System.out.println(colRs.getString("REMARKS");
}
MySQL获取表及列comment:连接参数中指定useInformationSchema=true
。
参考:
- How to get Column Comments in JDBC (opens new window)
- Retrieve mysql table comment using DatabaseMetaData (opens new window)
$ Satement
Statement.setMaxRows() 给JDBC驱动程序一个提示,当此Statement生成的ResultSet对象需要更多行时,应该从数据库中获取行数。
Statement.setFetchSize() 将此Statement对象生成的任何ResultSet对象可以包含的最大行数限制为给定数目。
参考:
$ MySQL时区
相关配置参数的组合情况:
useLegacyDatetimeCode=True(默认) | useLegacyDatetimeCode=False | |
---|---|---|
useTimezone=False(默认) | 将年月日时分秒+"连接时区", 创建时间戳 | 将年月日时分秒+"配置时区"创建时间戳 |
useTimezone=True | 先将年月日时分秒+"连接时区", 创建时间戳 再进行时区调整, 调整为"配置时区". | 将年月日时分秒+"配置时区"创建时间戳 |
参考:
5.3 Configuration Properties for Connector/J (opens new window)
Chapter 16 Known Issues and Limitations (opens new window)
$ 插入数据
$ Null处理
Statementstmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT ...");
while (rs.next()) {
int num = rs.getInt(1);
if (rs.wasNull()) {
// num is null
} else {
// num is not null
}
}
$ 日期类型
JDBC 4.2 以下:
不带时间的DATE
类型:
ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
//endDate是java.util.Date类的实例
ps.setDate(2, new java.sql.Date(endDate.getTime());
ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));
// Since Java 8
ps.setDate(2, java.sql.Date.valueOf(java.time.LocalDate.now()));
带时间的TIMESTAMP
或 DATETIME
类型:
ps.setTimestamp(2, java.sql.Timestamp.valueOf("2013-09-04 13:30:00");
ps.setTimestamp(2, new java.sql.Timestamp(endDate.getTime()));
ps.setTimestamp(2, new java.sql.Timestamp(System.currentTimeMillis()));
// Since Java 8
ps.setTimestamp(2, java.sql.Timestamp.from(java.time.Instant.now()));
ps.setTimestamp(2, java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()));
JDBC 4.2 以上:
PreparedStatement.setObject(1 , localDate);
ResultSet.getObject(1 , LocalDate.class);
使用EPOCH_DATE
替代日期0000-00-00
:
LocalDate EPOCH_DATE = LocalDate.ofEpochDay(0); // 1970-01-01 is day 0 in Epoch counting.