手写数据库客户端

controller

	@Autowired
    private IExecSqlService execSqlService;

    @Log(title = "执行sql", businessType = BusinessType.OTHER)
    @PostMapping("/exec")
    public Response<?> exec(@RequestBody ExecSqlVo execSqlVo){
        if (StringUtils.isBlank(execSqlVo.getSqlCommand())){
            throw new CustomException("待执行sql不能为空");
        }
        return okResponse(execSqlService.exec(execSqlVo.getSqlCommand()));
    }

service

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xxx.mapper.ExecSqlMapper;
import com.xxx.service.IExecSqlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ExecSqlServiceImpl implements IExecSqlService {
    @Autowired
    private ExecSqlMapper execSqlMapper;

    @Override
    public Object exec(String sql) {
        if (sql.startsWith("select") || sql.startsWith("SELECT")){
            return (JSONArray)JSON.toJSON(execSqlMapper.execQuery(sql));
        } else {
            List result = new ArrayList();
            Map<String, Object> map = new HashMap<>();
            map.put("update rows", execSqlMapper.execUpdate(sql));
            result.add(map);
            return result;
        }
    }
}

mapper

import org.apache.ibatis.annotations.Mapper;

import java.util.LinkedHashMap;
import java.util.List;

@Mapper
public interface ExecSqlMapper {

    List<LinkedHashMap<String, Object>> execQuery(String sql);

    int execUpdate(String sql);
}

mapper.xml

<mapper namespace="com.xxx.mapper.ExecSqlMapper">

	<select id="execQuery" parameterType="java.lang.String" resultType="java.util.LinkedHashMap">
		${sql}
	</select>

	<update id="execUpdate" parameterType="java.lang.String">
		${sql}
	</update>
</mapper>

vue

<template>
  <div class="app-container">
    <el-form class="searchBar" :model="queryParams" ref="queryForm" :inline="true">
      <el-input
        type="textarea"
        v-model="queryParams.sqlCommand"
        placeholder="请输入待执行sql"
        rows="13"
        clearable
        style="margin-top: 20px;margin-bottom: 20px;width:80%;"/>
      <el-button type="danger" @click="handleQuery" style="margin-left: 40px;margin-bottom: 20px;">执行sql</el-button>
    </el-form>
    <el-row>
      <el-col :span="4">执行结果:</el-col>
    </el-row><br/>
     <el-table border style="width: 100%" :data="resultTable" id="table">
        <!-- 动态列表渲染 -->
        <el-table-column
          width="150"
          :label="item.label"
          :prop="item.prop"
          v-for="(item, key) in result"
          :key="key"
        >
        </el-table-column>
      </el-table>
  </div>
</template>

<script>
import { execSql} from '@/api/system/exec-sql'

export default {
  name: 'ExeSqlMng',
  props: {
    // 是否有已修改
    reload: { type: Boolean, default: false },
    orgTypeOptions: { type: Array, default: () => [] }
  },
  data() {
    return {
      resultTable: [], //查看数据处理后的数据
      result: [], //查看数据用于循环的数据
      // 查询参数
      queryParams: {
      	sqlCommand: null
      },
      // 菜单ID
      menuId: this.$route.meta.menuId,
    }
  },
  methods: {
    /**点击当前行 */
    rowClick(row) {
      this.selectRow = row
    },
    /** 查询列表 */
    getList() {
      const loading = this.$loading(this.GLOBAL.Loading);
    	execSql(this.queryParams)
      .then(response => {
        loading.close();
        this.result = this.getCol(response.data);
        this.resultTable = this.getTable(response.data);
      })
      .catch((e) => {
        loading.close()
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      if(!this.queryParams.sqlCommand){
          this.$message({
            type: 'warn',
            message: `待执行sql为空`
          });
          return
      }
      this.getList()
    },
    getCol(src) {
      let col = [];
      for (let j in src[0]) {
        col.push({
            prop: j,
            label: j,
          });
      }
      return col;
    },
    getTable(src) {
      let table = [];
      for (let i = 0; i < src.length; i++) {
        let temp = {};
        for (let j in src[i]) {
          temp[j] = src[i][j];
        }
        table.push(temp);
      }
      return table;
    },
  }
}
</script>
<style scoped>
.el-form--inline .el-form-item {
    display: inline-block;
    margin-right: 10px;
    vertical-align: top;
    width: 1000px;
}
</style>
一、介绍 MyDB是我在2009年12月底开始动手写作的,是一个纯java写的数据库管理器,目前只是一个实现基本功能的演示性框架,用来验证功能的可实现性。 整个应用包括三个部分,数据库服务器,数据库客户端数据库驱动。目前这三部分已经都实现,但功能还不完整。 运行目录下的脚本,可以启动相应程序: 启动服务器: server.bat 相应命令:java -classpath ./lib/mydb.jar;./lib/antlr-3.2.jar;./lib/commons-beanutils.jar;./lib/commons-collections.jar;./lib/commons-digester.jar;./lib/commons-pool.jar;./lib/metouia.jar;./lib/QSAdminGUI.jar;./lib/QuickServer.jar lions.mydb.server.Server 启动客户端: client.bat 相应命令:java -classpath ./lib/mydb.jar;./lib/antlr-3.2.jar lions.mydb.client.Client 驱动: 使用方法: Class.forName("lions.mydb.jdbc.Driver"); Connection conn = DriverManager.getConnection( "jdbc:mydb://localhost:3305/test", "", ""); Statement stmt = conn.createStatement(); //ResultSet rs = stmt.executeQuery("select * from test"); 目前实现了以下几条基本指令: create database use drop database show databases create table drop table show tables select * from insert into () values() delete from 由于sql的完整规范比较复杂,要实现它需要日后不断地添加。目前感觉sql经常用到的也就几条,所以有想法对sql进行精减,只实现最常用的那几条, 同时增加一些方便日常操作的指令。 整个MyDB的开发时间都是我利用晚上22点到2点之间,以及周末的空余时间来进行的,因此进展缓慢,且效率不高。 计划在3年内将其实现完整,可以应用于实际生产环境。 MyDB采用的是纯java的技术实现,网络通讯部分,服务器使用了QuickServer框架,驱动使用的是常规的Socket技术,使用了antlr来解析sql语句, 数据库的业务处理部分是我自己写的,为了实现日后的功能,还需要做一定的细节调整。 二、版权声明 MyDB是本人在2009年底开始独立开发的应用,纯粹使用了自己投资的硬件,以及利用了自己的业余时间来进行开发的,本人拥有独立的全部的所有权, 除使用到的部分开源组件外,本人对MyDB保留所有权利,与其他公司无关,即使有功能相同的程序,也是本人独立实现的不同代码。其中使用到的组件 有:QuickServer, antlr。 任何人不得对MyDB进行反编译等逆向工程。 任何人不得将MyDB应用到未经允许的环境。 三、免责声明 MyDB目前功能还不完整,只提供用于研究,对于在应用中出现的任何问题,本人不承担任何责任。 2010年2月7日 瞿正峰 qq: 191506998 email: chinalions@sohu.com 上海
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值