在惠普济宁基地进行了两周sql和java的学习,学到很多东西
刚才实现了用jdbc访问数据库对数据库进行操作,是用eclipse写的,过几天移植到NetBeans上,个人还是比较习惯看图形化界面
前几天茫然无头绪的时候闫老师指点迷津了一下,讲了具体的流程,如下:
1.创建项目
2.导入相关JAR
3.组织项目结构
util:工具类,公共类
po:实体类对象
dao:数据访问
biz:业务类
view:显示
第一步不多陈述
第二步具体如何配置可以参见蔡振华的博客http://qmkkd.blog.51cto.com/9511687/1682048
我详细说下第三步组织项目结构,我的理解还不是很透彻,欢迎大家指正,先弄张图
先创建com.shop.util包,包里放工具类,公共类,我是放了一个SqlHelper类,提供sql的相关帮助
之前在用C#做的时候,我在里面放了连接和增删查改的函数,但是在这里我只放了连接数据库,关闭结果集,关闭Statement,关闭连接的函数,上代码
1 package com.shop.util; 2 3 import java.sql.*; 4 5 //SqlHelper类 6 //定义了数据库连接函数,关闭查询结果集,关闭Statement对象,关闭数据库连接 7 //这样的做法是执行上述4个操作时可以直接调用函数(面向对象的思想),可以好好理解一下 8 public class SqlHelper { 9 public static Connection getConnection() { 10 Connection conn = null; 11 String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";// 驱动 12 String url = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=Shopping";// SqlServer链接地址 13 String username = "sa";// 用户名 14 String password = "sa";// 密码 15 try { 16 Class.forName(driver);// 加载驱动类 17 conn = DriverManager.getConnection(url, username, password); 18 } catch (ClassNotFoundException e) { 19 System.out.println("找不到驱动程序类 ,加载驱动失败!"); 20 e.printStackTrace(); 21 } catch (SQLException e) { 22 System.out.println("数据库连接失败!"); 23 e.printStackTrace(); 24 } 25 // System.out.println("连接成功"); 26 return conn; 27 } 28 //关闭连接 29 public static void closeConn(Connection conn){ 30 if(conn!=null){ 31 try { 32 conn.close(); 33 } catch (SQLException e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 } 38 } 39 //关闭执行对象 40 public static void closeStatement(Statement stmt){ 41 if(stmt!=null){ 42 try { 43 stmt.close(); 44 } catch (SQLException e) { 45 // TODO Auto-generated catch block 46 e.printStackTrace(); 47 } 48 } 49 } 50 //关闭结果集 51 public static void closeResultSet(ResultSet rs){ 52 if(rs!=null){ 53 try { 54 rs.close(); 55 } catch (SQLException e) { 56 // TODO Auto-generated catch block 57 e.printStackTrace(); 58 } 59 } 60 } 61 }
然后是com.shop.po包,包里放实体类对象,这点如果不是老师指点我完全没有想到。。以前都是整条数据直接插入。
但是设置实体类对象后提高了程序的结构性和面向对象的感觉。。这样说有点怪。。下面是Goods类,很简单,这个类就对应数据库里面的一个表,这个类的对象就对应数据库里面的一条记录,这样说大家不知道能不能明白,上代码
1 package com.shop.po; 2 3 public class Goods { 4 private int id; 5 private String name; 6 private String kind; 7 private double price; 8 private int stock; 9 private String description; 10 11 public int getId() { 12 return id; 13 } 14 15 public void setId(int id) { 16 this.id = id; 17 } 18 19 public Goods(){ 20 21 } 22 23 public Goods(String name, String kind, double price, int stock, 24 String description) { 25 super(); 26 this.name = name; 27 this.kind = kind; 28 this.price = price; 29 this.stock = stock; 30 this.description = description; 31 } 32 33 public String getName() { 34 return name; 35 } 36 37 public void setName(String name) { 38 this.name = name; 39 } 40 41 public String getKind() { 42 return kind; 43 } 44 45 public void setKind(String kind) { 46 this.kind = kind; 47 } 48 49 public double getPrice() { 50 return price; 51 } 52 53 public void setPrice(double price) { 54 this.price = price; 55 } 56 57 public int getStock() { 58 return stock; 59 } 60 61 public void setStock(int stock) { 62 this.stock = stock; 63 } 64 65 public String getDescription() { 66 return description; 67 } 68 69 public void setDescription(String description) { 70 this.description = description; 71 } 72 73 public String toString() { 74 return this.getName() + "," + this.getKind() + "," + this.getPrice() 75 + "," + this.getStock() + "," + this.getDescription(); 76 } 77 78 }
然后是dao包,包里放数据访问的类,这部分里面的代码可能不太规范。。。毕竟是自己慢慢挤的,闫老师的方法是
写一个GoodsDao接口,里面定义对Goods表操作的函数,但不提供实现,上代码
1 package com.shop.dao; 2 3 import java.util.List; 4 5 import com.shop.po.Goods; 6 7 /** 8 * 对商品信息操作 9 * @author HP-Developer 10 * 11 */ 12 //定义接口,其中的函数是用来对数据库进行操作 13 //具体实现是在GoodsDaoImpl中 14 public interface GoodsDao { 15 16 public int insertGoods(Goods goods); 17 18 public int deleteGoods(int id); 19 20 public int updateGoods(int id,Goods goods);//参数为修改后的新商品对象 21 22 public List<Goods> findAll(); 23 24 public Goods findById(int id); 25 }
然后是接口的实现,在GoodsDaoImpl类中,上代码,这部分代码是核心,有一定的瑕疵
1 package com.shop.dao; 2 3 import java.sql.*; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import com.shop.po.Goods; 8 import com.shop.util.SqlHelper; 9 10 /** 11 * GoodsDao接口实现类 12 * 13 * @author HP-Developer 14 * 15 */ 16 public class GoodsDaoImpl implements GoodsDao { 17 18 public int insertGoods(Goods goods) { 19 Connection conn = null; 20 //PreparedStatement和Statement的区别在于 21 //PreparedStatement接口继承Statement, 22 //PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。 23 //作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。 24 //三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数 25 //PreparedStatement性能更优,建议使用,但是比较复杂一点 26 27 //Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句 28 //使用 Statement 对象执行语句 29 Statement stmt = null; 30 int result = 0; 31 String name=goods.getName(); 32 String kind=goods.getKind(); 33 double price=goods.getPrice(); 34 int stock=goods.getStock(); 35 String des=goods.getDescription(); 36 String sql = "insert into Goods values('"+name+"','"+kind+"','"+price+"','"+stock+"','"+des+"')"; 37 // 访问数据库 38 try { 39 // 1获得连接 40 conn = SqlHelper.getConnection(); 41 // 2执行对象 42 stmt = conn.createStatement(); 43 // 3执行 44 result = stmt.executeUpdate(sql); 45 46 } catch (Exception e) { 47 //捕捉错误 48 e.printStackTrace(); 49 } finally { 50 //关闭操作对象 51 SqlHelper.closeStatement(stmt); 52 //关闭连接 53 SqlHelper.closeConn(conn); 54 } 55 //返回受影响的行数 56 return result; 57 //try catch finally是一种语句结构 58 //就我个人的理解,在try中执行操作,catch捕捉错误,finally进行收尾 59 } 60 61 //删除和更新与插入类似 ,我就不加注释了 62 public int deleteGoods(int id) { 63 Connection conn = null; 64 Statement stmt = null; 65 int result = 0; 66 String sql = "delete from Goods where gID='"+id+"'"; 67 try { 68 conn = SqlHelper.getConnection(); 69 stmt = conn.createStatement(); 70 result = stmt.executeUpdate(sql); 71 } catch (SQLException e) { 72 // TODO Auto-generated catch block 73 e.printStackTrace(); 74 } finally { 75 SqlHelper.closeStatement(stmt); 76 SqlHelper.closeConn(conn); 77 } 78 79 return result; 80 } 81 82 public int updateGoods(int id, Goods goods) { 83 // TODO Auto-generated method stub 84 Connection conn = null; 85 Statement stmt = null; 86 int result = 0; 87 String name=goods.getName(); 88 String kind=goods.getKind(); 89 double price=goods.getPrice(); 90 int stock=goods.getStock(); 91 String des=goods.getDescription(); 92 String sql = "update Goods set gName='"+name+"',gKind='"+kind+"',gPrice='"+price+"',gNum='"+stock+"',gDes='"+des+"' where gID='"+id+"'"; 93 try { 94 conn = SqlHelper.getConnection(); 95 stmt = conn.createStatement(); 96 result = stmt.executeUpdate(sql); 97 } catch (SQLException e) { 98 e.printStackTrace(); 99 } finally { 100 SqlHelper.closeStatement(stmt); 101 SqlHelper.closeConn(conn); 102 } 103 return result; 104 } 105 106 //查询全部商品 107 //因为是多个对象,采用返回List的方式,返回Goods对象的集合 108 public List<Goods> findAll() { 109 Connection conn=null; 110 Statement stmt=null; 111 //创建对象集合 112 List gdList = new ArrayList(); 113 ResultSet rs=null; 114 String sql="select * from Goods"; 115 try{ 116 conn=SqlHelper.getConnection(); 117 stmt=conn.createStatement(); 118 rs=stmt.executeQuery(sql); 119 while(rs.next()){ 120 //创建单个对象 121 Goods gd = new Goods(); 122 gd.setId(rs.getInt("gID")); 123 gd.setName(rs.getString("gName")); 124 gd.setKind(rs.getString("gKind")); 125 gd.setPrice(rs.getDouble("gPrice")); 126 gd.setStock(rs.getInt("gNum")); 127 gd.setDescription(rs.getString("gDes")); 128 //将此对象存入集合中,昨天闫老师带我们学习了ArrayList,add方法大家应该不陌生 129 gdList.add(gd); 130 } 131 } 132 catch(SQLException e){ 133 e.printStackTrace(); 134 } 135 finally{ 136 SqlHelper.closeResultSet(rs);//关闭结果集 137 SqlHelper.closeStatement(stmt);//关闭Statement对象 138 SqlHelper.closeConn(conn);//关闭连接 139 //注意关闭的顺序不能 140 } 141 return gdList; 142 } 143 144 public Goods findById(int id) { 145 Connection conn=null; 146 Statement stmt=null; 147 //在判断商品存在后再new对象,这样规范 148 Goods gd = null; 149 ResultSet rs=null;//定义数据集ResultSet 接受stmt.executeQuery(sql)的返回值 150 String sql="select * from Goods where gID='"+id+"'"; 151 try{ 152 conn=SqlHelper.getConnection(); 153 stmt=conn.createStatement(); 154 //gd=(Goods)stmt.executeQuery(sql);stmt.executeQuery(sql)的返回值是一个结果集ResultSet 155 //因为返回的记录是一条,之前想用强制转换的方法实现返回一个商品(Goods)对象,但是不可行,这条代码错误,下面给出正确的操作 156 rs=stmt.executeQuery(sql); 157 if(rs.next()){ 158 gd=new Goods(); 159 gd.setId(rs.getInt("gID")); 160 gd.setName(rs.getString("gName")); 161 gd.setKind(rs.getString("gKind")); 162 gd.setPrice(rs.getDouble("gPrice")); 163 gd.setStock(rs.getInt("gNum")); 164 gd.setDescription(rs.getString("gDes")); 165 } 166 else{ 167 //这样返回一个空商品对象,节省了即使对象为空还赋值的多余操作 168 return gd; 169 } 170 } 171 catch(SQLException e){ 172 e.printStackTrace(); 173 } 174 finally{ 175 SqlHelper.closeResultSet(rs);//关闭结果集 176 SqlHelper.closeStatement(stmt);//关闭 177 SqlHelper.closeConn(conn);//关闭数据库连接 178 } 179 return gd; 180 } 181 }
//我改正了里面的一些代码
然后是com.shop.biz业务类包。这个我不太熟悉。这个项目比较简单。里面是空的
最后是com.shop.view视图包,里面我放了主函数,这个可能也写的不太规范,我刚才修正了之前的一些代码,上代码
1 package com.shop.view; 2 3 import java.util.List; 4 import java.util.Scanner; 5 6 import com.shop.dao.*; 7 import com.shop.po.Goods; 8 9 public class TestGoods { 10 static Scanner sc = new Scanner(System.in); 11 // 非静态方法需要声明对象来调用 12 static GoodsDaoImpl goodsdao = new GoodsDaoImpl(); 13 14 public static void main(String[] args) { 15 while (true) { 16 System.out.println("请选择你要进行的操作:"); 17 System.out 18 .println("1.插入商品 2.删除商品 3.更新商品 4.按id查询商品 5.查询全部商品 6.退出"); 19 int choose = sc.nextInt(); 20 switch (choose) { 21 case 1: 22 insertGood(); 23 break;// 插入商品 24 case 2: 25 deleteGood(); 26 break;// 删除商品 27 case 3: 28 updateGood(); 29 break;// 更新商品 30 case 4: 31 printGoodById(); 32 break;// 按id查询商品 33 case 5: 34 printAll(); 35 break;// 输出全部商品信息 36 case 6: 37 System.exit(0); 38 default: 39 System.out.println("输入有误"); 40 break; 41 } 42 } 43 44 } 45 46 public static void insertGood() { 47 // 插入数据测试,测试成功 48 // Goods goodTest=new Goods("大哥大","手机",10000,5,"高级又防身"); 49 System.out.println("请输入商品名称:"); 50 String name = sc.next(); 51 System.out.println("请输入商品类型:"); 52 String kind = sc.next(); 53 System.out.println("请输入商品价格:"); 54 double price = sc.nextDouble(); 55 System.out.println("请输入商品库存:"); 56 int stock = sc.nextInt(); 57 System.out.println("请输入商品描述:"); 58 String des = sc.next(); 59 Goods goodInsertTest = new Goods(name, kind, price, stock, des); 60 // 调用GoodsDaoImpl中实现的函数 61 // 插入删除和更新的操作 ,函数返回值为受影响的行数, 一般为1 , 大家用sql执行的时候应该有发现 62 int result = goodsdao.insertGoods(goodInsertTest); 63 if (result == 1) { 64 System.out.println("插入数据成功"); 65 } else { 66 System.out.println("插入失败"); 67 } 68 } 69 70 public static void deleteGood() { 71 System.out.println("请输入要删除的商品id:"); 72 int id = sc.nextInt(); 73 int result = goodsdao.deleteGoods(id); 74 if (result == 1) { 75 System.out.println("删除数据成功"); 76 } else { 77 System.out.println("不存在您指定id的商品,删除数据失败"); 78 } 79 } 80 81 public static void updateGood() { 82 System.out.println("请输入要更新的商品id:"); 83 int id = sc.nextInt(); 84 Goods isGdExist = goodsdao.findById(id); 85 // 这里直接用对象是否为空判断,摒弃之前用对象的getName()方法进行判断的方式 86 if (isGdExist != null) { 87 System.out.println("请输入商品新名称:"); 88 String name = sc.next(); 89 System.out.println("请输入商品新类型:"); 90 String kind = sc.next(); 91 System.out.println("请输入商品新价格:"); 92 double price = sc.nextDouble(); 93 System.out.println("请输入商品新库存:"); 94 int stock = sc.nextInt(); 95 System.out.println("请输入商品新描述:"); 96 String des = sc.next(); 97 // 生成一个新的商品,此处应该可以优化,但键入全部信息比较方便实现 98 Goods goodUpdateTest = new Goods(name, kind, price, stock, des); 99 int result = goodsdao.updateGoods(id, goodUpdateTest); 100 if (result == 1) { 101 System.out.println("更新数据成功"); 102 } else { 103 System.out.println("更新数据失败"); 104 } 105 } else { 106 System.out.println("不存在您指定id的商品,无法更新数据"); 107 } 108 } 109 110 public static void printAll() { 111 // 定义一个List接受查询结果 112 List<Goods> gdList = goodsdao.findAll(); 113 // 遍历,此处可用增强的for循环 114 for (int i = 0; i < gdList.size(); i++) { 115 System.out.println(gdList.get(i)); 116 } 117 } 118 119 public static void printGoodById() { 120 System.out.println("请输入要查询的商品id:"); 121 int id = sc.nextInt(); 122 // 定义一个对象接受查询返回的结果 123 Goods goodQueryByIdTest = goodsdao.findById(id); 124 // 这里直接用对象是否为空判断,摒弃之前用对象的getName()方法进行判断的方式 125 if (goodQueryByIdTest != null) { 126 System.out.println(goodQueryByIdTest); 127 } else 128 System.out.println("您要查询的商品不存在"); 129 } 130 }
//我改正了里面的一些代码
大家有不清楚可以在群里交流。建议用NetBeans做成图形化界面。