一、介绍

最近有个这样的需求,一张有大量数据元素的表,这里就暂且举例为 student 表,现在要按照学生的首字母来进行检索学生信息。比如用户输入“ZS”,获得的学生列表的姓名第一个字拼音以“Z”开头,第二个字以“S”开头。我想这个应该大家都明白什么需求,对于这个需求我之前项目中没有遇到过,至于有没有一些搜索系统或者第三方解决这个问题,我不太清楚,下面是我就这个需求进行的实现,也为以后自己遇到类似需求做参考。

二、分析

以首字母来查询有两种情况,1、可以增加表字段,即将student表中添加一个firstwords字段来记录学生名的首字母,这样就可以直接拿此字段进行模糊匹配检索(name:“张三”,firstwords:"ZS")。2、不能增加表字段,工作中很多表或者数据库都是客户的或者是长时间不动的表,基本不建议修改的情况,无法增加首字母的相关字段,此时就需要用代码来实现此需求。这里只介绍第二种情况的实现,第一种情况太简单就不说了。

三、实现

刚开始我看需求时,我上网各种查询,发现很多方法都不能用或者说我用不好吧,不过通过阅读网上各种方法,我自己总结了一个搜索方式,测试过没发现什么问题。

我们知道数据库查询时可以排序查询,比如ASC关键字排序,那么汉子是通过什么排序呢,最后通过网上查阅资料,如果存储汉字的字段编码使用的是GBK字符集的话,其采用的是拼音排序的方法,UTF-8的字符集目前我没去研究,虽然mysql存储数据基本都是utf-8,但可以在查询的时候转为GBK,一样可以查询,下面是A—Z的字符集对应汉子的范围

 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");}

这是段代码,代码意思为每个首字母对应汉子的包含范围,比如:首字母为“a”的汉子ASC编码范围都在45217和45252之间,有了这个信息基本上也就可以完成该需求了,下面是需求实现的代码

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("暂无数据");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”这几个是数据库的一些函数,整体意思先转GBK编码,然后截取某个位置字母,然后转16进制的字符集,然后再由16进制转10进制,最终得到的就是像那个hashmap集合里面的那一串数字。后面的between  and 语句就不解释了,这个不知道估计这篇文章也不会看的太不懂。

上面的sql语句已经可以得到,下面是mysql数据库原生连接的方法

