Câu trả lời này có thể không hiệu quả nhất, nhưng nó chắc chắn là động. Ghép nối JDBC gốc với thư viện Gson của Google, tôi có thể dễ dàng chuyển đổi từ kết quả SQL sang luồng JSON.
Tôi đã bao gồm trình chuyển đổi, tệp thuộc tính DB mẫu, tạo bảng SQL và tệp xây dựng Gradle (có sử dụng các phần phụ thuộc).
QueryApp.java
import java.io.PrintWriter;
import com.oracle.jdbc.ResultSetConverter;
public class QueryApp {
public static void main(String[] args) {
PrintWriter writer = new PrintWriter(System.out);
String dbProps = "/database.properties";
String indent = " ";
writer.println("Basic SELECT:");
ResultSetConverter.queryToJson(writer, dbProps, "SELECT * FROM Beatles", indent, false);
writer.println("\n\nIntermediate SELECT:");
ResultSetConverter.queryToJson(writer, dbProps, "SELECT first_name, last_name, getAge(date_of_birth) as age FROM Beatles", indent, true);
}
}
ResultSetConverter.java
package com.oracle.jdbc;
import java.io.*;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.*;
import com.google.common.reflect.TypeToken;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonWriter;
public class ResultSetConverter {
public static final Type RESULT_TYPE = new TypeToken<List<Map<String, Object>>>() {
private static final long serialVersionUID = -3467016635635320150L;
}.getType();
public static void queryToJson(Writer writer, String connectionProperties, String query, String indent, boolean closeWriter) {
Connection conn = null;
Statement stmt = null;
GsonBuilder gson = new GsonBuilder();
JsonWriter jsonWriter = new JsonWriter(writer);
if (indent != null) jsonWriter.setIndent(indent);
try {
Properties props = readConnectionInfo(connectionProperties);
Class.forName(props.getProperty("driver"));
conn = openConnection(props);
stmt = conn.createStatement();
gson.create().toJson(QueryHelper.select(stmt, query), RESULT_TYPE, jsonWriter);
if (closeWriter) jsonWriter.close();
stmt.close();
conn.close();
} catch (SQLException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
try {
if (stmt != null) stmt.close();
} catch (SQLException se2) {
}
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
try {
if (closeWriter && jsonWriter != null) jsonWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
private static Properties readConnectionInfo(String resource) throws IOException {
Properties properties = new Properties();
InputStream in = ResultSetConverter.class.getResourceAsStream(resource);
properties.load(in);
in.close();
return properties;
}
private static Connection openConnection(Properties connectionProperties) throws IOException, SQLException {
String database = connectionProperties.getProperty("database");
String username = connectionProperties.getProperty("username");
String password = connectionProperties.getProperty("password");
return DriverManager.getConnection(database, username, password);
}
}
QueryHelper.java
package com.oracle.jdbc;
import java.sql.*;
import java.text.*;
import java.util.*;
import com.google.common.base.CaseFormat;
public class QueryHelper {
static DateFormat DATE_FORMAT = new SimpleDateFormat("YYYY-MM-dd");
public static List<Map<String, Object>> select(Statement stmt, String query) throws SQLException {
ResultSet resultSet = stmt.executeQuery(query);
List<Map<String, Object>> records = mapRecords(resultSet);
resultSet.close();
return records;
}
public static List<Map<String, Object>> mapRecords(ResultSet resultSet) throws SQLException {
List<Map<String, Object>> records = new ArrayList<Map<String, Object>>();
ResultSetMetaData metaData = resultSet.getMetaData();
while (resultSet.next()) {
records.add(mapRecord(resultSet, metaData));
}
return records;
}
public static Map<String, Object> mapRecord(ResultSet resultSet, ResultSetMetaData metaData) throws SQLException {
Map<String, Object> record = new HashMap<String, Object>();
for (int c = 1; c <= metaData.getColumnCount(); c++) {
String columnType = metaData.getColumnTypeName(c);
String columnName = formatPropertyName(metaData.getColumnName(c));
Object value = resultSet.getObject(c);
if (columnType.equals("DATE")) {
value = DATE_FORMAT.format(value);
}
record.put(columnName, value);
}
return record;
}
private static String formatPropertyName(String property) {
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, property);
}
}
database.properties
driver=com.mysql.jdbc.Driver
database=jdbc:mysql://localhost/JDBC_Tutorial
username=root
password=
JDBC_Tutorial.sql
-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: Jan 12, 2016 at 07:40 PM
-- Server version: 10.1.8-MariaDB
-- PHP Version: 5.6.14
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `jdbc_tutorial`
--
CREATE DATABASE IF NOT EXISTS `jdbc_tutorial` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `jdbc_tutorial`;
DELIMITER $$
--
-- Functions
--
DROP FUNCTION IF EXISTS `getAge`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `getAge` (`in_dob` DATE) RETURNS INT(11) NO SQL
BEGIN
DECLARE l_age INT;
IF DATE_FORMAT(NOW(),'00-%m-%d') >= DATE_FORMAT(in_dob,'00-%m-%d') THEN
-- This person has had a birthday this year
SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y');
ELSE
-- Yet to have a birthday this year
SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y')-1;
END IF;
RETURN(l_age);
END$$
DELIMITER ;
-- --------------------------------------------------------
--
-- Table structure for table `beatles`
--
DROP TABLE IF EXISTS `beatles`;
CREATE TABLE IF NOT EXISTS `beatles` (
`id` int(11) NOT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`date_of_birth` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Truncate table before insert `beatles`
--
TRUNCATE TABLE `beatles`;
--
-- Dumping data for table `beatles`
--
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(100, 'John', 'Lennon', '1940-10-09');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(101, 'Paul', 'McCartney', '1942-06-18');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(102, 'George', 'Harrison', '1943-02-25');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(103, 'Ringo', 'Starr', '1940-07-07');
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
mainClassName = 'com.oracle.jdbc.QueryApp'
repositories {
maven {
url "http://repo1.maven.org/maven2"
}
}
jar {
baseName = 'jdbc-tutorial'
version = '1.0.0'
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
compile 'mysql:mysql-connector-java:5.1.16'
compile 'com.google.guava:guava:18.0'
compile 'com.google.code.gson:gson:1.7.2'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.9'
}
Các kết quả
CHỌN cơ bản
[
{
"firstName": "John",
"lastName": "Lennon",
"dateOfBirth": "1940-10-09",
"id": 100
},
{
"firstName": "Paul",
"lastName": "McCartney",
"dateOfBirth": "1942-06-18",
"id": 101
},
{
"firstName": "George",
"lastName": "Harrison",
"dateOfBirth": "1943-02-25",
"id": 102
},
{
"firstName": "Ringo",
"lastName": "Starr",
"dateOfBirth": "1940-07-07",
"id": 103
}
]
SELECT trung gian
[
{
"firstName": "John",
"lastName": "Lennon",
"age": 75
},
{
"firstName": "Paul",
"lastName": "McCartney",
"age": 73
},
{
"firstName": "George",
"lastName": "Harrison",
"age": 72
},
{
"firstName": "Ringo",
"lastName": "Starr",
"age": 75
}
]