mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-12-21 23:08:52 -05:00
Start at documentation
This commit is contained in:
parent
ac4216709e
commit
b861d63115
117
readme.md
117
readme.md
@ -3,12 +3,14 @@ POJOs (Plain Old Java Objects) from the database in different types of collectio
|
|||||||
enforced throughout so neither casting nor ignoring warnings is required.
|
enforced throughout so neither casting nor ignoring warnings is required.
|
||||||
|
|
||||||
There are 2 different approaches to accomplish this. JdbcMapper generates code at compile time, QueryMapper does
|
There are 2 different approaches to accomplish this. JdbcMapper generates code at compile time, QueryMapper does
|
||||||
everything at runtime.
|
everything at runtime. Currently there are different packages for java6 and java8+, these are built from the same
|
||||||
|
source with a bit of sed-like magic, when the documentation refers to classes only available in java8+ just know these
|
||||||
|
are obviously unavailable if you use the java6 version.
|
||||||
|
|
||||||
Why
|
Why
|
||||||
---
|
---
|
||||||
|
|
||||||
The java.sql API is horrible, ResultSet.wasNull() ?, enough said. Hibernate is black magic that generates some truly
|
The [java.sql](https://docs.oracle.com/javase/8/docs/api/java/sql/package-summary.html) API is horrible, [ResultSet.wasNull()](https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#wasNull--) ?, enough said. Hibernate is black magic that generates some truly
|
||||||
awful SQL queries. Everything in between insists on writing your queries and/or forcing you to fully annotate all your
|
awful SQL queries. Everything in between insists on writing your queries and/or forcing you to fully annotate all your
|
||||||
POJOs with information on how to map them from SQL, making them some combination of too verbose, too slow, or too much
|
POJOs with information on how to map them from SQL, making them some combination of too verbose, too slow, or too much
|
||||||
unknown magic.
|
unknown magic.
|
||||||
@ -25,7 +27,116 @@ Goals
|
|||||||
Column to Object Mapping
|
Column to Object Mapping
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
todo: explain how individual columns are mapped to simple objects
|
All decisions as to which ResultSet method(s) to call are based on the Java type being mapped to, because we have no
|
||||||
|
knowledge of any database schema. These mappings rarely if ever need changed, they can be overridden with QueryMapper
|
||||||
|
but not currently at compile-time with JdbcMapper.
|
||||||
|
|
||||||
|
If you are thinking 'shut up and show me the code already' refer to [ResultSetUtil.java](https://github.com/moparisthebest/JdbcMapper/blob/master/common/src/main/java/com/moparisthebest/jdbc/util/ResultSetUtil.java)
|
||||||
|
which contains the implementations actually called.
|
||||||
|
|
||||||
|
For the purposes of this mapping, consider 'rs' an instance of ResultSet, and 'index' an int index of a ResultSet column.
|
||||||
|
|
||||||
|
### numeric primitives
|
||||||
|
if the SQL value is NULL, 0 is returned for these, and no exception is thrown
|
||||||
|
##### byte
|
||||||
|
```java
|
||||||
|
return rs.getByte(index);
|
||||||
|
```
|
||||||
|
##### short
|
||||||
|
```java
|
||||||
|
return rs.getShort(index);
|
||||||
|
```
|
||||||
|
##### int
|
||||||
|
```java
|
||||||
|
return rs.getInt(index);
|
||||||
|
```
|
||||||
|
##### long
|
||||||
|
```java
|
||||||
|
return rs.getLong(index);
|
||||||
|
```
|
||||||
|
##### float
|
||||||
|
```java
|
||||||
|
return rs.getFloat(index);
|
||||||
|
```
|
||||||
|
##### double
|
||||||
|
```java
|
||||||
|
return rs.getDouble(index);
|
||||||
|
```
|
||||||
|
### numeric objects
|
||||||
|
these wrapper types are retrieved using the same function returning their primitives above, except null is returned
|
||||||
|
if the SQL value is NULL instead of 0
|
||||||
|
```java
|
||||||
|
x ret = rs.getX(index);
|
||||||
|
return rs.wasNull() ? null : ret;
|
||||||
|
```
|
||||||
|
##### java.math.BigDecimal
|
||||||
|
```java
|
||||||
|
return rs.getBigDecimal(index);
|
||||||
|
```
|
||||||
|
### boolean
|
||||||
|
in all cases of SQL NULL being returned, if primitive boolean is requested an SQLException is thrown, if Object Boolean
|
||||||
|
is requested then null is returned.
|
||||||
|
|
||||||
|
boolean has special handling due to many popular databases not actually having a boolean type (hi Oracle!),
|
||||||
|
forcing application level workarounds.
|
||||||
|
|
||||||
|
0/1 numeric types convert to boolean using the standard ResultSet API, but many systems use char/varchar of Y/N or T/F,
|
||||||
|
which we default to Y/N but can be set via system properties:
|
||||||
|
|
||||||
|
ResultSetUtil.TRUE=Y
|
||||||
|
ResultSetUtil.FALSE=N
|
||||||
|
|
||||||
|
First the standard ResultSet API is attempted:
|
||||||
|
```java
|
||||||
|
return rs.getBoolean(index);
|
||||||
|
```
|
||||||
|
If this does not throw an SQLException, it is returned directly
|
||||||
|
If SQLException is thrown, then we try to compare as a String:
|
||||||
|
```java
|
||||||
|
String bool = rs.getString(index);
|
||||||
|
boolean ret = ResultSetUtil.TRUE.equals(bool);
|
||||||
|
if (!ret && !ResultSetUtil.FALSE.equals(bool))
|
||||||
|
throw new SQLException(String.format("Implicit conversion of database string to boolean failed on column '%d'. Returned string needs to be '%s' or '%s' and was instead '%s'.", index, ResultSetUtil.TRUE, ResultSetUtil.FALSE, bool));
|
||||||
|
return ret;
|
||||||
|
```
|
||||||
|
The returned string MUST be either TRUE or FALSE (or null, for Object Boolean) or an exception will be thrown
|
||||||
|
### Misc Objects
|
||||||
|
For all of these, when SQL NULL is returned, it maps to null
|
||||||
|
##### String
|
||||||
|
```java
|
||||||
|
return rs.getString(index);
|
||||||
|
```
|
||||||
|
##### byte[]
|
||||||
|
```java
|
||||||
|
return rs.getBytes(index);
|
||||||
|
```
|
||||||
|
##### java.sql.Ref
|
||||||
|
```java
|
||||||
|
return rs.getRef(index);
|
||||||
|
```
|
||||||
|
##### java.sql.Blob
|
||||||
|
```java
|
||||||
|
return rs.getBlob(index);
|
||||||
|
```
|
||||||
|
##### java.sql.Clob
|
||||||
|
```java
|
||||||
|
return rs.getClob(index);
|
||||||
|
```
|
||||||
|
##### java.sql.Array
|
||||||
|
```java
|
||||||
|
return rs.getArray(index);
|
||||||
|
```
|
||||||
|
##### java.sql.Struct
|
||||||
|
```java
|
||||||
|
return rs.getObject(index);
|
||||||
|
```
|
||||||
|
##### *
|
||||||
|
If nothing else fits, we call getObject and cross our fingers with QueryMapper at runtime, this is a compile-time error
|
||||||
|
with JdbcMapper. todo: is this actually a compile-time error? it *should* be, check...
|
||||||
|
```java
|
||||||
|
return rs.getObject(index);
|
||||||
|
```
|
||||||
|
todo: finish documenting this
|
||||||
|
|
||||||
Row to Object Mapping
|
Row to Object Mapping
|
||||||
---------------------
|
---------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user