最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mysql如何按首字母進(jìn)行檢索數(shù)據(jù)

 更新時間:2024年11月28日 14:25:26   作者:農(nóng)碼天下  
這篇文章介紹了如何根據(jù)學(xué)生的首字母檢索學(xué)生信息的需求,并提供了一種不增加表字段的實現(xiàn)方法,通過利用漢字的拼音排序特性,結(jié)合數(shù)據(jù)庫的排序和轉(zhuǎn)換函數(shù),實現(xiàn)了根據(jù)首字母模糊匹配檢索學(xué)生信息的功能

一、介紹

最近有個這樣的需求,一張有大量數(shù)據(jù)元素的表,這里就暫且舉例為 student 表,現(xiàn)在要按照學(xué)生的首字母來進(jìn)行檢索學(xué)生信息。

比如用戶輸入“ZS”,獲得的學(xué)生列表的姓名第一個字拼音以“Z”開頭,第二個字以“S”開頭。

我想這個應(yīng)該大家都明白什么需求,對于這個需求我之前項目中沒有遇到過,至于有沒有一些搜索系統(tǒng)或者第三方解決這個問題,我不太清楚,下面是我就這個需求進(jìn)行的實現(xiàn),也為以后自己遇到類似需求做參考。

二、分析

以首字母來查詢有兩種情況:

1、可以增加表字段,即將student表中添加一個firstwords字段來記錄學(xué)生名的首字母,這樣就可以直接拿此字段進(jìn)行模糊匹配檢索(name:“張三”,firstwords:"ZS")。

2、不能增加表字段,工作中很多表或者數(shù)據(jù)庫都是客戶的或者是長時間不動的表,基本不建議修改的情況,無法增加首字母的相關(guān)字段,此時就需要用代碼來實現(xiàn)此需求。

這里只介紹第二種情況的實現(xiàn),第一種情況太簡單就不說了。

三、實現(xiàn)

剛開始我看需求時,我上網(wǎng)各種查詢,發(fā)現(xiàn)很多方法都不能用或者說我用不好吧,不過通過閱讀網(wǎng)上各種方法,我自己總結(jié)了一個搜索方式,測試過沒發(fā)現(xiàn)什么問題。

我們知道數(shù)據(jù)庫查詢時可以排序查詢,比如ASC關(guān)鍵字排序,那么漢子是通過什么排序呢,最后通過網(wǎng)上查閱資料,如果存儲漢字的字段編碼使用的是GBK字符集的話,其采用的是拼音排序的方法,UTF-8的字符集目前我沒去研究,雖然mysql存儲數(shù)據(jù)基本都是utf-8,但可以在查詢的時候轉(zhuǎn)為GBK,一樣可以查詢,下面是A—Z的字符集對應(yīng)漢子的范圍

 static {
        wordsMap = new HashMap<>();
        wordsMap.put("a","45217,45252");wordsMap.put("b","45253,45760");wordsMap.put("c","45761,46317");
        wordsMap.put("d","46318,46825");wordsMap.put("e","46826,47009");wordsMap.put("f","47010,47296");
        wordsMap.put("g","47297,47613");wordsMap.put("h","47614,48118");wordsMap.put("j","48119,49061");
        wordsMap.put("k","49062,49323");wordsMap.put("l","49324,49895");wordsMap.put("m","49896,50370");
        wordsMap.put("n","50371,50613");wordsMap.put("o","50614,50621");wordsMap.put("p","50622,50905");
        wordsMap.put("q","50906,51386");wordsMap.put("r","51387,51445");wordsMap.put("s","51446,52217");
        wordsMap.put("t","52218,52697");wordsMap.put("w","52698,52979");wordsMap.put("x","52980,53640");
        wordsMap.put("y","53689,54480");wordsMap.put("z","54481,55289");
    }

這是段代碼,代碼意思為每個首字母對應(yīng)漢子的包含范圍,比如:首字母為“a”的漢子ASC編碼范圍都在45217和45252之間,有了這個信息基本上也就可以完成該需求了,下面是需求實現(xiàn)的代碼

FisrtWordsSqlUtils 這個Utils類是用來存儲漢子范圍和拼接sql語句用的

package com.oracle;

import java.util.HashMap;
import java.util.Map;

/**
 * @author WYH
 */
public class FisrtWordsSqlUtils {
    
    //依次從小到大排序
    private static Map<String,String> wordsMap;

