书籍,出版社管理系统
1、需求
创建两个表,实现出版社和书籍管理,要求如下
publisher: id name(唯一) address
book: id isbn name publisher_id
要求:欢迎进入书籍管理系统
1、出版社管理:增、删(name)、改(name)、查(name)
2、书籍管理:增、删(name)、改(name)、查(name)
3、退出
根据要求创建如下两个表:
create table publisher(
id char(36) primary key comment '出版社id',
name varchar(24) unique comment '名字',
address varchar(120) comment '地址'
)
create table book(
id char(36) primary key comment '读书id',
isbn varchar(12) unique comment '标准图书编号',
name varchar(24) comment '读书名称',
publisher_id char(36) comment '出版社地址,外键'
foreign key(publisher_id) references publisher(id)
)
2、log4j.properties
当代码出现异常时,我们需要知道异常信息在哪里,java中获取异常的方法(printStackTrace();)会将异常信息存储到堆和栈中,而堆栈中存在的异常信息会溢出,导致最前边的异常信息不存在,信息不完整,不利于我们后期参照修改代码。所以我们考虑在src根目录配置log4j.properties文件,将异常信息输出到文件中,建议异常信息间隔输出为不同的文件。
位置如下图片
用三种情况说明log4j.properties 怎么使用(单独试)。
package hhhh;
import org.apache.log4j.Logger;
public class Test {
public static void main(String[] args) {
//1,
//System.out.println(1/0); //只有这一条异常信息。
//2,
// while(true){ //假设异常信息较多时
// try {
// System.out.println(1/0);
// }catch(Exception e){
// System.out.println(i);
// e.printStackTrace();
// }
// } //用此死循环 ,堆和栈不会满,因为存在更新信息。之前的信息没有了。
//3,
//log4j的使用:1,配置jar包。2,创建log4j文件
// Logger logger=Logger.getLogger(Test.class); //创建连接
// while(true) {
// try {
// System.out.println(1/0);
// }catch(Exception e){
// logger.debug(e.getMessage(),e); //捕捉异常信息,将异常信息打印到堆栈。
// }
// }
}
}
3、db.properties
配置信息(配置db.properties 文件)的目的:方便后期管理,因为有些信息后期会修改,编译后的class文件是不能被修改的,所以将一些可变信息(例如:数据库连接配置url,用户明和密码)配置到一个扩展名为properties的文件中(此文件位置在src根目录),其中的内容类似于key=values(这些values在properties中是可以被修改的),可以构造方法将配置文件中的信息获得。
// db.properties 文件
url=jdbc:mysql://127.0.0.1:3306/keeper //0,先将需要更改的信息配置到一个文件中
user_name=root
password=root
// DBUtil类中的连接方法
public static Connection getConnection(){
try {
PropertiesUtil util=new PropertiesUtil(); //1,获取连接时,创建PropertiesUtil 对象;
String url=util.getValue("url"); //2,调用getValue方法得到key=value中的value
String userName=util.getValue("user_name");
String password=util.getValue("password");
return DriverManager.getConnection(url, userName, password); //7,创建连接
} catch (Exception e) {
logger.debug(e.getMessage(),e);
}
return null;
}
//PropertiesUtil 类
package com.jd.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 配置工具类
*
* @author Administrator
*/
public class PropertiesUtil {
public static Properties properties=new Properties(); //3,创建一个properties 对象,properties继承自Hashtable,Hashtable实现了Map接口
static { //4,静态代码块加载在前,获取连接时用到了URL;user_name;password
InputStream inputStream=PropertiesUtil.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(inputStream);//将properties中的key=values变为Map集合中的键值对(放在静态代码块中,)。
} catch (IOException e) {
e.printStackTrace();
}
}
public String getValue(String key) { //5,定义一个获取值的方法,到DBUti类中,因为连接时用到,所以将获取方法写在连接方法中。
return properties.getProperty(key); //6,调用此方法得到的是key=value中的value
}
}
4、PropertiesUtil
package com.jd.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 配置工具类
*
* @author Administrator
*/
public class PropertiesUtil {
public static Properties properties=new Properties();
static { //静态代码块加载在前,获取连接时用到了URL;user_name;password
InputStream inputStream=PropertiesUtil.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(inputStream);//将properties中的key=values变为Map集合中的键值对(放在静态代码块中,)。
} catch (IOException e) {
e.printStackTrace();
}
}
public String getValue(String key) { //定义一个获取值的方法,到DBUti类中,
return properties.getProperty(key); //调用此方法得到的是key=value中的value
}
}
5、DBUtil
package com.jd.util;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import com.jd.test.Test;
/**
* 工具类
*
* @author Administrator
*/
public class DBUtil {
private static Logger logger=Logger.getLogger(DBUtil.class); //定义异常之后将异常信息输出,将e.printStackTrace();改为logger.debug(e.getMessage(),e);
static { //静态代码块,只在类加载时执行一次。
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
logger.debug(e.getMessage(),e);
}
}
/**
* 获取连接,
*
* @author Administrator
*/
public static Connection getConnection(){
try {
PropertiesUtil util=new PropertiesUtil();
String url=util.getValue("url"); //调用getValue方法得到key=value中的value
String userName=util.getValue("user_name");
String password=util.getValue("password");
return DriverManager.getConnection(url, userName, password);
} catch (Exception e) {
logger.debug(e.getMessage(),e);
}
return null;
}
/**
* 查询是否存在方法
*
* @author Administrator
*/
public static boolean exist(String sql){
class RowMapper implements IRowMapper{
boolean state;
public void rowMapper(ResultSet st) {
try {
if(st.next()) { //判断是否存在
state=true;
}
} catch (SQLException e) {
logger.debug(e.getMessage(),e);
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql, rowMapper);
return rowMapper.state;
}
/**
* 查询方法(防注入)
*
* @author Administrator
*/
public static void query(String sql,IRowMapper rowMapper,Object...params) { //使用动态参数,因为不知道问号是几个。
Connection connection=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
connection=getConnection();
preparedStatement=connection.prepareStatement(sql);
for(int i=1;i<=params.length;i++) {
preparedStatement.setObject(i,params[i-1]);
}
resultSet=preparedStatement.executeQuery(); //查询后的语句存储到了ResultSet类中
rowMapper.rowMapper(resultSet); //方法不是在本类中,需要用一个类名去调用方法,又输出语句在main方法中,所以创建一个内部类,实现接口,重写接口中的遍历方法。
} catch (Exception e) {
logger.debug(e.getMessage(),e);
}finally {
close(resultSet,preparedStatement,connection);
}
}
/**
* 增删改方法(防注入)
*
* @author Administrator
*/
public static boolean update(String sql,Object...params) {
Connection connection=null;
PreparedStatement preparedStatement=null;
try {
connection=getConnection();
preparedStatement=connection.prepareStatement(sql);
for(int i=1;i<=params.length;i++) { //i是动态的,由传入的参数决定。
preparedStatement.setObject(i,params[i-1]);
}
return preparedStatement.executeUpdate()>0;
} catch (Exception e) {
logger.debug(e.getMessage(),e);
}finally {
close(preparedStatement,connection);
}
return false;
}
/**
* 释放资源
*
* @author Administrator
*/
public static void close(PreparedStatement preparedStatement,Connection connection) {
try {
if(preparedStatement!=null) {
preparedStatement.close();
}
} catch (SQLException e) {
logger.debug(e.getMessage(),e);
}
try {
if(connection!=null) {
connection.close();
}
} catch (SQLException e) {
logger.debug(e.getMessage(),e);
}
}
/**
* 释放资源
*
* @author Administrator
*/
public static void close(ResultSet resultSet,PreparedStatement preparedStatement,Connection connection) {
try {
if(resultSet!=null) {
resultSet.close();
}
} catch (SQLException e) {
logger.debug(e.getMessage(),e);
}
close(preparedStatement,connection);
}
}
6、IRowMapper
package com.jd.util;
import java.sql.ResultSet;
public interface IRowMapper {
void rowMapper(ResultSet resultSet);
}
7、PublisherManager
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import org.omg.Messaging.SyncScopeHelper;
import util.StringUtil;
public class P{
/**
*
* @author Administrator
*
* 根据name返回id方法
* @param name
* @return
*/
private static boolean exist(String name) {
String sql="select id,name,address from publisher where name=?";
class RowMapper implements IRowMapper{
boolean state;
@Override
public void rowMapper(ResultSet rs) {
try {
if(rs.next()) {
state=true;
//System.out.println("出版社名称重复");
//return;//此处不用return是因为,return结束当前方法,只会结束掉rowMapper方法,所以程序总会执行添加地址的代码,不符合我们的要求。
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql,rowMapper,name);
return rowMapper.state; //此处直接返回state的结果。
} //重构上边方法,因为根据name返回id,表示一定存在。
/**
*
* @author Administrator
*
* 对存在方法重构,根据id存在来判断出版社存在
* @param name
* @return
*/
public static boolean exit(String name) {
if(getId(name)!=null) {
return true;
}
return false;
}
/**
*
* @author Administrator
*
* 根据name获取id
* @param name
* @return
*/
public static String getId(String name) { //获取id方法
String sql="select id,name,address from publisher where name=?";
class RowMapper implements IRowMapper{
String id;
@Override
public void rowMapper(ResultSet rs) {
try {
if(rs.next()) {
id=rs.getString("id");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql,rowMapper,name);
return rowMapper.id;
}
public static void main(String[] args) {
while(true) {
menu();
}
}
/**
*
* @author Administrator
*
* 添加出版社信息
*/
public static void insert() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入您要添加的出版社名称");
String name=scanner.next();
if(exist(name)) { //如果if条件成立,即exist(name)返回true。
System.out.println("出版社名称不能重复");
return;
}
System.out.println("请输入要添加出版社的地址");
String address=scanner.next();
String sql="insert into publisher (id,name,address) values (?,?,?)";
if(DBUtil.update(sql, StringUtil.getId(),name,address)) {
System.out.println("添加成功");
return;
}
System.out.println("系统错误,添加失败");
}
/**
*
* @author Administrator
*
* 删除出版社信息
*/
public static void delete(){
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要删除的出版社名称");
String name=scanner.next();
String sql="delete from publisher where name=?";
//因为我们调用的是我们自己构造的方法,不是HashMap中的方法,所以要判断是否存在。
if(exist(name)) {
if(DBUtil.update(sql,name)) { //此处动态参数是传入的参数的个数。
System.out.println("删除成功");
return;
}
System.out.println("系统错误,删除失败");
return;
}
System.out.println("不存在该出版社");
}
/**
*
* @author Administrator
*
* 修改出版社信息
*/
public static void update() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要修改的出版社名称");
String name=scanner.next();
String id=getId(name);
if(getId(name)!=null) {
System.out.println("请输入新的名称");
name=scanner.next(); //要将名称也改为新的,不然会出现不唯一,因为name设定值为是unique。
System.out.println("请输入新的地址");
String address=scanner.next();
String sql="update publisher set name=?,address=? where id=? ";
if(DBUtil.update(sql,name,address,id)) {
System.out.println("修改成功");
return;
}
System.out.println("系统错误!");
return;
}
System.out.println("不存在这个出版社");
}
/**
*
* @author Administrator
*
* 查询出版社信息
*/
public static void query() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要查询的出版社名称");
String name=scanner.next();
String sql="select id,name,address from publisher where name=?";
class RowMapper implements IRowMapper{
@Override
public void rowMapper(ResultSet rs) {
try {
if(rs.next()) {
String id=rs.getString("id");
String name=rs.getString("name");
String address=rs.getString("address");
System.out.println(id+";"+name+";"+address);
}else {
System.out.println("不存在该出版社!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql,rowMapper,name);
}
public static void menu() {
System.out.println("*\t欢迎来到出版社管理系统\t*");
System.out.println("请输入您要执行的操作,按enter键结束");
System.out.println("1,添加");
System.out.println("2,删除");
System.out.println("3,修改");
System.out.println("4,查询");
Scanner scanner=new Scanner(System.in);
int option=scanner.nextInt();
switch(option) {
case 1: //添加
insert();
break;
case 2://删除
delete();
break;
case 3: //修改
update();
break;
case 4: //查询
query();
break;
default :
System.out.println("没有该项操作");
}
}
}
8、BookManager
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
import util.StringUtil;
public class B {
/**
*
* @author Administrator
*
* 跟据isbn 判断书籍是否存在
* @param isbn
* @return
*/
public static boolean exit(String isbn) { //判断是否存在
String sql="select id,name,isbn,publisher_id from book where isbn=?";
class RowMapper implements IRowMapper{
boolean state;
@Override
public void rowMapper(ResultSet rs) {
try {
if(rs.next()) {
state=true;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql, rowMapper, isbn);
return rowMapper.state;
}
/**
*
* @author Administrator
*
* 跟据name获取id方法
* @param name
* @return
*/
public static String getId(String name) { //获取id方法,在publisherManager中有复用,所以可以调用publisherManager类中的,不用在这里重写。
String sql="select id,name,address from publisher where name=?";
class RowMapper implements IRowMapper{
String id;
@Override
public void rowMapper(ResultSet rs) {
try {
if(rs.next()) {
id=rs.getString("id");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql,rowMapper,name);
return rowMapper.id;
}
/**
*
* @author Administrator
*
* 根据isbn添加书籍方法
*/
public static void insert() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要添加的书籍isbn");
String isbn=scanner.next();
if(exit(isbn)) {
System.out.println("isbn不能重复");
return;
}
System.out.println("请输入书籍名称");
String name=scanner.next();
System.out.println("请选择出版社");
//查询所有出版社id
String sql="select id,name,address from publisher";
class BookRowMapper implements IRowMapper{
@Override
public void rowMapper(ResultSet rs) {
try {
while(rs.next()) {
String id=rs.getString("id");
String name=rs.getString("name");
String address=rs.getString("address");
System.out.println(id+";"+name+";"+address);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
BookRowMapper bookRowMapper=new BookRowMapper();
DBUtil.query(sql, bookRowMapper);
String publisherName=scanner.next(); //查询出所有的出版社的名字。
String publisherId=getId(publisherName); //根据出版社的名称得到出版社的id,
sql="insert into book (id,isbn,name,publisher_id) values (?,?,?,?)";
if(DBUtil.update(sql, StringUtil.getId(),isbn,name,publisherId)) { //要添加的信息是书籍id(随机获取),isbn(唯一),name(书籍名称),publisherId(唯一,不同的出版社名称不同,id不同。
System.out.println("书籍添加成功");
return;
}
System.out.println("系统错误,添加失败!");
}
/**
*
* @author Administrator
*
* 根据isbn删除书籍方法
*/
public static void delete() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要删除的书籍isbn");
String isbn=scanner.next();
if(!exit(isbn)) { //!exit(name)返回true,exit(name)返回false,即不存在。
System.out.println("不存在该isbn");
return;
}
String sql="delete from book where isbn=?";
if(DBUtil.update(sql, isbn)) {
System.out.println("删除成功");
return;
}
System.out.println("系统错误,删除失败");
}
/**
*
* @author Administrator
*
* 根据isbn修改书籍方法
*/
public static void update() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要修改的书籍isbn");
String isbn=scanner.next();
if(!exit(isbn)) { //!exit(name)返回true,exit(name)返回false,即不存在。
System.out.println("不存在该isbn");
return;
}
System.out.println("请输入新的书名");
String name=scanner.next();
System.out.println("请选择输入新的出版社名称");
//查询所有出版社id
String sql="select id,name,address from publisher";
class BookRowMapper implements IRowMapper{
@Override
public void rowMapper(ResultSet rs) {
try {
while(rs.next()) {
String id=rs.getString("id");
String name=rs.getString("name");
String address=rs.getString("address");
System.out.println(id+";"+name+";"+address);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
BookRowMapper bookRowMapper=new BookRowMapper();
DBUtil.query(sql, bookRowMapper);
String publisherName=scanner.next(); //查询出所有的出版社的名称。
String publisherId=getId(publisherName); //根据出版社的名称得到出版社的id,
sql="update book set name=?,publisher_id=? where isbn=?";
if(DBUtil.update(sql, name,publisherId,isbn)) {
System.out.println("修改成功");
return;
}
System.out.println("修改失败");
}
/**
*
* @author Administrator
*
* 根据isbn查询书籍方法
*/
public static void query() {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入要查询的书籍isbn");
String isbn=scanner.next();
//查询语句:内连接之后按照外键查询呢,重命名是为了方法书写,做到见名之意。
String sql="select b.id as book_id,b.name as book_name,b.isbn,p.id as publisher_id,p.name as publisher_name,address " +
"from book as b " +
"inner join publisher as p " +
"on p.id=publisher_id " +
"and isbn like '%"+isbn+"%'";
class RowMapper implements IRowMapper{
@Override
public void rowMapper(ResultSet rs) {
try {
while(rs.next()) { //为什么用getString而不是getInt:因为
String isbn=rs.getString("isbn");
String bookId=rs.getString("book_id");
String bookName=rs.getString("book_name");
String publisherId=rs.getString("publisher_id");
String publisherName=rs.getString("publisher_name");
String address=rs.getString("address");
System.out.println(isbn+";"+bookId+";"+bookName+";"+publisherId+";"+publisherName+";"+address);
return; //此处的return是执行一次循环之后关闭了while循环。因为是按照isbn来查询的,isbn唯一,查询结果只有一个。
}
System.out.println("不存在要查询的书籍");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
RowMapper rowMapper=new RowMapper();
DBUtil.query(sql, rowMapper); //此处先调用不防注入的查询方法。
}
public static void main(String[] args) {
while(true) {
menu();
}
}
public static void menu() {
System.out.println("*\t欢迎来到书籍管理系统\t*");
System.out.println("请输入您要执行的操作,按enter键结束");
System.out.println("1,添加");
System.out.println("2,删除");
System.out.println("3,修改");
System.out.println("4,查询");
Scanner scanner=new Scanner(System.in);
int option=scanner.nextInt();
switch(option) {
case 1: //增
insert();
break;
case 2: //删
delete();
break;
case 3: //改
update();
break;
case 4: //查:注意查询时要将两个表中的信息都查询出来,所以用到了连接(内连接)
query();
break;
default :
System.out.println("不存在该选项");
}
}
}
9、Client
创建客户端
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
welcome();
while(true) {
menu();
}
}
private static void welcome() {
System.out.println("************************");
System.out.println("*\t\t\t*");
System.out.println("*欢迎来到管理系统\t\t*");
System.out.println("*\t\t\t*");
System.out.println("************************");
}
public static void menu() {
System.out.println("请输入您要执行的操作,按entre键结束");
System.out.println("1,请进入书籍管理系统");
System.out.println("2,请进入出版社管理系统");
System.out.println("3,请选择退出");
Scanner scanner=new Scanner(System.in);
int option=scanner.nextInt();
switch(option) {
case 1: //进入书籍管理系统
new BookManager().menu();
break;
case 2: //进入出版社管理系统
new PublisherManager().menu();
break;
case 3: //退出:直接退出网页,return退出方法。
System.exit(0); //系统中存在的退出方法。
break;
default :
System.out.println("没有该项操作");
}
}
}