《Java技术》第八次作业
(一)学习总结
1.
2.通过实验内容中的具体实例说明在执行executeUpdate()方法和executeQuery()方法中使用动态参数时,为什么要使用PreparedStatement接口而不使用Statement,比较使用两种接口的不同之处。
如下代码:Statement stmt = null;ResultSet rs = null;ArrayListlist = new ArrayList ();try{ conn = JDBCUtils.getConnection(1,"PetStore"); stmt = conn.createStatement(); String sql = "select number,pet,variety,color,age,price from pet"; rs = stmt.executeQuery(sql); while(rs.next()){ PetItem thisPet = new PetItem(); thisPet.setNumber(rs.getString("number")); thisPet.setPet(rs.getString("pet")); thisPet.setVariety(rs.getString("variety")); thisPet.setColor(rs.getString("color")); thisPet.setAge(rs.getString("age")); thisPet.setPrice(rs.getDouble("price")); list.add(thisPet); } return list;}catch(Exception e ){ e.printStackTrace();}finally{ JDBCUtils.close(conn);}return result;
这段代码中的executeQuery()使用的是Statement接口,而后边这段代码:
Connection conn = null;PreparedStatement pstmt = null; boolean result=false;try{ conn = JDBCUtils.getConnection(1,"PetStore"); String sql = "insert into pet (number,pet,variety,color,age,price) values (?,?,?,?,?,?)"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, Pet.getNumber()); pstmt.setString(2,Pet.getPet()); pstmt.setString(3,Pet.getVariety()); pstmt.setString(4,Pet.getColor()); pstmt.setString(5,Pet.getAge()); pstmt.setDouble(6,Pet.getPrice()); int num = pstmt.executeUpdate(); if(num > 0){ result = true; } }catch(Exception e ){ e.printStackTrace();}finally{ JDBCUtils.close(conn);}return result;
则使用的是PreparedStatement接口。PreparedStatement是Statement接口的一个子接口,其中executeUpdate()方法和executeQuery()在PreparedStatement接口中是在预处理之后执行的,需要对sql语句中的"?"进行设置,而Statement接口则不会对"?"进行设置,若使用Statement接口的executeUpdata()方法执行一条包含"?"的sql语句,会提示"?"附近有语法错误,出现异常。
3.(1)连接数据库时,在添加了登录名后,一定要右键数据库服务器,重新启动,否则测试不会成功。
(2)"set rowcount 1"写在查询语句之前,只会影响一行,若不写或写成"set rowcount 0"则会影响全部数据。(二)实验总结
实验内容:
使用JDBC实现实验七的宠物商店 完成实验内容,代码上传到码云,注意,务必将创建数据库的脚本文件随项目文件一起上传,在随笔中分析程序设计思路,用PowerDesigner画出类图结构,并对完成实验内容过程中遇到的问题、解决方案和思考等进行归纳总结,注意代码中必须有必要的注释。程序设计思路:
大体思路与实验七相同,主要说一说不同和需要改动的地方。 将data包(用来记录用户信息、商品信息和购买商品信息)删除。 dbc: 新添加的包,包含一个类JDBCUtils,用来连接数据库和关闭数据库,包含三个方法:Connection型的getConnection方法,用来判断使用者是Sql Server或MySql(因为本题要求使用Sql Server,所以没有用到关于MySql的方法),调用Connection型的getConnectionSQL方法,用来连接并打开数据库。close方法,用来关闭数据库。items:
修改了PetBought类和UserItem类。UserItem类中不再有关于PetBought类的构造方法,而PetBought类中添加一个String类型的"name"变量,用来记录当前操作的用户名。functions:
其中AdminService类没有改变,在添加和修改方法中,先通过传入的参数初始化为PetItem类(记录商品信息)的对象,调用dao中的ChangeData相应地添加和删除方法即可。 修改LoginJudge类(用来判断登录信息),通过登录界面传入用户名和密码,打开数据库PetStoreUser(用户信息),使用sql语句"select name,passwords from users",使用ResultSet接口接收结果,使用循环,添加到UserItem的一个对象中,使用迭代器对该对象进行检索,判断用户名和密码是否一致,一致则返回true登录成功,否则返回false登录失败,若未检索到用户名,则返回false登录失败。 修改CheckRegister类(用来判断注册信息),与LoginJudge类代码类似,只不过最后使用迭代器判断如果有相同的用户名则返回false注册失败,否则声明UserItem类的对象,并将该对象使用Register类中的register方法进行注册(将信息添加进数据库)。 可以说是把BuyService类整个重写了,用来实现商品的购买、删除和计算价格。首先是queryPetItem类,用来返回所有商品,打开数据库PetStore(商品信息),使用sql语句"select number,pet,variety,color,age,price from pet",使用ResultSet接口的变量接收结果,并构造为一个PetItem类的对象。 其次是queryPetBought,用来返回所有已购买到的商品,打开数据库PetBought(已购买到的商品信息),使用sql语句"select name,number,pet,variety,color,age,price from petbought",使用ResultSet接口的变量接收结果,并构造为一个PetBought类的对象。 buyPetItem类,为当前用户购买该编号的商品,通过queryPetItem类返回的全部商品信息,对该编号进行查找,将该编号的商品信息传入到dao中ChangeBuy类的buyPetBought方法进行添加,返回true则返回true购买成功,返回false则返回false购买失败。 delPetBought类,删除一个购买到的商品,将用户名和删除的编号使用ChangeBuy类的delPetBought方法即可。 sumPrice类,将当前用户名的所有商品进行合计,打开数据库PetBought,使用sql语句"select name,price from petbought where name= ?",使用PreparedStatement接口中的setString将用户名进行设置,并将返回结果使用ResultSet接口进行接收,使用getString将关键字为"price"的数据进行求和运算,将结果返回。dao:
修改ChangeData类(用来实现管理员对商品的添加和删除)。首先是queryAllData方法(展示所有商品),为了实现其功能,打开数据库PetStore(商品信息),输入sql语句"select number,pet,variety,color,age,price from pet",然后用Statement接口的executeQuery方法返回结果,用ResultSet接口接收结果,并将结果使用PetItem类(记录商品信息)的set方法记录,使用while循环将所有的结果都记录后,返回该对象。其次是addPetItem方法(添加商品),打开数据库PetItem,输入sql语句"insert into pet (number,pet,variety,color,age,price) values (?,?,?,?,?,?)",并使用PreparedStatement接口,按"?"的顺序输入通过AdminService方法传入的PetItem对象。最后是delPetItem方法(删除商品),打开数据库PetItem,输入sql语句"delete from pet where number=?","?"使用PreparedStatement的setString方法,将AdminService传入的序号输入,进行删除。 修改Register类(注册),将CheckRegister类传入的UserItem类(用户信息)的对象写入数据库,打开数据库PetStoreUser(用户信息),使用sql语句"insert into users (name,passwords) values (?,?)",使用PreparedStatement接口的setString方法依次将该对象中的数据设置内容。最后返回true则注册成功,返回false注册失败。 修改ChangeBuy类。首先是buyPetBought类(添加购买到的商品),打开数据库PetBought(购买到的商品信息),使用sql语句 "insert into petbought (name,number,pet,variety,color,age,price) values (?,?,?,?,?,?,?)",将BuyService类传入的PetBought对象(用来记录购买的商品信息)的内容,使用PreparedStatement接口setString方法依次设置。最后是delPetBought类(删除购买到的商品),打开数据库PetBought,使用sql语句"set rowcount 1 delete from petbought where number= ? and name= ?"进行删除,条件是"name"和"number"必须和传入的参数相同,即要删除的序号和当前用户名。实验问题分析:
问题1:将一个已购买的商品删除,相同编号的所有商品都会被删除 原因:数据库语句"delete"会在执行时删除全部符合条件的数据删除。 解决方案:我的PetBought(已购买的商品)数据库中没有设置主键,从而可以允许添加多个重复的数据,而使用delete语句将会把所有符合条件的数据删除,即删除一个数据,全部重复的数据将都会被删除。在sql语句中"delete"前加上一条语句"set rowcount 1"即可,该语句为每次只影响 1 行数据。 问题2:XXXXXXX 原因:XXXXXXX 解决方案:XXXXXXX
(三)
- 码云commit历史截图