其中使用到了com.alibaba.fastjson和JDBC
会生成数据库中所有表对应的接口,接口地址为ip:port/表名/(get/set/add/del)
需要jdk7或以上, 如果使用intellij编译报错, ctrl+shift+alt+s -> modules -> language level 设置为1.7以上
数据库都是本人自己学习使用的(非商用或公用)
查询数据
添加一条数据
条件查询刚才插入的数据
改和删经测试暂时没发现问题,如果有错希望各位前辈指点
Connection conn = JDBCUtil.getConn();
//只需要把JDBC的Connection和服务器端口号给服务器对象就好了
//会生成数据库中所有表接口,接口地址为ip:port/tableName/(get/set/add/del)</p>
DataBaseManagerHttpServer dataBaseManagerHttpServer = new
DataBaseManagerHttpServer(conn, 20600);
dataBaseManagerHttpServer.startServer();
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DataBaseManagerHttpServer {
//用来储存数据库中所有表名
private ArrayList<String> beanClassNames;
//todo MSSql的字段类型名称转换(比如varchar转String),动态编译需要。 如果只是简单的学习小例子的话是不需要动态编译的,但是这是为了让服务器之后支持MVC框架
private HashMap<String, String> field_mssql;
{
field_mssql = new HashMap<>();
field_mssql.put("int", "int");
field_mssql.put("tinyint", "short");
field_mssql.put("bit", "short");
field_mssql.put("bigint", "long");
field_mssql.put("varchar", "String");
}
private Connection conn;
private int port;
public DataBaseManagerHttpServer(Connection conn, int port) {
this.conn = conn;
this.port = port;
generateTableClass();
}
public void startServer() {
ServerSocket serverSocket = null;
ExecutorService executorService = null;
try {
serverSocket = new ServerSocket(port);
executorService = Executors.newFixedThreadPool(3);
while (true) {
Socket socket = serverSocket.accept();
executorService.submit(handleSocket(socket));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (executorService != null) executorService.shutdown();
if (conn != null && !conn.isClosed()) conn.close();
if (serverSocket != null)
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void generateTableClass() {
/**
* <p>生成数据库中所有表接口,接口地址为ip:port/tableName/(get/set/add/del)</p>
*
* @param conn 需要生成接口的数据库连接
*/
Statement statement = null;
ResultSet resultSet = null;
try {
statement = conn.createStatement();
DatabaseMetaData metaData = conn.getMetaData();
//获取所有表名
resultSet = metaData.getTables(null, "root", null, new String[]{"TABLE"});
while (resultSet.next()) {
String tableNamePattern = resultSet.getString(3);
//动态编译String类型的Class
StringBuilder sb = new StringBuilder();
sb.append("public class " + tableNamePattern + "{");
beanClassNames.add(tableNamePattern);
ResultSet columns = metaData.getColumns(null, null, tableNamePattern, "%");
while (columns.next()) {
String fieldType = field_mssql.get(columns.getString("TYPE_NAME").split(" ")[0]);
String filedName = columns.getString("COLUMN_NAME");
sb.append("private " + fieldType + " " + filedName + "; ");
//字段首字母改大写
char[] fileNameCharArray = filedName.toCharArray();
if (fileNameCharArray[0] > 'a' && fileNameCharArray[0] < 'z')
fileNameCharArray[0] = (char) (fileNameCharArray[0] - 32);
sb.append("public " + fieldType + " get" + new String(fileNameCharArray) + "(){return this." + filedName + ";} ");
sb.append("public void set" + new String(fileNameCharArray) + "(" + fieldType + " " + filedName + "){this." + filedName + "=" + filedName + ";} ");
}
sb.append("}");
StringSrcCompiler.compile(sb.toString());
columns.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (statement != null) statement.close();
if (resultSet != null) resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
private Runnable handleSocket(Socket socket) {
/**
* <p>处理请求逻辑</p>
*/
return () -> {
OutputStream outputStream = null;
try {
outputStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len = socket.getInputStream().read(buffer);
if (len == -1) return;
outputStream.write("HTTP/1.1 200 OK\r\nContent-Type: text/json;charset=utf-8\r\n\r\n".getBytes());
RequestParser requestParser = new RequestParser(new String(buffer, 0, len));
System.out.println("CreateDataBaseTableBean\t-\thandleSocket:\t\t" + socket.getInetAddress().getHostAddress()+requestParser.getPath());
String[] pathSplit = requestParser.getPath().split("/");
String tableName = pathSplit[1];
String requestType = pathSplit[2];
switch (requestType) {
case "get":
get(tableName, requestParser.getBody().getJSONObject("where"), outputStream);
break;
case "set":
set(tableName, requestParser.getBody().getJSONObject("where"), requestParser.getBody().getJSONObject("param"), outputStream);
break;
case "add":
add(tableName, requestParser.getBody().getJSONObject("param"), outputStream);
break;
case "del":
del(tableName, requestParser.getBody().getJSONObject("where"), outputStream);
break;
}
} catch (Exception e) {
try {
outputStream.write(("{\"code\":400,\"message\":\"" + e.getMessage() + "\",\"data\":[]}").getBytes());
} catch (IOException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (outputStream != null) outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
private void get(String tableName, JSONObject where, OutputStream socketOutputStream) throws SQLException, IOException {
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from " + tableName + whereParamComPose(where, "where"));
Class tableCls = StringSrcCompiler.getCls(tableName);
Field[] declaredFields = tableCls.getDeclaredFields();
socketOutputStream.write("{\"code\":200,\"message\":\"success\",\"data\":[".getBytes());
if (resultSet.next())
while (true) {
socketOutputStream.write("{".getBytes());
for (int i = 0; i < declaredFields.length; i++) {
String name = declaredFields[i].getName();
socketOutputStream.write(("\"" + name + "\":\"" + resultSet.getString(name) + "\"").getBytes());
if (i != declaredFields.length - 1) socketOutputStream.write(",".getBytes());
}
socketOutputStream.write("}".getBytes());
if (resultSet.next()) socketOutputStream.write(",".getBytes());
else break;
}
socketOutputStream.write("]".getBytes());
statement.close();
}
private void set(String tableName, JSONObject where, JSONObject params, OutputStream socketOutputStream) throws SQLException, IOException {
Statement statement = conn.createStatement();
int i = statement.executeUpdate("update " + tableName + whereParamComPose(params, "set") + whereParamComPose(where, "where"));
statement.close();
boolean b = i > 0;
responseMessage(socketOutputStream, "{\"effectNum\":" + i + "}", b ? "success" : "fault", b ? 200 : 400);
}
private void add(String tableName, JSONObject params, OutputStream socketOutputStream) throws SQLException, IOException {
Statement statement = conn.createStatement();
String keyStr = params.keySet().toString();
int i = statement.executeUpdate("insert into " + tableName + " (" + keyStr.substring(1, keyStr.length() - 1) + ") values('" + StringUtil.join(params.values(), "','") + "')");
statement.close();
boolean b = i > 0;
responseMessage(socketOutputStream, "{\"effectNum\":" + i + "}", b ? "success" : "fault", b ? 200 : 400);
}
private void del(String tableName, JSONObject where, OutputStream socketOutputStream) throws SQLException, IOException {
Statement statement = conn.createStatement();
int i = statement.executeUpdate("delete " + tableName + whereParamComPose(where, "where"));
statement.close();
boolean b = i > 0;
responseMessage(socketOutputStream, "{\"effectNum\":" + i + "}", b ? "success" : "fault", b ? 200 : 400);
}
private void responseMessage(OutputStream outputStream, String data, String message, int code) throws IOException {
outputStream.write(("{\"code\":" + code + ",\"message\":\"" + message + "\",\"data\":" + data + "}").getBytes());
}
private String whereParamComPose(JSONObject js, String type) {
/**
* <p>讲json转换为: key1=val1 and key2=val2... 的String格式</p>
*
* @param js
*/
if (js == null || js.keySet().size() < 1) return "";
Set<String> keySet = js.keySet();
StringBuilder sb = new StringBuilder(" " + type + " ");
for (String s : keySet)
sb.append(s + "=" + js.getString(s) + " and ");
return sb.substring(0, sb.length() - 5);
}
private static class RequestParser {
private String path;
private JSONObject body;
public RequestParser(String request) {
/**
* <p>解析http请求, 切割除了其中的请求路径和请求体</p>
*/
String[] requestSplit = request.split("\r\n\r\n");
path = requestSplit[0].split("\r\n")[0].split(" ")[1];
if (requestSplit.length > 1) body = JSONObject.parseObject(requestSplit[1]);
else body = new JSONObject();
}
public String getPath() {
return path;
}
public JSONObject getBody() {
return body;
}
}
private static class StringUtil {
/**
* <p>因为原生StringUtil的join遇到集合中的int类型会报错,所以自己封装了一个工具</p>
*
* @param c 需要切割的集合
* @param split 切割符
* @return
*/
public static String join(Collection c, String split) {
Iterator iterator = c.iterator();
StringBuilder sb = new StringBuilder();
while (iterator.hasNext()) {
sb.append(iterator.next() + split);
}
if (sb.length() < 1) return "";
return sb.substring(0, sb.length() - split.length());
}
}
}