Java-根据数据库自动创建ServerSocket Http服务器并且可以对数据库增删改查,动态编译数据表为JAVABean

其中使用到了com.alibaba.fastjson和JDBC
会生成数据库中所有表对应的接口,接口地址为ip:port/表名/(get/set/add/del)

需要jdk7或以上, 如果使用intellij编译报错, ctrl+shift+alt+s -> modules -> language level 设置为1.7以上

动态编辑工具 StringSrcCompiler

数据库都是本人自己学习使用的(非商用或公用)
查询数据

在这里插入图片描述
添加一条数据在这里插入图片描述

条件查询刚才插入的数据

在这里插入图片描述

改和删经测试暂时没发现问题,如果有错希望各位前辈指点
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());
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值