    static {
        wordsMap = new HashMap<>();
        wordsMap.put("a","45217,45252");wordsMap.put("b","45253,45760");wordsMap.put("c","45761,46317");
        wordsMap.put("d","46318,46825");wordsMap.put("e","46826,47009");wordsMap.put("f","47010,47296");
        wordsMap.put("g","47297,47613");wordsMap.put("h","47614,48118");wordsMap.put("j","48119,49061");
        wordsMap.put("k","49062,49323");wordsMap.put("l","49324,49895");wordsMap.put("m","49896,50370");
        wordsMap.put("n","50371,50613");wordsMap.put("o","50614,50621");wordsMap.put("p","50622,50905");
        wordsMap.put("q","50906,51386");wordsMap.put("r","51387,51445");wordsMap.put("s","51446,52217");
        wordsMap.put("t","52218,52697");wordsMap.put("w","52698,52979");wordsMap.put("x","52980,53640");
        wordsMap.put("y","53689,54480");wordsMap.put("z","54481,55289");
    }
    /**
     * 拼接sql
     * @param str
     */
    public static String getSql(String str){
        String wordsStr = str.toLowerCase();
        //排除該三個首字母,因為中文就沒有以他們開頭的拼音
        if(str.contains("i")||str.contains("u")||str.contains("v")){
            System.out.println("暫無數(shù)據(jù)");
            return null;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < wordsStr.length(); i++) {
            String c = wordsStr.charAt(i)+"";
            String wordsASC  = wordsMap.get(c);
            String[] asc = wordsASC.split(",");
            int ASC01 = Integer.parseInt(asc[0]);
            int ASC02 = Integer.parseInt(asc[1]);
            if(i!=wordsStr.length()-1){
                sb.append("CONV(HEX(SUBSTRING(CONVERT(name USING gbk ), "+(i+1)+",1)), 16, 10) BETWEEN "+ASC01+" AND "+ASC02 + " and ");
            }else{
                sb.append("CONV(HEX(SUBSTRING(CONVERT(name USING gbk ), "+(i+1)+",1)), 16, 10) BETWEEN "+ASC01+" AND "+ASC02);
            }
        }
        return sb.toString();
    }
}

sql拼接代碼中:“CONV,HEX,SUBSTRING,CONVERT”這幾個是數(shù)據(jù)庫的一些函數(shù),整體意思先轉(zhuǎn)GBK編碼,然后截取某個位置字母,然后轉(zhuǎn)16進(jìn)制的字符集,然后再由16進(jìn)制轉(zhuǎn)10進(jìn)制,最終得到的就是像那個hashmap集合里面的那一串?dāng)?shù)字。后面的between and 語句就不解釋了,這個不知道估計這篇文章也不會看的太不懂。

上面的sql語句已經(jīng)可以得到,下面是mysql數(shù)據(jù)庫原生連接的方法

/**
 * @author WYH
 */
public class MySqlConnectUtil {

    public static Map<String,Object> getResultMap(String dbUser, String dbPwd, String orclUrl, String tableName,String mySql){
        Map<String,Object> resultMap = new HashMap<>();
        Connection con=null;
        PreparedStatement pre=null;
        ResultSet resultSet=null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            con= DriverManager.getConnection(orclUrl,dbUser,dbPwd);
            String sql="select * from "+tableName +" where " + mySql;
            System.out.println(sql);
            pre=con.prepareStatement(sql);
            resultSet=pre.executeQuery();
            resultMap = getResultMap(resultSet);
        }catch(Exception ex){
            ex.printStackTrace();
            System.out.println("未能返回結(jié)果");
        }finally{
            JdbcUtil.release(con,pre,resultSet);
        }
        return resultMap;
    }

    private static Map<String,Object> getResultMap(ResultSet resultSet) throws SQLException {
        Map<String,Object> reusltMap = new HashMap<>();
        List<Map> maps = new ArrayList<>();
        ResultSetMetaData rsmd = resultSet.getMetaData();
        while(resultSet.next()){
            int columnCount = rsmd.getColumnCount();
            Map map = new HashMap();
            for (int i = 1; i <= columnCount; i++) {
                Object object = resultSet.getObject(i);
                String columnName = rsmd.getColumnName(i);
                String columnTypeName = rsmd.getColumnTypeName(i).toLowerCase();
                if(columnTypeName.equals("date")&&columnTypeName.equals("time")&&columnTypeName.equals("timestamp")){
                    Date date = (Date) object;
                    long time = date.getTime();
                    map.put(columnName,time+"");
                }else {
                    map.put(columnName, object);
                }
            }
            maps.add(map);
        }
        reusltMap.put("data",maps);
        return reusltMap;
    }
}

