将“商品表.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路上的,屁颠屁颠的小码农。。。。