小工具三:城市反选小工具

就是这个城市反选小工具…前前后后做了一个多月。
0-。 -
工作空闲之余,断断续续的做。然后基本上每次花不少的时间整理一下之前的逻辑(因为越写到后面判断的情况越复杂),每次搞懂了之前进度以后,然后再写一点点…
如此循环,断断续续就写了很久。
当然说到底还是因为菜!
菜是原罪!
最近都没怎么更新博客,从今天开始恢复以往的节奏。
好了,不多BB,说正事。
背景:
有个需求上的功能点,叫做城市反选。
正好有我们这边有一个excel,上面是一个传入的模板,大概长这个样子:
在这里插入图片描述
什么是城市反选呢?当范围是全国的时候:

  1. 比如选择一个省,包含关系不属于,则落在数据库中的字段为其他的省份!
  2. 比如选择一个市区,包含关系不属于,则落在数据库中的字段为其他的省份+该省下面的其他市区!
  3. 比如选择一个省+一个市区(另外的一个省下面的),包含关系不属于,则落在数据库中的字段为其他的省+该省下面的其他市区

    那我们测试的时候,落入数据库中的字段很多的话,肉眼比对的时候会很痛苦。。。。

基于以上几点,正好是excel的模板,联想到以前的对于excel读写熟悉一点,
就开始想着写一个小工具来实现比对。
下面是代码:

package City_FanXuan;

import java.io.File;
import java.io.FileInputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import tool_date.sql_Connection;

/*
 * @author cs
 * */
public class cities_fanxuan {

	static XSSFWorkbook wb = null;
	static File src = null;
	static FileInputStream fis = null;

