将“商品表.xls”和“类别表.xls”中的数据导入到数据库中,实现相关检索功能,以及模糊搜索功能。

以下程序涉及到内容:

1.从excel文件中导入数据到数据库。

2.分页功能

3.模糊搜索


咱们先说第一个内容:如何将excel文件中的数据导入数据库?


/**
	 * 从excel-2000/2003版本的文件中读(写)数据,并添加到数据库
	 * 
	 * @param file	目标文件
	 * @return
	 */
	public void read(File file) {
		Goods goods = null;
		GType gtype = null;
		Workbook workbook = null;
		try {
			// 创建一个工作薄
			workbook = workbook.getWorkbook(file);
			// 获取指定名称的表单对象
			Sheet sheet = workbook.getSheet("Sheet1");
			// 获取总行数
			int rows = sheet.getRows();
			if ("商品表.xls".equals(file.getName())) {
				for (int i = 1; i < rows; i++) {

					goods = new Goods(); // (列,行)去掉了第一行(属性名)
					String s1 = sheet.getCell(0, i).getContents(); // 商品id
					String s2 = sheet.getCell(1, i).getContents(); // 商品名
					String s3 = sheet.getCell(2, i).getContents(); // 单价
					String s4 = sheet.getCell(3, i).getContents(); // 折扣
					String s5 = sheet.getCell(4, i).getContents(); // 上架时间
					String s6 = sheet.getCell(5, i).getContents(); // 库存
					String s7 = sheet.getCell(6, i).getContents(); // 商品类别id

					goods.setId(TypeTools.getInt(s1));
					goods.setgname(s2);
					goods.setPrice(TypeTools.getBigDecimal(s3));
					goods.setOffset(TypeTools.getDouble(s4));
					goods.setdate(TypeTools.getDate(s5));
					goods.setCounts(TypeTools.getInt(s6));
					goods.setType(new GType(TypeTools.getInt(s7), ""));

					// 将该记录存储数据库中
					Connection conn = DBUtils.getConn();
					DBUtils.execUpdate(conn,
							"insert into goods(id,gname,price,offset,date,counts,tid) values(?,?,?,?,?,?,?)",
							goods.getId(), goods.getgname(), goods.getPrice(), goods.getOffset(), TypeTools.getDate(s5),
							goods.getCounts(), TypeTools.getInt(s7));
					conn.close();
				}
			} else if ("类别表.xls".equals(file.getName())) {
				for (int i = 1; i < rows; i++) {

					gtype = new GType(); // (列,行)去掉了第一行(属性名)
					String s1 = sheet.getCell(0, i).getContents(); // 类别id
					String s2 = sheet.getCell(1, i).getContents(); // 类别

					gtype.setId(TypeTools.getInt(s1));
					gtype.setCname(s2);

					// 将该记录存储数据库中
					Connection conn = DBUtils.getConn();
					DBUtils.execUpdate(conn, "insert into gtype(id,cname) values(?,?)", gtype.getId(),
							gtype.getCname());
					conn.close();
				}
			} else {
				System.out.println("文件有误!");
				return;
			}
			System.out.println(file.getName() + "----数据导入完毕!");

		} catch (BiffException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}






其中涉及的DBUtils是个封装的DBCP数据库连接工具类,TypeTools是类型转换工具,代码分别如下:



import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;

import org.apache.commons.dbcp2.BasicDataSource;

/**
 * DBCP数据库连接工具类
 * 依赖
 * 1.mysql驱动
 * 2.dbcp相关插件
 * @author mrchai
 *
 */
public class DBUtils {

	//连接数据库基本属性
	private static String driverClass;
	private static String url;
	private static String username;
	private static String password;
	//连接池属性
	private static int initSize;
	private static int maxSize;
	private static int maxIdle;
	private static long maxWait;
	//数据源
	private static BasicDataSource bds;
	
	//初始化数据源配置
	static{
		init();
	}
	
	public static void init(){
		try {
			//创建数据源对象
			bds = new BasicDataSource();
			//加载属性文件,获取属性信息
			Properties props = new Properties();
			props.load(DBUtils.class.getResourceAsStream("jdbc.properties"));
			driverClass = props.getProperty("driver");
			url = props.getProperty("url");
			username = props.getProperty("user");
			password = props.getProperty("password");
			
			initSize = Integer.parseInt(props.getProperty("initSize"));
			maxSize = Integer.parseInt(props.getProperty("maxSize"));
			maxIdle = Integer.parseInt(props.getProperty("maxIdle"));
			maxWait = Long.parseLong(props.getProperty("maxWait"));
			
			//设置驱动类路径
			bds.setDriverClassName(driverClass);
			//设置url
			bds.setUrl(url);
			//设置用户名
			bds.setUsername(username);
			//设置密码
			bds.setPassword(password);
			
			//设置初始连接数
			bds.setInitialSize(initSize);
			//设置最大连接
			bds.setMaxTotal(maxSize);
			//设置最大闲置连接数
			bds.setMaxIdle(maxIdle);
			//等待获取连接的最大时间(MS)
			bds.setMaxWaitMillis(maxWait);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//获取连接
	public static Connection getConn(){
		try {
			if(bds == null || bds.isClosed()){
				init();
			}
			return bds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//封装资源回收的方法
	public static void close(ResultSet rs,Statement stat,Connection conn){
	
		try {
			if(rs != null) rs.close();
			if(stat != null) stat.close();
			if(conn != null)conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 通用增删改
	 * @param conn
	 * @param sql
	 * @param objs
	 * @return
	 */
	public static boolean execUpdate(Connection conn,String sql,Object ...objs){
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			for (int i = 0; i < objs.length; i++) {
				ps.setObject(i+1, objs[i]);
			}
			int i = ps.executeUpdate();
			return i>0 ? true:false;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * C++钩子函数    回调函数
	 * 集合查询
	 * @param sql
	 * @param call
	 * @param params
	 * @return
	 */
	public static <T> List<T> queryList(String sql,CallBack<T> call,Object...params){
		Connection conn = DBUtils.getConn();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i = 0;i<params.length;i++)
			{
				ps.setObject(i+1, params[i]);
			}
			ResultSet rs = ps.executeQuery();
			return call.getDatas(rs);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 查询一条记录
	 * @param sql
	 * @param call
	 * @param params
	 * @return
	 */
	public static <T> T queryOne(String sql,CallBack<T> call,Object...params)
	{
		Connection conn = DBUtils.getConn();
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i = 0;i<params.length;i++)
			{
				ps.setObject(i+1, params[i]);
			}
			ResultSet rs = ps.executeQuery();
			return call.getData(rs);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//查询返回接口 jdk1.8支持
//	public interface CallBack<T>{
//		default List<T> getDatas(ResultSet rs){
//			return null;
//		}
//		default T getData(ResultSet rs){
//			return null;
//		}
//	}
	
	//jdk1.8以下使用抽象类
	public static abstract class CallBack<T>{
		public List<T> getDatas(ResultSet rs){
			return null;
		}
		public T getData(ResultSet rs){
			return null;
		}
	}
	
}






TypeTools


import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

public class TypeTools {

	static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
	
	/**
	 * String -> int
	 * @param s
	 * @return
	 */
	public static int getInt(String s){
		if(Pattern.matches("^\\d*$",s)){
			return Integer.parseInt(s);
		}
		return 0;
	}
	
	/**
	 * String -> double
	 * @param s
	 * @return
	 */
	public static double getDouble(String s){
		if(Pattern.matches("^\\d+\\.??\\d+$", s)){
			return Double.parseDouble(s);
		}
		return 0.0;
	}
	
	/**
	 * String -> Date
	 * @param s
	 * @return
	 */
	public static Date getDate(String s)
	{
		//"" != null
		Date date = null;
		try {
			if(s != null && !"".equals(s)){
				date = sdf.parse(s);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	/**
	 * 把日期类型对象转为字符串对象
	 * @param d
	 * @return
	 */
	public static String getStringDate(Date d){
		if(d != null){
			return sdf.format(d);
		}
		return "";
	}
	
	/**
	 * BigDecimal 
	 * @param s
	 * @return
	 */
	public static BigDecimal getBigDecimal(String s)
	{
		if(Pattern.matches("^\\d+\\.??\\d+$", s)){
			return new BigDecimal(s);
		}
		return new BigDecimal("0.0");
	}
}








再说说第二个内容,分页显示

需要用到sql中的关键字limit;

limit A,B  显示从A(不包括A)开始的B条数据记录

要显示goods表中当前页cur的数据(每页size条记录),即:

select * from goods limit (cur-1)*size,size;


/**
	 * 根据分类,显示分类下所有的商品信息(分页显示),按照库存量从低到高排序(提供补货依据)
	 * 
	 * @param type 种类;	cur 分页,当前页;	size 分页大小
	 */
	public List<Goods> findByType(GType type, int cur, int size) {
		//limit A,B	显示从A(不包括A)开始的B条数据
		if (type.getCname() != null) {
			DBUtils.queryList(
					"select g.id,gname,price,offset,date,counts,tid from goods g,gtype gt where g.tid = gt.id and gt.cname = ? order by counts limit ?,?",
					new Call(), type.getCname(), (cur - 1) * size, size);
		} else if (type.getId() != 0) {
			DBUtils.queryList(
					"select g.id,gname,price,offset,date,counts,tid from goods g where g.tid = ? order by counts limit ?,?",
					new Call(), type.getId(), (cur - 1) * size, size);
		} else {
			System.out.println("你的类型(type)是空的哦....");

		}
		return null;
	}



注:上面的Call类是DBUtils类中CallBack的子类,并重写了其中getDatas方法,代码如下:


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.softeem.goodsManager.dto.GType;
import com.softeem.goodsManager.dto.Goods;
import com.softeem.utils.DBUtils.CallBack;

/**
 * 继承CallBack
 * @author Administrator
 *
 */
public class Call extends CallBack<Goods>{
	@Override
	public List<Goods> getDatas(ResultSet rs) {
		try {
			List<Goods> list = new ArrayList<>();
			Goods goods = new Goods();
//				System.out.println("id\tgname\tprice\toffset\tdate\tcounts\ttid");
			while(rs.next()){
//					System.out.println(rs.getInt("id")+"\t"+rs.getString("gname")+"\t"+rs.getString("price")
//							+"\t"+rs.getDouble("offset")+"\t"+rs.getDate("date")+"\t"+rs.getInt("counts")+"\t"+rs.getInt("tid"));
				goods.setId(rs.getInt("id"));
				goods.setgname(rs.getString("gname"));
				goods.setPrice(rs.getBigDecimal("price"));
				goods.setOffset(rs.getDouble("offset"));
				goods.setdate(rs.getDate("date"));
				goods.setCounts(rs.getInt("counts"));
				goods.setType(new GType(rs.getInt("tid"),null));
				list.add(goods);
				System.out.println(goods);
			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return super.getDatas(rs);
	}
}




最后,再说一说模糊搜索:

需要用到sql中like以及concat关键字;

concat的功能是连接字符串:

如: select concat('张三丰','项目经理','男','湖北武汉');便会得到 '张三丰项目经理男湖北武汉'

like的功能是关键字限制:

如:like '%服饰%'表示该数据中应当含有 ‘服饰’这个关键字

那么,我们便可以利用concat将数据库中各属性连接起来组成一个字符串,再依靠like进行关键字限制,便达到了模糊搜索的功能。


/**
	 * 模糊搜索,根据商品信息(名称或类别)
	 * 
	 * @param str
	 * @return
	 */
	public List<Goods> undefinedSearch(String str) {
		// #利用concat连接所有列,进行任意字段的模糊查询
		// select concat('张三丰','项目经理','男','湖北武汉');
		// select u.* from tbuser u,(select
		// concat(name,job,sex,address,school,major) words from tbuser) t where u.uid = t.uid and t.words like '%服饰%';
		DBUtils.queryList(
					"select g.* from goods g,(select concat(gname,cname) words,goods.id from goods,gtype where goods.tid = gtype.id) t "
							+ "where g.id = t.id and t.words like ?",
				new Call(), "%" + str + "%");
		return null;
	}




好了,以上就是一个关于jdbc的小练习。

我是一个走在学习java路上的,屁颠屁颠的小码农。。。。