亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java實(shí)現(xiàn)在線SQL編程最新完整版

 更新時(shí)間:2022年06月23日 11:10:57   作者:派大星i  
這篇文章主要介紹了Java實(shí)現(xiàn)在線SQL編程,在使用JDBC來進(jìn)行數(shù)據(jù)庫的操作,在使用時(shí)由于對其方法并不是全部了解,所以需要邊看源碼邊改善功能,感興趣的朋友跟隨小編一起看看吧

前言: 由于前段時(shí)間,項(xiàng)目組長分配的任務(wù)是要完成一個(gè)在線編寫SQL并要實(shí)現(xiàn)查詢功能的需求,最終需要將查詢到的數(shù)據(jù)以JSON格式顯示到響應(yīng)數(shù)據(jù)的區(qū)域,以供操作者進(jìn)行查看,一開始拿到需求時(shí)想著直接使用Mybatis進(jìn)行操作不就可以了,完全沒必要大費(fèi)周章,因?yàn)樵?code>MyBatis中有個(gè)拼接SQL的語法,可以使用${sql}來進(jìn)行執(zhí)行輸入的SQL語句,但是實(shí)際操作起來并不是想象中的那么簡單,因?yàn)槭褂?code>MyBatis會(huì)將數(shù)據(jù)源固定在本項(xiàng)目所使用的數(shù)據(jù)庫,而不可以進(jìn)行數(shù)據(jù)源之間的切換,無法進(jìn)行其他數(shù)據(jù)源中表的查詢操作 ?,所以在實(shí)現(xiàn)過程也是相當(dāng)艱難曲折...

?? 難度分析

在線執(zhí)行SQL語句的查詢主要的難點(diǎn)分為以下幾點(diǎn):其一則是對JDBC的部分的API理解的不夠透徹,導(dǎo)致在實(shí)現(xiàn)某些工鞥是并不是想象中的順利;其二在于對于查詢部分屬性的SQL語句該如何使用Java進(jìn)行實(shí)現(xiàn),是將輸入的字符串進(jìn)行分割再拼接還是使用直接整條語句的查詢操作;其三則是用戶可以動(dòng)態(tài)的切換數(shù)據(jù)源,并且對相應(yīng)數(shù)據(jù)源下的表進(jìn)行查詢操作,如果使用Mybatis進(jìn)行SQL的查詢操作則無法進(jìn)行數(shù)據(jù)源的切換,只能查詢所在微服務(wù)項(xiàng)目所連接的數(shù)據(jù)庫進(jìn)行查詢,否則無法進(jìn)行相應(yīng)的操作,即會(huì)出現(xiàn)該數(shù)據(jù)庫下并不存在所查詢的某張數(shù)據(jù)庫表的錯(cuò)誤信息 ?

?? 項(xiàng)目回顧(在線編寫SQL查詢)

?? 最終效果演示

?? 技術(shù)選型:

  • ?? SpringBoot
  • ?? MyBatis-Plus
  • ?? JDBC
  • ?? Vue
  • ?? 代碼編輯器monaco-editor

?? 需求分析

使用者在頁面可以選擇切換需要操作的數(shù)據(jù)源,并在編輯區(qū)域內(nèi)輸入SQL語句進(jìn)行查詢,查詢語句可以是全表查詢表中所有字段或者根據(jù)所需查詢指定某幾列字段對應(yīng)的值,點(diǎn)擊查詢之后即可在響應(yīng)數(shù)據(jù)之后以JSON的格式將查詢到的每一條數(shù)據(jù)封裝一個(gè)對象最后顯示到響應(yīng)數(shù)據(jù)區(qū)域以供操作者進(jìn)行觀看以達(dá)到可視化工具的效果。

?? 項(xiàng)目搭建

① 引入項(xiàng)目所需要的相關(guān)Maven依賴

<!--SpringBoot相關(guān)依賴-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>commons-lang</groupId>
  <artifactId>commons-lang</artifactId>
  <version>2.6</version>