/*** @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("未能返回结果");}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;}
}

这个是连接数据库的工具类,手写的原生的,如果项目中使用第三方的如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();}}
}

测试结果截图如下:

文章核心点就是每个首字母对应的ASC编码的范围,利用此范围进行拼接sql,然后查询数据

mysql 按首字母进行检索数据相关推荐

  1. springboot返回按照首字母分组排序数据

    最终需要实现的效果图如下: 一.实现思路 1.将数据list 进行排序Collections,排序后是按照汉字字母排序的. 2.循环找出26个字母,以字母为key,以list中相同首字母的数据为值(集 ...

  2. 【如何通过汉字首字母拼写查询数据】mysql数据库汉字首字母获取查询或通过ES插件elasticsearch-analysis-pinyin进行汉字首拼查询

    一.mysql数据库汉字首字母获取查询 1.汉字提取首字母 get_first_pinyin_char: 此函数是将一个中文字符串的第一个汉字转成拼音字母 (例如:"李"-> ...

  3. SQL 100+个最佳入门案例实践(覆盖Oralce、SQL Server、Mysql)之基础操作_1_检索数据

    SQL基础操作_1_检索数据 目录 7.1.1 数据集 7.1.2 学生选课关系表 7.1.3 供应商关系表 7.2.1 从表中查询所有行和列 7.2.2 从表中查询部分行 7.2.3 查询满足某个条 ...

  4. mysql 拼音首字母_Mysql:拼音首字母查询(超高性能)

    注:不用新建表,查询性能高,可以兼容中英文 简单分析 应用场景:通常对地址或者数量较多的分类会选择首字母查询的方法 性能考虑:PHP中进行首字母查询,网上可以找到很多脚本实现,但需要将所有数据进行读出 ...

  5. mysql 升序_MySQL之排序检索数据

    获取数据: 深大享:MySQL之数据准备​zhuanlan.zhihu.com 排序检索数据: 如何使用SELECT语句的ORDER BY子句,根据需要排序检索出的数据. 1.未排序检索数据 -- 未 ...

  6. mysql中首字母大写的函数,如何借助MySQL函数将字符串的首字母大写?

    实际上,MySQL中没有单个函数仅将字符串的首字母大写.我们需要使用的功能,嵌套和针对这种情况,我们可以使用UPPER()和LOWER()使用SUBSTRING()方法.为了理解它,我们使用来自'em ...

  7. mysql替换首字母_MySQL中使用replace、regexp进行正则表达式替换的用法分析

    这篇文章主要介绍了MySQL中使用replace.regexp进行正则表达式替换的用法,结合具体实例形式分析了replace.regexp正则替换的使用技巧与相关注意事项,需要的朋友可以参考下 本文实 ...

  8. mysql 按拼音码查询,MySQL拼音首字母查询

    最近一个项目中有个模块须要实现拼音首字母查询功能,网上查了一下资料,本身从新修改整理了一下,使其知足项目的要求.sql 实现过程以下:函数 1.建立一个获取中英文大写首字母函数:code DROP F ...

  9. mysql 拼音首字母_MySQL 获取某个字段的汉语拼音首字母 - 文章

    在做一个商城的时候,需要用户能有切换城市的功能,城市列表按照汉语拼音首字母排序,城市的数据是从国家统计局扒下来的,只有城市的编码和城市的名称,通过下面的 MySQL 函数,获取某个汉语的首字母. CR ...

最新文章

  1. WinForm 窗体之间交互的一些方法-兼托管事件
  2. Hasor【付诸实践 02】SpringBoot 集成 Dataway 无代码接口工具配置及问题解决(含GreenPlum建表语句、demo源码、测试说明)
  3. mac nginx apache mysql php 一键_Mac 下搭建 apache / nginx+php+mysql
  4. keep-alive使用_如何使用Google Keep进行无忧笔记
  5. Java源代码分析与生成
  6. 数据库笔记07:实施数据完整性
  7. linux监控指定用户操作,Linux 用户行为轨迹监控
  8. vue 引入qunee_Vue页面中js引入的问题
  9. Python使用openpyxl和pandas处理学生成绩Excel文件实用案例
  10. python逐行读取txt文件readline_Python - 无法读取整个.txt文件:.readlines错误?
  11. Linux制作软盘镜像
  12. [开发笔记]-多线程
  13. linux安装git lfs
  14. 连锁机构3D指纹考勤系统解决方案
  15. 博客自定义html模块代码,如何添加博客自定义代码HTML?
  16. php查询qq等级,php仿QQ等级太阳显示函数_php
  17. 【人机交互技术】工具软件界面设计
  18. 了解电子邮件:E-Mail从入门到精通
  19. excel表格xlsx解密方法,忘记excel表格xlsx密码怎么办?
  20. 程序员租女友被骗 揭秘“租友”市场背后那些坑

热门文章

  1. 谈谈Python的Flask框架学习与福利分享
  2. 基于浏览器内核的被动式爬虫任务下发框架
  3. kanziopengl杂谈
  4. 1342764-64-0,Lipoamido-PEG3-alcohol具有lipoamide和羟基端基
  5. 山东大学软件工程期末复习知识点总结
  6. The resource identified by this request is only capable of generating respon
  7. 学ps要计算机基础吗,零基础怎样学会PS?电脑0零基础绘画
  8. 教你一键采集天猫商品主图视频的方法及步骤
  9. 无人机航测技术的优势有哪些?
  10. 无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动