借着大三这次期末课设,我打算对之前学过的JDBC做以复习。
简易通讯录
首先是课设的问题描述:
编写一个简单的通讯录管理程序。通讯录中需要存储姓名,地址,电话号码,邮政编码四项。还可以存储Email,家庭电话等信息。
基本要求:程序应提供的基本管理功能有:
1)添加:即增加一个人的记录到通信录中。
2) 显示:即在屏幕上显示所有通信录中的人员信息。
3)存储:即将通讯录信息保存在数据库表中。
4)查询:可根据姓名查找某人的相关信息,若找到显示其姓名、地址、电话号码和邮政编码。
5)修改:可修改一个人的除姓名外其它信息。
6)排序:可以根据条目的某个项对所有条目进行排序,如姓名,或是邮政编码等。
因为需要用到与MySQL数据库的驱动、连接等一系列操作,所以新建Maven项目:
一定要注意这些目录,需要改成我们现在在用的Maven的,没理由建了一个Maven项目,用的却还是人家IDEA默认提供的东西。
建好后就可以愉快地开始写代码啦,这个小系统需要实现的功能很简单,项目结构如下所示:
在addressBook中,首先需要在控制台呈现进入通讯录的界面,如果确定要使用通讯录功能,就与数据库进行连接,通过每次不同的user和password来登录MySQL客户端,这样不同的客户就可以在各自客户端新建数据库,这里默认提供的是我自己的user和password进行登录,总之,当用户确定要使用通讯口功能时,就应该完成数据库的连接、新建一个表的操作:
//首先需要用户进行登录验证,
// 这里我用我自己的MySQL用户名与密码进行登录。
public void homePageTochoose()
{
System.out.println("欢迎使用通讯录系统,按1进入");
//用户选择"1"后,就加载驱动、连接数据库、执行新建数据库的操作,
Scanner in=new Scanner(System.in);
while (in.hasNextInt())
{
if(in.nextInt()==1) {
try {
JDBCFuction();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
else break;
}
}
//将加载驱动、连接数据库、执行新建数据库的操作,封装在本类中
public void JDBCFuction()
throws ClassNotFoundException,SQLException
{
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//每次都会执行语句,为用户建表mine?
String sql=" create table mine3(name char(20),address char(20), telphone char(11))default charset=utf8";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//用commit结束事务。
connection.commit();
//释放资源
connection.close();
preparedStatement.close();}
public static void main(String[] args)
{
addressBook addressbook=new addressBook();
addressbook.homePageTochoose();
}}
运行主方法,(不知道为什么在单元测试时不能在console中输入"1"),运行
数据库中确实新建了表mine4:
接下来得让用户先添加几个元组到通讯录,以实现之后的显示、查询、修改、排序操作。在主方法中写:
public static void main(String[] args) throws SQLException, ClassNotFoundException {
addressBook addressbook=new addressBook();
addressbook.homePageTochoose();
int choose;
System.out.println("首先需要存储联系人信息,请按照以下格式输入:");
System.out.println("姓名,地址,电话,邮编");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String date=in.nextLine();
if(date.equals("exit")) break;
//获得date后,需要将它作为元组插入到表中
addressbook.insert(date);
System.out.println("已将该信息存入通讯录,如要退出存储请输入‘exit’,否则继续输入联系人信息");
}
//用户可选择除了存储以外的功能
//1chooseFun();
}}
这时修改后的代码了,在这我之前犯了个低级错误,忽视了调用nextLine时,可就直接去读取下一行的数据了。它不是光取了值。 本来是想判断 if(in.nextLine.equals(“exit”) 就退出存储。把它放在前面,后边再用nextLine读数据时,读到的就会是空格了。本憨批写成了这样:
while (in.hasNext())
{ if(in.nextLine().equals("exit")) break;
String date=in.nextLine();
//获得date后,需要将它作为元组插入到表中
addressbook.insert(date);
System.out.println("已将该信息存入通讯录,如要退出存储请输入‘exit’,否则继续输入联系人信息");
}
//用户可选择除了存储以外的功能
//1chooseFun();
}
通过debug才发现了这个问题。
我的insertInto方法是这样实现的:(之所以用占位符,结合setXXX的方式,是因为属性都是char[],对应Java中的String类型,存在" "与’ '各种问题,用占位符结合setXXX更妥一些,能避免错误。)
public void insert(String date) throws ClassNotFoundException, SQLException {
String[] information=date.split(",");
//拼成一个sql语句
String sql="insert into mine7( name,address,telphone,zipcode) values(?,?,?,?)";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
PreparedStatement preparedStatement=connection.prepareStatement(sql);
for(int i=0;i<4;i++)
{ preparedStatement.setString(i+1,information[i]);
}
int res=preparedStatement.executeUpdate();//执行sql语句
if(res>0){
System.out.println("数据录入成功");
}
//事务一定要提交啊!!!
// 否则只是在本地程序OK fine,在数据库中并没有添加元组。
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
}
如果不用占位符,就是这样,已通过测试:
//试试不使用占位符
public void insert(String date) throws ClassNotFoundException, SQLException {
String sql="insert into mine7( name,address,telphone,zipcode) values("+date+");";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
PreparedStatement preparedStatement=connection.prepareStatement(sql);
int res=preparedStatement.executeUpdate();//执行sql语句
if(res>0){
System.out.println("数据录入成功");
}
//事务一定要提交啊!!!
// 否则只是在本地程序OK fine,在数据库中并没有添加元组。
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
}
然后就会发现一个问题,用这种非占位符的,如果我在控制台输入:a,b,c,d,运行结果为:
Exception in thread “main” com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘a’ in ‘field list’ 因为我输入的字母没有带单引号,(数字类型是可以不带单引号的,如果我带了单引号‘a’,‘b’,‘c’)是可以的添加成功的。
而如果是占位符的方式,输入字母时不带单引号也是可以的。怪不得推荐用占位符的方式嘞。
还有要注意的一点,录入信息时逗号必须是英文符号的","才能被split方法分组。
接下来写显示功能,即选择所有元组即可:
public void displayAll()
throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql=" select * from mine7";
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);
while (resultSet.next())
{String name=resultSet.getString(
"name");
String address=resultSet.getString("address");
String telephone=resultSet.getString("telphone");
String zipcode=resultSet.getString("zipcode");
System.out.println("姓名为"+name+",地址为"+address+",电话为"+
telephone+",邮编为"+zipcode);}
//释放资源
connection.close();
statement.close();
resultSet.close();
}
写着写着发现,可能选择了除存储之外的功能,还是有可能调用存储这个功能的(比如人家查询完,又要存新的联系人了,就把insertInto封装到存储storeAll中。)
//用户存储联系人信息。
public void storeAddr() throws SQLException, ClassNotFoundException {
System.out.println("需要存储联系人信息,请按照以下格式输入:");
System.out.println("姓名,地址,电话,邮编");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String date=in.nextLine();
if(date.equals("exit")) break;
//获得date后,需要将它作为元组插入到表中
insert(date);
System.out.println("已将该信息存入通讯录,如要退出存储请输入‘exit’,否则继续输入联系人信息");
}
//存储完毕以后,用户可选择除了存储以外的功能
chooseOtherF();
}
接下来写查询功能,根据姓名查询信息。
public void SearchForName() throws SQLException, ClassNotFoundException {
System.out.println("请输入要查找的姓名:");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String Sname=in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql="select * from mine7 where name = ?";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,Sname);
ResultSet resultSet=preparedStatement.executeQuery();
//这个方法判断是否查到元组可行,下来学习一下,见博客第二种方法
//
if(!resultSet.isBeforeFirst()) System.out.println("查无此人.")
while (resultSet.next())
{String name=resultSet.getString(
"name");
String address=resultSet.getString("address");
String telephone=resultSet.getString("telphone");
String zipcode=resultSet.getString("zipcode");
System.out.println("姓名为"+name+",地址为"+address+",电话为"+
telephone+",邮编为"+zipcode);}
//释放资源
connection.close();
preparedStatement.close();
resultSet.close();
chooseOtherF();}
}
接下来是修改功能,也就是数据的update:
public void alter() throws ClassNotFoundException, SQLException {
System.out.println("请输入要修改的联系人所有信息," +
"请按照以下格式输入:"+
"姓名,地址,电话,邮编");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String Amessage=in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql=" update mine7 set address=?,telphone=?,zipcode=? where name=?";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
String[] Asplit=Amessage.split(",");
preparedStatement.setString(4,Asplit[0]);
preparedStatement.setString(1,Asplit[1]);
preparedStatement.setString(2,Asplit[2]);
preparedStatement.setString(3,Asplit[3]);
int res=preparedStatement.executeUpdate();//执行sql语句
if(res>0){
System.out.println("数据录入成功");
}
//事务一定要提交啊!!!
// 否则只是在本地程序OK fine,在数据库中并没有添加元组。
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
chooseOtherF();
}}
最后是排序,有这么一个发现:
如果在order by查询时加了’ ‘单引号,升序是不会起作用的,而如果没有‘ ’单引号,才是可以正确排序的,所以这里不可以用 PreparedStatement 预编译,因为预编译是会给代替占位符的字符串加上单引号’ '的。一定要注意。
//排序不能用预编译,因为占位符带进去会是'name',而不是name,
//起不到排序的作用
public void sort()throws SQLException,ClassNotFoundException
{
System.out.println("请输入排序依据:1.姓名 2.邮编 3.升序 4.降序;输入格式:1,3");
Scanner in=new Scanner(System.in);
String sql=null1
;
while (in.hasNext())
{String choose=in.nextLine();
String chose[]=choose.split(",");;
if(chose[0].equals("1")&&chose[1].equals("3"))
sql="select * from mine7 order by NAME ASC";
if(chose[0].equals("1")&&chose[1].equals("4"))
sql="select * from mine7 order by NAME DESC";
if(chose[0].equals("2")&&chose[1].equals("3"))
sql="select * from mine7 order by ZIPCODE ASC";
if(chose[0].equals("2")&&chose[1].equals("4"))
sql="select * from mine7 order by ZIPNODE DESC";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/first?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句,默认是降序
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);
while (resultSet.next())
{String name=resultSet.getString(
"name");
String address=resultSet.getString("address");
String telephone=resultSet.getString("telphone");
String zipcode=resultSet.getString("zipcode");
System.out.println("姓名为"+name+",地址为"+address+",电话为"+
telephone+",邮编为"+zipcode);}
//释放资源
connection.close();
statement.close();
resultSet.close();
chooseOtherF();}}
整个小系统就完成了,运行效果如下:
产品销售子系统
问题描述
编写一个简单的产品销售管理子系统,包括产品与顾客的基本信息管理、订货、产品销售后的查询和统计功能。顾客信息包括顾客号、顾客名、地址、电话、信贷状况、预付款等信息。顾客订购产品由订单反映,每张订单包括订单号、订购项数、订购日期、订货产品号、数量等基本信息。产品由产品号、产品名、单价、数量等组成。
程序应提供的基本管理功能有:
1)产品信息的基本管理(添加、修改、删除)。
2) 客户信息的基本管理(添加、修改、删除)
3)下订单:一个顾客可以完成多个订单,但一个订单只针对一个顾客。
4)查询订单:可根据顾客号查找订单信息。
5)查询库存:可根据产品号查询产品的库存信息。
6)统计:统计不同顾客的订购不同产品的数量和总金额。
这个小系统其实和上一个差别不大,只是在实现最后一个功能时,我发现在MySQL中写乘法并不方便,所以分步,把查询的结果先存在数组中,后续再进行乘法运算,整个代码如下:
package main;
import java.sql.*;
import java.util.Scanner;
public class ProductSales {
//刚进入子系统需要选择产品or客户模块
public void homePageTochoose() throws SQLException, ClassNotFoundException {
System.out.println("选择功能 1:产品信息管理 2.客户信息管理 3.下订单 4.查询订单 5.查询库存 6.统计");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String choose = in.nextLine();
if (choose.equals("1")) turnToProduct();
if (choose.equals("2")) turnToClient();
if (choose.equals("3")) Ordering();
if (choose.equals("4")) SearchForO();
if(choose.equals("5")) SearchForN();
if(choose.equals("6")) {
statisticsAmount();
}
}
}
//产品信息管理
public void turnToProduct() throws SQLException, ClassNotFoundException {
Scanner in = new Scanner(System.in);
System.out.println("选择功能: 1.添加 2.修改 3.删除");
String choose = in.nextLine();
if (choose.equals("1")) insertPro();
if (choose.equals("2")) alterPro();
if (choose.equals("3")) deletePro();
homePageTochoose();
}
//客户信息管理
public void turnToClient() throws SQLException, ClassNotFoundException {
Scanner in = new Scanner(System.in);
System.out.println("选择功能: 1.添加 2.修改 3.删除");
String choose = in.nextLine();
if (choose.equals("1")) insertCli();
if (choose.equals("2")) alterCli();
if (choose.equals("3")) deleteCli();
homePageTochoose();
}
//产品模块,添加元组功能
public void insertPro() throws SQLException, ClassNotFoundException {
//首先需要建表
try {
createProduct();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//接下来插入元组
System.out.println("添加产品信息,请按照以下格式输入:");
System.out.println("产品号,产品名,单价,数量");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String date = in.nextLine();
if (date.equals("exit")) break;
//获得date后,需要将它作为元组插入到表中
try {
insertIntoP(date);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("已将该产品信息存入,如要退出存储请输入‘exit’,否则继续添加产品信息");
}
//存储完毕以后,用户可选择除了存储以外的功能
homePageTochoose();
}
public void insertIntoP(String date) throws ClassNotFoundException, SQLException {
String[] information = date.split(",");
//拼成一个sql语句
String sql = "insert into product(ID,name,unitPiece,amount) values(?,?,?,?)";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, Integer.parseInt(information[0]));
preparedStatement.setString(2, information[1]);
preparedStatement.setDouble(3, Double.parseDouble(information[2]));
preparedStatement.setInt(4, Integer.parseInt(information[3]));
int res = preparedStatement.executeUpdate();//执行sql语句
if (res > 0) {
System.out.println("数据录入成功");
}
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
}
//建表product
public void createProduct() throws SQLException, ClassNotFoundException {// 通过用户名与密码连接数据库
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接,题目一用的是first数据库,本题用的是second数据库。
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//建表product
//属性:产品号、产品名、单价、数量。
String sql = " create table if not exists product (ID int,name char(20), unitPiece double ,amount int)default charset=utf8";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//用commit结束事务。
connection.commit();
//释放资源
connection.close();
preparedStatement.close();
}
//修改产品信息
public void alterPro() throws SQLException, ClassNotFoundException {
System.out.println("根据产品号修改产品的其他信息," +
"请按照以下格式输入:" +
"产品号,产品名,单价,数量");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String Amessage = in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql = " update product set name=?,unitPiece=?,amount=? where ID=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
String[] Asplit = Amessage.split(",");
preparedStatement.setInt(4, Integer.parseInt(Asplit[0]));
preparedStatement.setString(1, Asplit[1]);
preparedStatement.setDouble(2, Double.parseDouble(Asplit[2]));
preparedStatement.setInt(3, Integer.parseInt(Asplit[3]));
int res = preparedStatement.executeUpdate();//执行sql语句
if (res > 0) {
System.out.println("数据录入成功");
}
//事务一定要提交啊!!!
// 否则只是在本地程序OK fine,在数据库中并没有添加元组。
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
homePageTochoose();
}
}
//删除产品信息
public void deletePro() throws SQLException, ClassNotFoundException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql = " delete from product where ID = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("请输入删除产品的ID:");
Scanner in = new Scanner(System.in);
preparedStatement.setInt(1, Integer.parseInt(in.nextLine()));
int res = preparedStatement.executeUpdate();
//提交事务
connection.commit();
if (res > 0) System.out.println("删除成功");
//关闭资源
connection.close();
preparedStatement.close();
}
//选择了客户模块的添加功能
public void insertCli() throws SQLException, ClassNotFoundException { //首先需要建表
try {
createClient();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//接下来插入元组
System.out.println("添加客户信息,请按照以下格式输入:");
System.out.println("顾客号,顾客名,地,电话,信贷状况,预付款");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String date = in.nextLine();
if (date.equals("exit")) break;
//获得date后,需要将它作为元组插入到表中
try {
insertIntoC(date);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("已将该客户信息存入,如要退出存储请输入‘exit’,否则继续添加客户信息");
}
//存储完毕以后,用户可选择除了存储以外的功能
homePageTochoose();
}
//建表client
public void createClient() throws SQLException, ClassNotFoundException {// 通过用户名与密码连接数据库
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接,题目一用的是first数据库,本题用的是second数据库。
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//建表product
//属性:顾客号,顾客名,地址,电话,信贷状况,预付款
String sql = " create table if not exists client(ID int,name char(20),address char(20) ,telephone char(11),credit char(10),prepay char(20))default charset=utf8";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//用commit结束事务。
connection.commit();
//释放资源
connection.close();
preparedStatement.close();
}
//将元组插入clinet表中
public void insertIntoC(String date) throws ClassNotFoundException, SQLException {
String[] information = date.split(",");
//拼成一个sql语句
String sql = "insert into client(ID,name,address,telephone,credit,prepay) values(?,?,?,?,?,?)";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, Integer.parseInt(information[0]));
for (int i = 2; i < 7; i++) {
preparedStatement.setString(i, information[i - 1]);
}
int res = preparedStatement.executeUpdate();//执行sql语句
if (res > 0) {
System.out.println("数据录入成功");
}
connection.commit();
connection.close();
preparedStatement.close();
}
//修改客户信息
public void alterCli() throws SQLException, ClassNotFoundException {
System.out.println("根据顾客号修改产品的其他信息," +
"请按照以下格式输入:" +
"顾客号,顾客名,地,电话,信贷状况,预付款");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String Amessage = in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
//ID,name,address,telephone,credit,prepay
String sql = " update client set name=?,address=?,telephone=?,credit=?,prepay=? where ID=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
String[] Asplit = Amessage.split(",");
preparedStatement.setInt(6, Integer.parseInt(Asplit[0]));
for (int i = 1; i < 6; i++) {
preparedStatement.setString(i, Asplit[i]);
}
int res = preparedStatement.executeUpdate();//执行sql语句
if (res > 0) {
System.out.println("数据录入成功");
}
connection.commit();
connection.close();
preparedStatement.close();
homePageTochoose();
}
}
//删除客户信息
public void deleteCli() throws SQLException, ClassNotFoundException { //加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql = " delete from client where ID = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("请输入删除顾客的ID:");
Scanner in = new Scanner(System.in);
preparedStatement.setInt(1, Integer.parseInt(in.nextLine()));
int res = preparedStatement.executeUpdate();
//提交事务
connection.commit();
if (res > 0) System.out.println("删除成功");
//关闭资源
connection.close();
preparedStatement.close();
}
//下订单
public void Ordering() throws SQLException, ClassNotFoundException {
//首先需要建theOrder表
createOrder();
System.out.println("即将生成订单,请输入订单信息(订单号将自动生成)");
System.out.println("输入格式为:顾客ID,订购项数,订购日期(XXXX-XX-XX),订货产品号,数量");
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String theOrder = in.nextLine();
if (theOrder.equals("exit")) homePageTochoose();
//获得theOrder后,需要将它作为元组插入到表中
try {
insertIntoO(theOrder);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("已生成订单,如要退出下单请输入‘exit’,否则继续生成新订单");
}
}
//建theOrder订单表
public void createOrder() throws SQLException, ClassNotFoundException {
// 通过用户名与密码连接数据库
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接,题目一用的是first数据库,本题用的是second数据库。
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
//建表product
//属性:订单号、顾客ID、订购项数、订购日期、订货产品号、数量。
String sql = " create table if not exists theOrder(ID int primary key auto_increment,clientID int,number int,orderDate date,productID int,amount int)default charset=utf8";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate();
//用commit结束事务。
connection.commit();
//释放资源
connection.close();
preparedStatement.close();
}
//将元组插入订单表
public void insertIntoO(String theOrders) throws SQLException, ClassNotFoundException {
String[] information = theOrders.split(",");
//拼成一个sql语句
String sql = "insert into theOrder(clientID,number,orderDate,productID,amount) values(?,?,?,?,?)";
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false", "root", "jdpy1229jiajia");
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, Integer.parseInt(information[0]));
preparedStatement.setInt(2, Integer.parseInt(information[1]));
preparedStatement.setDate(3, Date.valueOf(information[2]));
preparedStatement.setInt(4, Integer.parseInt(information[3]));
preparedStatement.setInt(5, Integer.parseInt(information[4]));
int res = preparedStatement.executeUpdate();//执行sql语句
if (res > 0) {
System.out.println("数据录入成功");
}
connection.commit();
//关闭资源
connection.close();
preparedStatement.close();
}
//查询订单
public void SearchForO()throws SQLException,ClassNotFoundException
{
System.out.println("请输入要查找的顾客ID:");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String cID=in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句
String sql="select * from theOrder where clientID = ?";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,cID);
ResultSet resultSet=preparedStatement.executeQuery();
if(!resultSet.isBeforeFirst()) System.out.println("查无此订单.");
//| ID | clientID | number | orderDate | productID | amount
while (resultSet.next())
{int ID=resultSet.getInt("ID");
int clientID=resultSet.getInt("clientID");
int number=resultSet.getInt("number");
java.util.Date orderDate =resultSet.getDate("orderDate");
int productID=resultSet.getInt("productID");
int amount=resultSet.getInt("amount");
System.out.println("顾客ID为"+clientID+"订单ID为"+ID+",订购了"+number+"项产品,订购日期为"+orderDate+",产品"+
productID+",数量为"+amount+"个");}
//释放资源
connection.close();
preparedStatement.close();
resultSet.close();
homePageTochoose();}}
//查询库存
//查询订单
public void SearchForN()throws SQLException,ClassNotFoundException
{
System.out.println("请输入要查找的产品ID:");
Scanner in=new Scanner(System.in);
while (in.hasNext())
{String pID=in.nextLine();
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
//执行SQL语句,用产品入库即建product表后的值减去订单中该产品的总数量
String sql=" select((select product.amount as s2)-(select sum(theorder.amount) as s1 from theorder where productID=?)) as inventory from product where ID=?;";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.setInt(1,Integer.parseInt(pID));
preparedStatement.setInt(2,Integer.parseInt(pID));
ResultSet resultSet=preparedStatement.executeQuery();
if(!resultSet.isBeforeFirst()) System.out.println("查无此订单.");
while (resultSet.next())
{int inventory=resultSet.getInt("inventory");
System.out.println("库存为"+inventory);}
//释放资源
connection.close();
preparedStatement.close();
resultSet.close();
homePageTochoose();}}
//统计,根据顾客ID统计其订购的不同产品的数量和总金额
//可以通过group函数求得不同产品的数量
//但是总金额不好求,分开求解
public void statisticsAmount()throws SQLException,ClassNotFoundException
{
System.out.println("请输入需要统计的顾客ID:");
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
Connection connection=DriverManager.getConnection
("jdbc:mysql://localhost:3306/second?useSSL=false","root","jdpy1229jiajia");
connection.setAutoCommit(false);
Scanner in=new Scanner(System.in);
String CID=in.nextLine();
//执行SQL语句
String sql=" select productID,sum(amount) as totalAmount from theorder where clientID=? group by productID;";
PreparedStatement preparedStatement=connection.prepareStatement(sql);
preparedStatement.setInt(1,Integer.parseInt(CID));
ResultSet resultSet=preparedStatement.executeQuery();
int[] totalAmount=new int[10];
int[] proID=new int[10];
int i=0;
//这回不是直接输出了,把产品总数存在数组中,
while (resultSet.next()) {
proID[i]=resultSet.getInt("productID");
totalAmount[i]=resultSet.getInt("totalAmount");
i++; }
//在执行第二个查询,把产品单价放在数组中
sql="select distinct product.ID,unitPiece from product,theorder where product.ID=theorder.productID and theorder.clientID=?";
preparedStatement=connection.prepareStatement(sql);
preparedStatement.setInt(1,Integer.parseInt(CID));
resultSet=preparedStatement.executeQuery();
int[] unitPiece=new int[10];
int j=0;
while (resultSet.next())
{unitPiece[j]=resultSet.getInt("unitPiece");
j++;}
/* while (resultSet.next()) {
int productID = resultSet.getInt("productID");
int totalAmount = resultSet.getInt("totalAmount");
System.out.println("该顾客订购的产品,产品ID为"+productID+",总数为"+totalAmount);
}*/
for(int k=0;k<i;k++)
{
System.out.println("该顾客订购的产品,产品ID为"+proID[k]+",总数为"+totalAmount[k]+",总金额为"+(unitPiece[k]*totalAmount[k]));
}
//释放资源
connection.close();
preparedStatement.close();
resultSet.close();
homePageTochoose();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException {
ProductSales productSales=new ProductSales();
productSales.homePageTochoose();
}
}
留给后续研究的:
1.commit()与rollback(),哪时候用哪个?
有一次我写insert子句没有commit ,然后本地控制台执行成功,但是数据库的表并没有添加元组。无语(ˉ▽ˉ;)…。
2.为什么要用“?useSSL=false“
3.我有一个问题,如果用select查找元组,查不到时,这时为什么不能用resultSet==null来判断,这篇博客中的方法一,为什么不能再跳回第一行呢??? 方法二可棒,优秀。
反思与总结
如此功能简单的小系统居然也要花掉将近一天时间,我爬了,不知道以后工作做高并发项目,是不是因为总要耗着时间和体力。 这两个小系统欠缺的东西还很多,比如无可视化界面(何时能够拿下前端三把斧QAQ),再有我都是throws向上一层也就是main方法抛出异常,并没有着手处理它们,那么用户每次遇到如输入格式有误的问题,都得重新进入方法,而且封装得也不彻底,比如每次的连接、statement、关闭资源没有封装(因为我不知道怎么整才能让关闭资源的close方法在查询或更新后被调用??? 是整个静态方法吗,隐约记得属性文件的配置应当放在静态代码块里。) 收获是这是自己第一个一步一步debug、unit test出来的小系统,我对prepareStatement有了更深的理解,怪不得涉及SQL注入等问题需要用它,而且JDBC操作与SQL语句的掌握是密不可分的,比如那个求总金额的(好像SQL没有乘法,得自己写函数),写不出来SQL语句就只能用笨方法,再说增删改查可简单可复杂,学Java怎么能不熟练运用SQL语句,搞数据库呢?不应当,这方面有待提高。希望后续搞小系统时能用上设计模式等思想,更高效,更优雅。