</dependency>
<!--servlet-api相關(guān)依賴-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
  <scope>provided</scope>
</dependency>
<!--MySQL驅(qū)動(dòng)相關(guān)依賴-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.28</version>
</dependency>

② 編寫配置文件

server:
  port: 8080
spring:
  datasource:
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/data_source?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai

③ 創(chuàng)建Controller前端控制器

	@PostMapping("/dynamic-query")
	@ApiOperation(value = "動(dòng)態(tài)執(zhí)行SQL")
	public Result<?> dynamicQuery(@RequestBody DynamicQuery dynamicQuery){
		List<HashMap<Object,Object>> res = null;
		BladeVisualDb visualDb = bladeVisualDbService.getOne(new QueryWrapper<BladeVisualDb>().eq("id", dynamicQuery.getId()));
		List<HashMap<String,Object>> result = ConnectBySql.connAndExecSql(visualDb.getUrl(), visualDb.getDriverClass(), visualDb.getUsername(), visualDb.getPassword(),dynamicQuery.getSql());
		return Result.ok(result);
	}

④ 探究 JDBC中ResultSet中的方法

  • next()

解釋: 將光標(biāo)從其當(dāng)前位置向前移動(dòng)一行。 ResultSet 游標(biāo)最初位于第一行之前;第一次調(diào)用 next 方法使第一行成為當(dāng)前行;第二次調(diào)用使第二行成為當(dāng)前行,依此類推。實(shí)則對查詢到的數(shù)據(jù)進(jìn)行遍歷操作

  • getString(String columnLabel)

解釋: 根據(jù)表中對應(yīng)的列名稱來查詢到該列對應(yīng)到的數(shù)據(jù)

  • getMetaData()

解釋: 獲取某張表中列的數(shù)量、類型和列名稱

  • findColumn(String columnLabel)

解釋: 返回某個(gè)列的索引值即下標(biāo)

⑤ 獲取所有的數(shù)據(jù)源

因?yàn)槭褂谜呤强梢詣?dòng)態(tài)的選擇數(shù)據(jù)源從而來對表中的數(shù)據(jù)進(jìn)行相關(guān)操作,所以首先要查詢出可供連接的數(shù)據(jù)源

	 /**
	  * 下拉數(shù)據(jù)源列表
	  * @return
	  */
	@ApiOperation(value = "下拉列表")
	@GetMapping("/db-list")
	public Result<?> list(){
		List<BladeVisualDb> bladeVisualDbs = bladeVisualDbService.list();
		return Result.ok(bladeVisualDbs);
	}

⑥ 實(shí)現(xiàn)執(zhí)行查詢邏輯

首先執(zhí)行查詢有兩種方式:所有字段的全查詢即select * from xx 或者 查詢指定字段即select xx from xx

  • 所有字段的全查詢即select * from xx

在進(jìn)行所有字段的查詢時(shí),由于無法得知需要查詢的表中有什么字段,所以首先需要對輸入的SQL字符串進(jìn)行判斷是否是全字段查詢,然后即可獲取查詢表中的所有字段,然后再一一的進(jìn)行查詢出字段對應(yīng)的值即可,此操作也是需要對輸入SQL字符串進(jìn)行分割的,拿出所有插敘的表名即可。

ResultSet resultSet = stmt.executeQuery(sql);
//如果輸入的SQL屬于select * 操作
if (sql.contains("*")){
  List<String> list = new ArrayList<>();
  //獲取SQL中需要查詢的表的結(jié)構(gòu)
  ResultSetMetaData metaData = resultSet.getMetaData();
  int columnCount = metaData.getColumnCount();
  for (int i = 1; i <= columnCount; i++) {
    log.info("屬性列   ======>{}",metaData.getColumnName(i));
    //獲取表中的所有列
    list.add(metaData.getColumnName(i));
  }
  while (resultSet.next()){
    HashMap<String,Object> hashMap = new HashMap<>();
    for (String index : list) {
      //根據(jù)列名稱查詢出該列對應(yīng)的數(shù)據(jù)
      String rs = resultSet.getString(index);
      //將其放入列和值存放HashMap中
      hashMap.put(index,rs);
      //將多個(gè)HashMap合并成一個(gè)Map
      hashMap.putAll(hashMap);
    }
    res.add(hashMap);
  }
}
  • 查詢指定字段即select xx from xx