	public static String cities_fanxuan(String[] city) {
		String city_id = null;
		String city_name = null;
		String city_type = null;
		String up_city = null;
		int j = 0;
		int i;
		int index;
		HashSet<Integer> arr_sheng = new HashSet<Integer>();
		HashSet<Integer> arr_result = new HashSet<Integer>();
		ArrayList<Integer> list_sheng = new ArrayList<Integer>();
		ArrayList<Integer> list_result = new ArrayList<Integer>();
		// 加载城市ID模板,读取excel中的城市信息
		XSSFSheet sh1 = wb.getSheetAt(0);
		// 入参的字符串将会从流量活动的详情页上面复制
		// 对于入参进行判断,先在B列进行匹配判断,如果匹配到了城市名称,则获取当前一行的四个字段的信息
		for (i = 0; i < city.length; i++) {
			for (j = 1; j < sh1.getPhysicalNumberOfRows(); j++) {
				if (city[i].equals(sh1.getRow(j).getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
						.getStringCellValue().trim())) {
					city_id = sh1.getRow(j).getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()
							.trim();
					city_name = sh1.getRow(j).getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
							.getStringCellValue().trim();
					city_type = sh1.getRow(j).getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
							.getStringCellValue().trim();
					up_city = sh1.getRow(j).getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()
							.trim();
					arr_result.add(Integer.valueOf(city_id));
					break;
				}
			}
			System.out.println("第" + (i + 1) + "个参数选城市ID:" + city_id);
			System.out.println("第" + (i + 1) + "个参数选城市名称:" + city_name);
			if (city_type.equals("0")) {
				// 1. 先判断是否为省/区——判断条件:当前行所在的c列是否为0;如果是省/区,则会记录以省ID开头的城市ID并扣掉,拿出其他省份;
				for (int q = 1; q < sh1.getPhysicalNumberOfRows(); q++) {
					// 抠除当前省份的行数
					if (q != j) {
						// 循环遍历其他行,通过0/1来判断是否为省,如果是,则拿该行的第一列(城市id)放入数组中
						if (Integer.valueOf(sh1.getRow(q).getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
								.getStringCellValue().trim()) == 0) {
							arr_sheng.add(
									Integer.valueOf(sh1.getRow(q).getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
											.getStringCellValue().trim()));
						}
					}
				}
			} else {
				System.out.println("我的上级城市是:" + up_city);
				// 2. 当前为市区:
				for (int q = 1; q < sh1.getPhysicalNumberOfRows(); q++) {
					arr_result.add(Integer.valueOf(up_city));
					// 抠除当前市区以及当前市区所在的省份,且只有省的行数下:
					if (!sh1.getRow(q).getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue()
							.trim().equals(city_id)
							&& !sh1.getRow(q).getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
									.getStringCellValue().trim().equals(up_city)
							&& Integer.valueOf(sh1.getRow(q).getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)
									.getStringCellValue().trim().substring(2, 6)) == 0000) {
						arr_sheng.add(Integer.valueOf(sh1.getRow(q)
								.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue().trim()));
					}
					if (sh1.getRow(q).getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue().trim()
							.equals(up_city) && q != j) {
						arr_sheng.add(Integer.valueOf(sh1.getRow(q)
								.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue().trim()));
					}
				}
			}
		}
		for (Integer str : arr_sheng) {
			list_sheng.add(str);
		}
		for (Integer str : arr_result) {
			list_result.add(str);
		}
		for (int k = 0; k < list_sheng.size(); k++) {
			if (list_result.contains(list_sheng.get(k))) {
				list_sheng.remove(k);
			}
		}
		System.out.print("本次运行结果:");
		for (index = 0; index < list_sheng.size(); index++) {
			if (index != list_sheng.size() - 1) {
				System.out.print(list_sheng.get(index) + ",");
			}
		}
		return list_sheng.toString();
	}

	// 去数据库查询城市ID
	public static String sql(String a) {
		//避免暴露信息所以**代替
		String sql = "SELECT ** FROM `******` WHERE ****= '" + a + "'";// SQL语句
		sql_Connection db1 = new sql_Connection(sql);// 创建sql_Connection对象
		ResultSet ret = null;
		String city_code = null;
		try {
			ret = db1.pst.executeQuery();// 执行语句,得到结果
			while (ret.next()) {
				city_code = ret.getString(1);
				System.out.println("数据库中的值为:" + city_code);
			} // 显示数据
			ret.close();
			db1.close();// 关闭连接
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return city_code;
	}

	// 运行结果和数据库中的字段进行比对
	public static boolean BiDui(String a, String b) {
		String[] strArr = sql(b).split(",");
		String[] strArr2 = a.replace(" ", "").replace("[", "").replace("]", "").split(",");
		Arrays.sort(strArr);
		Arrays.sort(strArr2);
		boolean result = Arrays.equals(strArr, strArr2);
		System.out.println("本次数据库结果按升序排序:");
		for (int x = 0; x < strArr.length; x++) {
			System.out.print(strArr[x]);
		}
		System.out.println();
		System.out.println("本次运行结果按升序排序:");
		for (int y = 0; y < strArr2.length; y++) {
			System.out.print(strArr2[y]);
		}
		System.out.println();
		System.out.println("本次比对结果为:");
		return result;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		src = new File("./Files_CityID/CityID.xlsx");
		// 加载文件
		try {
			fis = new FileInputStream(src);
			wb = new XSSFWorkbook(fis);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		long t1 = System.currentTimeMillis();
		Scanner input = new Scanner(System.in);
		System.out.println("请复制详情页面城市字段的值到这儿进行粘贴:");
		String s = input.next();
		System.out.println(BiDui(cities_fanxuan(s.split(",")), "1904160030000510756"));
		long t2 = System.currentTimeMillis();
		System.out.println("大吉大利!请进行下次数据比对!本次用时 " + (t2 - t1) + " 毫秒");
	}
}

还有一个jdbc:

package tool_date;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class sql_Connection {
	public static final String url = "jdbc:mysql://****";
	public static final String name = "com.mysql.jdbc.Driver";
	public static final String user = "*****";
	public static final String password = "****";

	public Connection conn = null;
	public PreparedStatement pst = null;

	public sql_Connection(String sql) {
		try {
			Class.forName(name);// 指定连接类型
			conn = DriverManager.getConnection(url, user, password);// 获取连接
			pst = conn.prepareStatement(sql);// 准备执行语句
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void close() {
		try {
			this.conn.close();
			this.pst.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

单个市区:
在这里插入图片描述
单个省:
在这里插入图片描述
多个市区:
在这里插入图片描述
多个省+多个市区:
在这里插入图片描述
以上就是实现的功能…
在使用的时候,需要传入两个参数:
一个id是用来进行sql查询的;
另外一个是反选的城市名称。
这两个参数都可以在详情页直接复制,拷贝进来(连逗号都不用去,入参已经考虑到这种情况),直接运行,很方便。
在这里插入图片描述
在这过程中,遇到了很多的痛苦点,差点把头搞晕
难点:

  1. 只选择省,则只返回其他省份(需要抠掉市区);
  2. 只选择市区,则需要抠掉当前市区对应的省,再拿到该省下其他的市区+其他省;
  3. 选择省+市区,则需要拿到…
    几种情况一累加,稍微有点晕。
    总结:
    当然,目前这个小工具写的很多地方都不完善,比如入参的校验、异常的捕捉等等
    但是基本上是可以使用的!
    其实有相关的城市的静态代码块,用集合相关的方法来处理,其实比我这种硬用excel读写来判断要简单的多!
    哈哈
    其实这个工具感觉稍微有一点点鸡肋…
    但是在这个工具写的过程中,暴露出很多问题:
    对于java基础知识不牢靠;
    jdk-api上面的方法淡忘了;
    做事积极性不高

    慢慢来吧!
    待改善的地方:
    我这边的范围是全国,如果范围不是全国,可以自己传入参数来设定的范围:
    比如几个省+几个市区
    那么反选的结果是什么?

    实现过程异常复杂,待大神修改啦!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值