這個是連接數(shù)據(jù)庫的工具類,手寫的原生的,如果項目中使用第三方的如mybatis等可以不用,這里我寫這個也是為了測試使用,邏輯上看的更清晰一點。

下面是最終測試的方法

/**
 * @author WYH
 */
public class TestFirstWordsSearcher {
    public static void main(String[] args) {
        String userName = "root";
        String password = "root";
        String oracleUrl = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=utf-8";
        String tableName = "student";
        try {
            String sql = FisrtWordsSqlUtils.getSql("LS");
            Map<String, Object> reusltMap =MySqlConnectUtil.getResultMap(userName,password,oracleUrl,tableName,sql);
            String s = JSON.toJSONString(reusltMap);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

測試結(jié)果截圖如下:

文章核心點就是每個首字母對應(yīng)的ASC編碼的范圍,利用此范圍進(jìn)行拼接sql,然后查詢數(shù)據(jù)

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mysql8.0?lower_case_table_names?大小寫敏感設(shè)置問題解決

    mysql8.0?lower_case_table_names?大小寫敏感設(shè)置問題解決

    在默認(rèn)情況下,這個變量是設(shè)置為0的,以保持向前兼容性,如果將該變量設(shè)置為1,則表名和數(shù)據(jù)庫名將被區(qū)分大小寫,本文主要介紹了mysql8.0?lower_case_table_names?大小寫敏感設(shè)置問題解決,感興趣的可以了解一下
    2023-09-09
  • MySQL安裝報錯找不到MSVCR120.dll文件丟失的解決方案

    MySQL安裝報錯找不到MSVCR120.dll文件丟失的解決方案

    文章介紹了解決MSVCR120.dll丟失問題的幾種方法,包括重新安裝Microsoft Visual C++ Redistributable、手動下載DLL文件、運行系統(tǒng)文件檢查工具、檢查系統(tǒng)更新以及卸載并重新安裝相關(guān)軟件
    2024-12-12
  • Mybatis中的動態(tài)SQL語句解析

    Mybatis中的動態(tài)SQL語句解析

    這篇文章主要介紹了Mybatis中的動態(tài)SQL語句解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • MySQL kill指令使用指南

    MySQL kill指令使用指南

    這篇文章主要介紹了MySQL kill指令的使用方法,幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下
    2020-12-12
  • mysql超大分頁優(yōu)化的實現(xiàn)

    mysql超大分頁優(yōu)化的實現(xiàn)

    本文介紹了MySQL中處理超大分頁查詢的優(yōu)化方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • Mysql元數(shù)據(jù)如何生成Hive建表語句注釋腳本詳解

    Mysql元數(shù)據(jù)如何生成Hive建表語句注釋腳本詳解

    這篇文章主要給大家介紹了關(guān)于Mysql元數(shù)據(jù)如何生成Hive建表語句注釋腳本的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • MySQL BETWEEN AND踩坑記錄

    MySQL BETWEEN AND踩坑記錄

    這篇文章主要介紹了MySQL BETWEEN AND踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MySql中刪除數(shù)據(jù)表的方法詳解

    MySql中刪除數(shù)據(jù)表的方法詳解

    這篇文章主要介紹了MySql中刪除數(shù)據(jù)表的方法的相關(guān)資料,作者講解的十分細(xì)致全面,這里推薦給大家,需要的朋友可以參考下
    2022-08-08
  • 在Windows環(huán)境下使用MySQL:實現(xiàn)自動定時備份

    在Windows環(huán)境下使用MySQL:實現(xiàn)自動定時備份

    下面小編就為大家分享一篇在Windows環(huán)境下使用MySQL:實現(xiàn)自動定時備份的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • MySQL常用慢查詢分析工具詳解

    MySQL常用慢查詢分析工具詳解

    這篇文章主要介紹了MySQL常用慢查詢分析工具詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08

最新評論

潜山县| 沾益县| 图木舒克市| 茂名市| 茌平县| 安丘市| 库车县| 额尔古纳市| 定州市| 安图县| 宿迁市| 商洛市| 百色市| 上林县| 惠东县| 慈溪市| 凤台县| 大丰市| 朝阳市| 和田县| 江孜县| 洪江市| 儋州市| 深圳市| 婺源县| 怀宁县| 张掖市| 临沂市| 永吉县| 柯坪县| 方正县| 旬邑县| 屏南县| 定边县| 福海县| 孝感市| 唐山市| 通许县| 都兰县| 东丰县| 绥棱县|