在使用JDBC進(jìn)行指定字段查詢時(shí)需要對輸入的SQL字符串進(jìn)行分割后將所需要查詢到的字段再使用JDBC中的getString(String columnName)進(jìn)行查詢字段對應(yīng)的值

    /**
     * 將SQL語句進(jìn)行拆分
     * @param sql
     * @return
     */
    @NotNull
    private static List<String> getString(String sql) {
        List<String> list = new ArrayList<>();
        String str = sql.substring(0, sql.indexOf("from"));
        String realSql = str.replace("select", "").trim();
        if (realSql.contains(",")){
            String[] split = realSql.split(",");
            for (String s : split) {
                list.add(s);
            }
        }else {
            list.add(realSql);
        }
        return list;
    }

隨后將分割完成的SQL存放到List集合中再進(jìn)行查詢操作

ResultSet resultSet = stmt.executeQuery(sql);
while (resultSet.next()){
  HashMap<String,Object> hashMap = new HashMap<>();
  List<String> str = getString(sql);
  for (String index : str) {
    String rs = resultSet.getString(index);
    hashMap.put(index,rs);
    hashMap.putAll(hashMap);
  }
  res.add(hashMap);
}

經(jīng)過對操作者輸入的SQL即可完成對表的查詢操作,由于所要實(shí)現(xiàn)的是可動(dòng)態(tài)切換數(shù)據(jù)源從而進(jìn)行相關(guān)的查詢操作,所以在此操作邏輯中首先需要連接數(shù)據(jù)庫,后再對輸入的SQL進(jìn)行分割查詢等操作。合并后的完整代碼:

    /**
     * 連接數(shù)據(jù)庫并根據(jù)輸入的SQL語句查詢數(shù)據(jù)
     * @param url
     * @param driverClass
     * @param username
     * @param password
     * @param sql
     * @return
     */
    public static List<HashMap<String,Object>> connAndExecSql(String url, String driverClass, String username, String password, String sql) {
        Boolean result = false;
        Connection conn = null;
        Statement stmt = null;
        List<HashMap<String,Object>> res = new ArrayList<>();

        try {
            Class.forName(driverClass);
            System.out.println("------------連接數(shù)據(jù)庫-----------");
            conn = DriverManager.getConnection(url,username,password);
            stmt = conn.createStatement();

            ResultSet resultSet = stmt.executeQuery(sql);
            //如果輸入的SQL屬于select * 操作
            if (sql.contains("*")){
                List<String> list = new ArrayList<>();
                //獲取SQL中需要查詢的表的結(jié)構(gòu)
                ResultSetMetaData metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    log.info("屬性列   ======>{}",metaData.getColumnName(i));
                    //獲取表中的所有列
                    list.add(metaData.getColumnName(i));
                }
                while (resultSet.next()){
                    HashMap<String,Object> hashMap = new HashMap<>();
                    for (String index : list) {
                        //根據(jù)列名稱查詢出該列對應(yīng)的數(shù)據(jù)
                        String rs = resultSet.getString(index);
                        //將其放入列和值存放HashMap中
                        hashMap.put(index,rs);
                        //將多個(gè)HashMap合并成一個(gè)Map
                        hashMap.putAll(hashMap);
                    }
                    res.add(hashMap);
                }
            }else {
                while (resultSet.next()){
                    HashMap<String,Object> hashMap = new HashMap<>();
                    List<String> str = getString(sql);
                    for (String index : str) {
                        String rs = resultSet.getString(index);
                        hashMap.put(index,rs);
                        hashMap.putAll(hashMap);
                    }
                    res.add(hashMap);
                }
            }
            //完成連接數(shù)據(jù)庫
            stmt.close();
            conn.close();
            System.out.println("查詢連接結(jié)束");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 將SQL語句進(jìn)行拆分
     * @param sql
     * @return
     */
    @NotNull
    private static List<String> getString(String sql) {
        List<String> list = new ArrayList<>();
        String str = sql.substring(0, sql.indexOf("from"));
        String realSql = str.replace("select", "").trim();
        if (realSql.contains(",")){
            String[] split = realSql.split(",");
            for (String s : split) {
                list.add(s);
            }
        }else {
            list.add(realSql);
        }
        return list;
    }

⑦ Vue前端引入monaco-editor組件進(jìn)行編寫SQL語句

?? 項(xiàng)目總結(jié)

在使用JDBC來進(jìn)行數(shù)據(jù)庫的操作,在使用時(shí)由于對其方法并不是全部了解,所以需要邊看源碼邊改善功能,因此遇到問題時(shí)才會(huì)感覺到腦中知識儲備的不足,目前只是實(shí)現(xiàn)了查詢操作,還未完善CRUD全部過程的操作。

到此這篇關(guān)于Java實(shí)現(xiàn)在線SQL編程的文章就介紹到這了,更多相關(guān)java SQL編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring通過c3p0配置bean連接數(shù)據(jù)庫

    Spring通過c3p0配置bean連接數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了Spring通過c3p0配置bean連接數(shù)據(jù)庫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • SpringCloud Feign隔離與降級詳細(xì)分析

    SpringCloud Feign隔離與降級詳細(xì)分析

    Feign是Netflix公司開發(fā)的一個(gè)聲明式的REST調(diào)用客戶端; Ribbon負(fù)載均衡、 Hystrⅸ服務(wù)熔斷是我們Spring Cloud中進(jìn)行微服務(wù)開發(fā)非?;A(chǔ)的組件,在使用的過程中我們也發(fā)現(xiàn)它們一般都是同時(shí)出現(xiàn)的,而且配置也都非常相似
    2022-11-11
  • Java FastJson使用教程

    Java FastJson使用教程

    這篇文章主要介紹了如何使用FastJson,幫助大家將 Java 對象轉(zhuǎn)換為 JSON 格式,感興趣的朋友可以了解下
    2020-10-10
  • springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過大問題

    springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過大問題

    這篇文章主要介紹了springcloud使用feign調(diào)用服務(wù)時(shí)參數(shù)內(nèi)容過大問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot整合xxl-job的實(shí)現(xiàn)示例

    springboot整合xxl-job的實(shí)現(xiàn)示例

    本文主要介紹了springboot整合xxl-job的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 解決Maven中的依賴導(dǎo)包問題(組合技巧)

    解決Maven中的依賴導(dǎo)包問題(組合技巧)

    自從我開始接觸了以spring為框架的項(xiàng)目學(xué)習(xí)后,這個(gè)maven導(dǎo)包老是出現(xiàn)問題,每次在這個(gè)上面花費(fèi)好多時(shí)間,于是乎打算寫一個(gè)秘籍出來,這篇文章主要介紹了解決Maven中的依賴導(dǎo)包問題,需要的朋友可以參考下
    2023-11-11
  • 深入理解Java 線程池

    深入理解Java 線程池

    這篇文章主要介紹了Java 線程池的相關(guān)資料,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 基于mybatis batch實(shí)現(xiàn)批量提交大量數(shù)據(jù)

    基于mybatis batch實(shí)現(xiàn)批量提交大量數(shù)據(jù)

    這篇文章主要介紹了基于mybatis batch實(shí)現(xiàn)批量提交大量數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • java父類和子類初始化順序的深入理解

    java父類和子類初始化順序的深入理解

    本篇文章是對java父類和子類初始化順序進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • spring boot如何添加攔截器

    spring boot如何添加攔截器

    本篇文章主要介紹了spring boot如何添加攔截器,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04

最新評論