因为项目做一个一个批量查询,当后台将上传的Excel表格解析并返回到前台的input搜索框后,点击查询寻
$table.search()进入到后台,因为项目需要,其需要进行一个模糊查询,按匹配度,查出相关的内容,匹配度100%,只查出一条,不足的按匹配度从高到低,查出5条。匹配度为0的就查不出。
现在看后台:
因为前台写了一个查询和批量查询按钮,所以这里做了一个判断。因为查询条件拿的是form表单的值,所以要进行判断。
/**
* 查询企业背景-企业基本列表
*/
@RequiresPermissions("system:tycBaseinfo:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(TycBaseinfo tycBaseinfo)
{
/*startPage();*/
List <TycBaseinfo> listAll= new ArrayList<>();
String selectName = tycBaseinfo.getName();
String nameAll = tycBaseinfo.getNameArr();
//批量查询
if((!("").equals(nameAll)&&nameAll!=null)&&(("").equals(selectName)||selectName==null)){
return getDataTable(tycBaseinfoService.selectTycBaseinfoSearchList(tycBaseinfo));
}else {
//单项查询
tycBaseinfo.setNameArr("");
return getDataTable(tycBaseinfoService.selectTycBaseinfoList(tycBaseinfo));
}
}
这里主要看server层的逻辑代码:
tycBaseinfoService.selectTycBaseinfoSearchList(tycBaseinfo)
进入servers层
public List<TycBaseinfo> selectTycBaseinfoSearchList(TycBaseinfo tycBaseinfo)
{
List <TycBaseinfo> listAll= new ArrayList<>();
//存放匹配度100%list
List <TycBaseinfo> listOnly= new ArrayList<>();
//存放匹配度不是100%list
List <TycBaseinfo> listMany= new ArrayList<>();
String nameAll = tycBaseinfo.getNameArr();
String[] nameArr = nameAll.split(",");
List<String> factoryNameList=new ArrayList<String>(Arrays.asList(nameArr));
for(int i=0;i<factoryNameList.size(); i++) {
TycBaseinfo tycBaseinfo1 = new TycBaseinfo();
List<TycBaseinfo> list = tycBaseinfoMapper.selectTycBaseinfoList(tycBaseinfo1);
//对每个查询条件第一个查询出来的数据,selectName进行赋值(等价于前台分组)
//拿到当前的查询条件,进行比对。查出匹配度最高的五条记录
//进行分组查询,需要将保存企业命名的nameList遍历查询
String str1 = factoryNameList.get(i);
//如果查询条件是空,或是null,则默认查出所有数据
if(("").equals(str1)||str1==null){
}else{
list = levenshtein(str1,list);
if(list.size()==1){
for (int j = 0; j < list.size(); j++) {
if (j == 0) {
list.get(j).setSelectName(factoryNameList.get(i));
} else {
list.get(j).setSelectName("");
}
}
//如果是匹配度100%,就一条数据,就保存到listOnly
listOnly.addAll(list);
}else{
for (int j = 0; j < list.size(); j++) {
if (j == 0) {
list.get(j).setSelectName(factoryNameList.get(i));
} else {
list.get(j).setSelectName("");
}
}
//如果是匹配度不是100%,就有5或以下条数据,就保存到listMany
listMany.addAll(list);
}
}
}
listAll.addAll(listOnly);
listAll.addAll(listMany);
return listAll;
}
因为前台传来的NameArr是一大串字符串,所以采用
String[] nameArr = nameAll.split(",");进行分割,存到数组中
然后将其转为list
List factoryNameList=new ArrayList(Arrays.asList(nameArr));
查出所以数据:
List list = tycBaseinfoMapper.selectTycBaseinfoList(tycBaseinfo1);
调用编辑算法
list = levenshtein(str1,list);
编辑距离算法
public List<TycBaseinfo> levenshtein(String str1,List<TycBaseinfo> list) {
//保存相似度
/* List<Float> similaritylist = new ArrayList();*/
//listFive用于保存匹配对最高的五条记录
List<TycBaseinfo> listFive = new ArrayList<>() ;
//保存相似度最大的值
float similarityFirst = (float) 0;
float similaritySecond = (float) 0;
float similarityThird = (float) 0;
float similarityFourth = (float) 0;
float similarityFifth = (float) 0;
//保存相似度最大的那条记录的list的i值
int first = 0;
int second = 0;
int third = 0;
int fourth = 0;
int fifth = 0;
//计算两个字符串的长度。
int len1 = str1.length();
for(int k =0;k<list.size();k++){
String str2 = list.get(k).getName();
int len2 = str2.length();
//建立上面说的数组,比字符长度大一个空间
int[][] dif = new int[len1 + 1][len2 + 1];
//赋初值,步骤B。
for (int a = 0; a <= len1; a++) {
dif[a][0] = a;
}
for (int a = 0; a <= len2; a++) {
dif[0][a] = a;
}
//计算两个字符是否一样,计算左上的值
int temp;
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
temp = 0;
} else {
temp = 1;
}
//差异步骤,取三个值中最小的
dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1,
dif[i - 1][j] + 1);
}
}
/*System.out.println("字符串\""+str1+"\"与\""+str2+"\"的比较");
//取数组右下角的值,同样不同位置代表不同字符串的比较
System.out.println("差异步骤:"+dif[len1][len2]);
//计算相似度*/
float similarity =1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length());
/*System.out.println("相似度:"+similarity);*/
//取相似度最高的那条记录
if(similarityFirst<=similarity){
similarityFirst = similarity;
first= k;
}
//取相似度第二的那条记录
if(similarity<similarityFirst&&similaritySecond<=similarity){
similaritySecond = similarity;
second= k;
}
//取相似度第三的那条记录
if(similarity<similaritySecond&&similarityThird<=similarity){
similarityThird = similarity;
third= k;
}
//取相似度第四的那条记录
if(similarity<similarityThird&&similarityFourth<=similarity){
similarityFourth = similarity;
fourth= k;
}
//取相似度第五的那条记录
if(similarity<similarityFourth&&similarityFifth<=similarity){
similarityFifth = similarity;
fifth= k;
}
}
if(similarityFirst ==1.00){
listFive.add(list.get(first));
}else if(similarityFirst == 0.00){
}else{
listFive.add(list.get(first));
if(similaritySecond != 0.00){
listFive.add(list.get(second));
}
if(similarityThird != 0.00){
listFive.add(list.get(third));
}
if(similarityFourth != 0.00){
listFive.add(list.get(fourth));
}
if(similarityFifth != 0.00){
listFive.add(list.get(fifth));
}
}
return listFive;
}
//得到最小值
private static int min(int... is) {
int min = Integer.MAX_VALUE;
for (int i : is) {
if (min > i) {
min = i;
}
}
return min;
}
listAll.addAll(listOnly);
listAll.addAll(listMany);
listOnly是保存匹配度100%的信息
listMany是保存匹配度不为100%的信息。
最后进行拼接,保存到一个list中
最后,和上面的上传功能整体的一个页面是这样的