Overview
ResultSetConverter provides static methods that convert a JDBC ResultSet
into B4J-friendly List and Map structures. Column types are preserved
automatically (integers, doubles, booleans, dates, etc.). Unrecognized types default to strings.
All conversion methods (except GetFieldTypes and GetFieldList)
automatically close the ResultSet after processing.
Configuration
SetLowerCaseFieldNames
Sets whether column names are converted to lowercase when used as keys or headers. Applies globally to all subsequent calls. Default is false.
GetFieldTypes, GetFieldList, ToListOfMaps, ToListOfLists, ToMap, ToMapOfMaps, ToMapOfLists, ToJSON, ToJSONObject, ToCSV, and ToPagedJSON.- value — If true, all column names used as keys or headers are lowercased.
Example — SetLowerCaseFieldNames(false) (default):
[{"Name":"John", "Age":30, "HireDate":"2020-03-15"}, ...]
Example — SetLowerCaseFieldNames(true):
[{"name":"John", "age":30, "hiredate":"2020-03-15"}, ...]
Sample Source Data
All examples below use the following sample database table:
Employees
| Name (VARCHAR) | Age (INTEGER) | Salary (DOUBLE) | Active (BOOLEAN) | HireDate (DATE) |
|---|---|---|---|---|
| John | 30 | 55000.50 | true | 2020-03-15 |
| Jane | 25 | 48000.00 | true | 2021-07-01 |
| Bob | 40 | 72000.75 | false | 2018-11-20 |
SQL Query used:
SELECT Name, Age, Salary, Active, HireDate FROM Employees
GetFieldTypes Map Does not close RS
Returns a Map of column names to their JDBC type names. Useful for inspecting the schema of a ResultSet before processing it.
- rs — The ResultSet to inspect.
Output:
{ "Name": "VARCHAR", "Age": "INTEGER", "Salary": "DOUBLE", "Active": "BOOLEAN", "HireDate": "DATE" }
GetFieldList List Does not close RS
Returns a List of column names from the ResultSet.
- rs — The ResultSet to inspect.
Output:
["Name", "Age", "Salary", "Active", "HireDate"]
ToListOfMaps List
Converts the ResultSet into a List of Maps. Each row becomes a Map with column names as keys. If includeRowNumber is true, a 1-based row number is added as the first entry, using rowNumberColumnName as the key. Pass null for rowNumberColumnName to use the default key "Row".
- rs — The ResultSet to convert.
- includeRowNumber — If true, each Map includes a row number field.
- rowNumberColumnName — The key name for the row number field. Defaults to
"Row"if null.
Output (includeRowNumber = false):
[ {"Name": "John", "Age": 30, "Salary": 55000.5, "Active": true, "HireDate": "2020-03-15"}, {"Name": "Jane", "Age": 25, "Salary": 48000.0, "Active": true, "HireDate": "2021-07-01"}, {"Name": "Bob", "Age": 40, "Salary": 72000.75, "Active": false, "HireDate": "2018-11-20"} ]
Output (includeRowNumber = true, rowNumberColumnName = null):
[ {"Row": 1, "Name": "John", "Age": 30, "Salary": 55000.5, "Active": true, "HireDate": "2020-03-15"}, {"Row": 2, "Name": "Jane", "Age": 25, "Salary": 48000.0, "Active": true, "HireDate": "2021-07-01"}, {"Row": 3, "Name": "Bob", "Age": 40, "Salary": 72000.75, "Active": false, "HireDate": "2018-11-20"} ]
Output (includeRowNumber = true, rowNumberColumnName = "#"):
[ {"#": 1, "Name": "John", "Age": 30, "Salary": 55000.5, "Active": true, "HireDate": "2020-03-15"}, {"#": 2, "Name": "Jane", "Age": 25, "Salary": 48000.0, "Active": true, "HireDate": "2021-07-01"}, {"#": 3, "Name": "Bob", "Age": 40, "Salary": 72000.75, "Active": false, "HireDate": "2018-11-20"} ]
ToListOfLists List
Converts the ResultSet into a List of Lists. If includeHeader is true, the first inner list contains the column names.
- rs — The ResultSet to convert.
- includeHeader — If true, the first List contains column names.
Output (includeHeader = true):
[ ["Name", "Age", "Salary", "Active", "HireDate"], ["John", 30, 55000.5, true, "2020-03-15"], ["Jane", 25, 48000.0, true, "2021-07-01"], ["Bob", 40, 72000.75, false, "2018-11-20"] ]
Output (includeHeader = false):
[ ["John", 30, 55000.5, true, "2020-03-15"], ["Jane", 25, 48000.0, true, "2021-07-01"], ["Bob", 40, 72000.75, false, "2018-11-20"] ]
ToList List
Extracts values from the first column into a flat List. Expects a ResultSet with a single column.
- rs — The ResultSet to convert.
Expected input: SELECT Name FROM Employees
| Name (VARCHAR) |
|---|
| John |
| Jane |
| Bob |
Output:
["John", "Jane", "Bob"]
ToScalar
Returns a single value from the first column of the first row. Ideal for aggregate queries such as COUNT(*), MAX(), SUM(), etc. Returns null if the ResultSet is empty.
- rs — The ResultSet to read.
Example 1 — SELECT COUNT(*) FROM Employees
3
Example 2 — SELECT MAX(Age) FROM Employees
40
Example 3 — SELECT SUM(Salary) FROM Employees
175001.25
Example 4 — SELECT Name FROM Employees WHERE Age = 30
"John"
ToScalarString
Returns the first column of the first row as a String. Any column type is accepted: numeric, boolean, date, and string types are all converted via their toString representation. Dates are formatted as "yyyy-MM-dd", times as "HH:mm:ss", and timestamps as "yyyy-MM-dd'T'HH:mm:ss.SSSXXX". Returns null if the ResultSet is empty, the value is SQL NULL, or an error occurs.
- rs — The ResultSet to read.
Example — SELECT Name FROM Employees WHERE Age = 30
"John"
Example — SELECT Age FROM Employees WHERE Age = 30
"30"
ToScalarInt
Returns the first column of the first row as an int. Returns 0 if the ResultSet is empty, the value is SQL NULL, the column is not an integer type, or an error occurs.
Accepted column types: INTEGER, SMALLINT, TINYINT.
- rs — The ResultSet to read.
Example — SELECT Age FROM Employees WHERE Name = 'John'
30
Returns 0 if the column is not an integer type or the value is SQL NULL.
ToScalarLong
Returns the first column of the first row as a long. Returns 0 if the ResultSet is empty, the value is SQL NULL, the column is not a bigint type, or an error occurs.
Accepted column types: BIGINT.
- rs — The ResultSet to read.
Example — SELECT Id FROM Employees WHERE Name = 'John' (Id is BIGINT)
1001
Returns 0 if the column is not a bigint type or the value is SQL NULL.
ToScalarDouble
Returns the first column of the first row as a double. Returns 0.0 if the ResultSet is empty, the value is SQL NULL, the column is not a floating-point or decimal type, or an error occurs.
Accepted column types: DOUBLE, FLOAT, REAL, DECIMAL, NUMERIC.
- rs — The ResultSet to read.
Example — SELECT Salary FROM Employees WHERE Name = 'John'
55000.5
Returns 0.0 if the column is not a numeric type or the value is SQL NULL.
ToMap Map
Converts a single-row ResultSet into a Map with column names as keys. If more than one row exists, only the first row is used.
- rs — The ResultSet to convert.
Expected input: SELECT * FROM Employees WHERE Name = 'John'
| Name | Age | Salary | Active | HireDate |
|---|---|---|---|---|
| John | 30 | 55000.50 | true | 2020-03-15 |
Output:
{ "Name": "John", "Age": 30, "Salary": 55000.5, "Active": true, "HireDate": "2020-03-15" }
ToMapOfMaps Map
Converts the ResultSet into a Map of Maps. The first column's value is used as the key for each row. Column one should contain unique values.
- rs — The ResultSet to convert.
Output:
{ "John": { "Name": "John", "Age": 30, "Salary": 55000.5, "Active": true, "HireDate": "2020-03-15" }, "Jane": { "Name": "Jane", "Age": 25, "Salary": 48000.0, "Active": true, "HireDate": "2021-07-01" }, "Bob": { "Name": "Bob", "Age": 40, "Salary": 72000.75, "Active": false, "HireDate": "2018-11-20" } }
ToMapOfLists Map
Converts the ResultSet into a column-oriented Map. Each key is a column name, and each value is a List of all values in that column.
- rs — The ResultSet to convert.
Output:
{ "Name": ["John", "Jane", "Bob"], "Age": [30, 25, 40], "Salary": [55000.5, 48000.0, 72000.75], "Active": [true, true, false], "HireDate": ["2020-03-15", "2021-07-01", "2018-11-20"] }
ToMapOfRowNumberValuePair Map
Converts a single-column ResultSet into a Map with the row number (starting at 1) as the key and the column value as the value.
- rs — The ResultSet to convert.
Expected input: SELECT Name FROM Employees
| Name (VARCHAR) |
|---|
| John |
| Jane |
| Bob |
Output:
{ 1: "John", 2: "Jane", 3: "Bob" }
ToMapOfKeyValuePair Map
Converts a two-column ResultSet into a Map. The first column provides the keys and the second column provides the values.
- rs — The ResultSet to convert.
Expected input: SELECT Name, Age FROM Employees
| Name (VARCHAR) | Age (INTEGER) |
|---|---|
| John | 30 |
| Jane | 25 |
| Bob | 40 |
Output:
{ "John": 30, "Jane": 25, "Bob": 40 }
ToJSON String
Converts the ResultSet to a JSON array of objects, with column names as keys. If includeRowNumber is true, each object includes a "Row" field (1-based) as the first key.
- rs — The ResultSet to convert.
- includeRowNumber — If true, each object includes a "Row" field.
Output (includeRowNumber = false):
[ {"Name":"John","Age":30,"Salary":55000.5,"Active":true,"HireDate":"2020-03-15"}, {"Name":"Jane","Age":25,"Salary":48000.0,"Active":true,"HireDate":"2021-07-01"}, {"Name":"Bob","Age":40,"Salary":72000.75,"Active":false,"HireDate":"2018-11-20"} ]
Output (includeRowNumber = true):
[ {"Row":1,"Name":"John","Age":30,"Salary":55000.5,"Active":true,"HireDate":"2020-03-15"}, {"Row":2,"Name":"Jane","Age":25,"Salary":48000.0,"Active":true,"HireDate":"2021-07-01"}, {"Row":3,"Name":"Bob","Age":40,"Salary":72000.75,"Active":false,"HireDate":"2018-11-20"} ]
ToJSONObject String
Converts the first row of the ResultSet to a single JSON object with column names as keys. Returns {} if the ResultSet is empty. If more than one row exists, only the first is used.
- rs — The ResultSet to convert.
Expected input: SELECT * FROM Employees WHERE Name = 'John'
| Name | Age | Salary | Active | HireDate |
|---|---|---|---|---|
| John | 30 | 55000.50 | true | 2020-03-15 |
Output:
{"Name":"John","Age":30,"Salary":55000.5,"Active":true,"HireDate":"2020-03-15"}
ToJSONArray String
Converts the first column of the ResultSet to a flat JSON array. Expects a single-column ResultSet.
- rs — The ResultSet to convert.
Expected input: SELECT Name FROM Employees
| Name (VARCHAR) |
|---|
| John |
| Jane |
| Bob |
Output:
["John","Jane","Bob"]
ToTimeSeriesJSON String
Converts the ResultSet to an ECharts-compatible time-series JSON object. The time column must contain epoch millisecond values stored as a BIGINT. Each name in valueColumns produces one series in the output. Column lookup for both timeColumn and valueColumns is case-insensitive.
{"series":[]} if the ResultSet is invalid or timeColumn is not found. Missing value columns are silently treated as null for every row.- rs — The ResultSet to convert.
- timeColumn — Column name containing epoch-ms timestamps (BIGINT).
- valueColumns — Column names to expose as series (case-insensitive).
Expected input: SELECT Ts, CPU, Memory FROM ServerMetrics ORDER BY Ts
| Ts (BIGINT) | CPU (DOUBLE) | Memory (DOUBLE) |
|---|---|---|
| 1711450000000 | 23.4 | 61.2 |
| 1711450060000 | 41.7 | 63.8 |
| 1711450120000 | 35.1 | 62.5 |
Output — ToTimeSeriesJSON(rs, "Ts", Array("CPU", "Memory")):
{"series":[ {"name":"CPU","data":[ [1711450000000,23.4], [1711450060000,41.7], [1711450120000,35.1] ]}, {"name":"Memory","data":[ [1711450000000,61.2], [1711450060000,63.8], [1711450120000,62.5] ]} ]}
ToPagedJSON String
Converts the ResultSet to a paginated JSON object. All rows are read into memory first, then the requested page slice is returned. Pages are 1-based. If page is less than 1 it is clamped to 1; if pageSize is less than 1 it defaults to 100.
Respects SetLowerCaseFieldNames.
- rs — The ResultSet to convert.
- page — 1-based page number to return.
- pageSize — Number of rows per page.
Output — ToPagedJSON(rs, 1, 2) on the Employees table:
{ "page": 1, "pageSize": 2, "totalRows": 3, "data": [ {"Name":"John","Age":30,"Salary":55000.5,"Active":true,"HireDate":"2020-03-15"}, {"Name":"Jane","Age":25,"Salary":48000.0,"Active":true,"HireDate":"2021-07-01"} ] }
Page 2 of the same query — ToPagedJSON(rs, 2, 2):
{ "page": 2, "pageSize": 2, "totalRows": 3, "data": [ {"Name":"Bob","Age":40,"Salary":72000.75,"Active":false,"HireDate":"2018-11-20"} ] }
ToCSV String
Converts the ResultSet to a CSV string. Lines are separated by CRLF per RFC 4180. Values containing commas, double-quotes, or newlines are wrapped in double-quotes, with internal double-quotes escaped by doubling.
- rs — The ResultSet to convert.
- includeHeader — If true, the first line contains column names.
Output (includeHeader = true):
Name,Age,Salary,Active,HireDate John,30,55000.5,true,2020-03-15 Jane,25,48000.0,true,2021-07-01 Bob,40,72000.75,false,2018-11-20
Output (includeHeader = false):
John,30,55000.5,true,2020-03-15 Jane,25,48000.0,true,2021-07-01 Bob,40,72000.75,false,2018-11-20
ToHTMLTable String
Converts the ResultSet to an HTML table string with <thead> and <tbody> sections. Column names are used as header cells. All text content is HTML-escaped. Null values render as empty cells.
- rs — The ResultSet to convert.
- cssClass — Optional CSS class for the
<table>element. Passnullor""for no class.
Output (cssClass = "data-table"):
<table class="data-table">
<thead><tr><th>Name</th><th>Age</th><th>Salary</th><th>Active</th><th>HireDate</th></tr></thead>
<tbody>
<tr><td>John</td><td>30</td><td>55000.5</td><td>true</td><td>2020-03-15</td></tr>
<tr><td>Jane</td><td>25</td><td>48000.0</td><td>true</td><td>2021-07-01</td></tr>
<tr><td>Bob</td><td>40</td><td>72000.75</td><td>false</td><td>2018-11-20</td></tr>
</tbody>
</table>
Type Mapping Reference
The following table shows how JDBC types are mapped to Java types when reading values from a ResultSet:
| JDBC Type(s) | Java Type | Example Value |
|---|---|---|
| INTEGER, SMALLINT, TINYINT | int | 42 |
| BIGINT | long | 9223372036854775807 |
| FLOAT, REAL | float | 3.14 |
| DOUBLE | double | 3.141592653589793 |
| DECIMAL, NUMERIC | BigDecimal | 99999.99 |
| BOOLEAN, BIT | boolean | true |
| DATE | String | "2020-03-15" |
| TIME | String | "14:30:00" |
| TIMESTAMP | String | "2020-03-15T14:30:00.000+00:00" |
| All others | String | "text value" |
All recognized JDBC type names (returned by GetFieldTypes):