java-web与jdbc简单的图书租赁系统
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-web与jdbc简单的图书租赁系统,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含20191字,纯文字阅读大概需要29分钟。
内容图文
![java-web与jdbc简单的图书租赁系统](/upload/InfoBanner/zyjiaocheng/741/b60c2b08df604afea34f8925038086a9.jpg)
1.项目背景
本项目基于java-web与jdbc之间的关系,将简单阐述一下最简单的前后端之间的交互,包括数据库的建立分析,后端java部分的步骤分析,逻辑分析。前端部分与后端的交接,最后的测试,本项目只是为了练习java-web的应用。并从中分析总结技术经验
2.编写目的
为了更加了解项目的本质,本项目连同数据库的建立,后端分析,前端简单制作,测试等全部流程都是由自己搭建的,也是更加的能了解整个项目的运转流程。
3.流程分析
本项目相对来说直接或者间接的应用了数据库的增删改查操作,那么分析流程就从数据库的角度开始了。
(1)设置登录
登录部分可以说其实就是一次查询,其实就是把你输入的信息获取去查询数据库,返回一个boolean类型的值。(当然像我们qq等一些生活常用软件的登录远远没有那么的简单)我们通过boolean类型的值进行判断,去进入到我们想进入到的页面。但是因为涉及到了增删改查,仔细想一下,图书租赁系统,有用户操作的部分当然也有管理者操控的部分,那么所以我们还要给每一个登录的账号设置权限(管理者权限和用户权限)通过对应的权限去返回对应的状态。
(2)图书类型的增删改查
图书存在很多种类,如果我们直接把所有的图书都放给用户,在数据很少的情况下还可以,如果图书信息多了,用户就会很不便利,那么就要给图书分类别,通过类别在进入到对应的图书当中去,这样极大地方便了用户操作。
(2-1)首先先设置图书类型当中要存在的数据有什么,图书类型名称和日租金。
(2-2)实现增删改查即可
(2-3)前面说到了存在管理员模式和用户模式,那么像删除和修改和添加的操作其实就只能由管理员来进行,而不是由用户进行。但是用户界面要实现查看功能。
(3)图书的增删改查
(3-1)我们前面分析到了,我么你要通过图书类型进入到图书,那么其实这就有一个主从关系了,那么我们就要在建立数据库的时候通过设立外键的方式去让图书类型和图书关联起来。
(3-2)那么我们该分析图书该具有哪些属性了,首先为了和图书类型关联,需要把图书类型的主键设置成图书的外键,然后图书也存在自己的名字,像图书名称,图书价格,图书出版社,图书作者,图书库存。
(3-3)实现增删改查即可。
(3-4)那么又要管理员和用户分离,增加修改和删除是管理员才能做的。而查看是用户做的。
(4)租赁的增删改查
(4-1)通过前面设置用户信息,我们能够判断管理员模式和用户模式。租赁其实用户模式的功能之一。
(4-2)那么我们应该怎么判断租赁呢,租赁必然涉及到金额问题,那么我们就要通过每个用户来判断租赁问题,用户租赁的是图书,我们还要和图书关联起来,那么其实就是将用户的主键和图书的主键关联起来当做租赁的外键。这样就将租赁和整个模式关联起来了。使其成为了一个主题。
(4-3)分析租赁具有哪些属性,首先将用户的主键和图书的主键,然后是租赁天数,租赁金额,租的日期,还的日期,租借状态。
(4-4)租赁过程成还涉及到别的表的更新,我们每租一本书那么库存就要少一本数,还一本书那么库存就要多一本书。
(4-5)实现租书和还书功能
(5)查询功能
实现模糊查询,通过图书类型或者图书名称,输入一些提示信息去查询到你想要的租赁信息。
4.项目实现
首先最最重要的是要把数据库和实体类建立好。然后按照流程分析的过程去一步一步的编写功能。
(1)数据库连接
(1-1)做项目之前先封装好连接数据库的工具类,可以节约大量的代码。
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/web?useUnicode=true&characterEncoding=utf8";
private static final String USERNAME = "root";
private static final String PWD = "123456";
public Connection getConn(){
Connection con = null;
try {
Class.forName(DRIVER);
con = DriverManager.getConnection(URL,USERNAME,PWD);
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
????????(2)登录部分
(2-1)数据库的设计,需要提前想好用户user数据库中究竟包含着什么样的信息。如下。
(2-2)实体类,既然创建好了数据库,就要创建对应的实体类,以便通过集合的方式来实现增删改查。
private int userid;
private String username;
private String password;
private int level;
public Account() {
super();
}
public Account(int userid, String username, String password, int level) {
super();
this.userid = userid;
this.username = username;
this.password = password;
this.level = level;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + level;
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
result = prime * result + userid;
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (level != other.level)
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (userid != other.userid)
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
@Override
public String toString() {
return "Account [userid=" + userid + ", username=" + username
+ ", password=" + password + ", level=" + level + "]";
}
(2-3)创建对应的servlet,然后实现前端后端,由前端通过form表单发送数据到对应的servlet中去,然后在对应的servlet中处理接受到的数据拿到数据库中进行遍历。
(2-4)通常上增加,删除,修改操作返回的是int型,而查询操作返回的是一个结果集,但是登陆查询其实本意上是一个查询,故登陆查询的时候应该也返回一个boolean的结果才可以。所以。
// 验证登录方法
public boolean login(Account account) {
boolean flag = false;
try{
Connection con = db.getConn();//链接数据库
PreparedStatement pstmt = null;//执行数据库
String sql = "SELECT * from user where username = ? and password = ?";//执行数据库
ResultSet rs = null;//结果集
pstmt = con.prepareStatement(sql);//执行数据库
pstmt.setString(1, account.getUsername());
pstmt.setString(2, account.getPassword());
rs = pstmt.executeQuery();//查询结果
while(rs.next()){
flag = true;
}
}catch(SQLException e){
System.out.println("验证登录方法出现错误");
}
return flag;
}
(2-5)用户权限,在第三个环节就介绍到了其实登陆是分忧权限的,不可能把删除等操作都放给用户去做,那么所以就在一开始考虑到了用户权限的问题,本项目中采用了最不高明的用法。(虽然已经掌握了最新的方法,不过不打算改动了)本项目查询出对应的用户信息然后比较level。
public Account loginlevel(Account account){
Account acc = null;
try{
Connection con = db.getConn();//链接数据库
PreparedStatement pstmt = null;//执行数据库
String sql = "SELECT * from user where username = ? and password = ?";//执行数据库
ResultSet rs = null;//结果集
pstmt = con.prepareStatement(sql);//执行数据库
pstmt.setString(1, account.getUsername());
pstmt.setString(2, account.getPassword());
rs = pstmt.executeQuery();//查询结果
while(rs.next()){
acc = new Account(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getInt(4));
}
}catch(SQLException e){
System.out.println("通过账号和密码查询整条用户信息出现错误");
}
return acc;
}
}
boolean isOk = adi.login(account);
Account acc = adi.loginlevel(account);
if(isOk&&(acc.getLevel() == 1)) {
HttpSession session = request.getSession();
session.setAttribute("username", username);
// System.out.println(session.getAttribute("username"));
request.getRequestDispatcher("index.jsp").forward(request, response);
}else if(isOk&&(acc.getLevel() == 0)){
HttpSession session = request.getSession();
session.setAttribute("username", username);
// System.out.println(session.getAttribute("username"));
request.getRequestDispatcher("userindex.jsp").forward(request, response);
}else {
System.out.println("用户名或密码出现错误");
}
(2-6)session问题,我们通常在登录进去后还要通过对应的用户信息去显示对应的内容,那么session就显的格外重要了,也就是在登录的时候发送到你想要的页面去,然后在你想要的页面接收一下session的信息即可。
(2-7)主界面接收session。向下转型接收。
String username = (String)session.getAttribute("username");
(2-8)session失效,我们可以人为的让session失效,或者也可以等待三十分钟没有操作session也会自动失效。
HttpSession session = request.getSession();
session.invalidate();//session失效
session = null;
????????(3)图书类型
(3-1)数据库的建立
(3-2)实体类的建立
private String typeName;
private String typePrice;
private int id;
public AccountBook() {
super();
}
public AccountBook(int id,String typeName, String typePrice) {
super();
this.id = id;
this.typeName = typeName;
this.typePrice = typePrice;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public String getTypePrice() {
return typePrice;
}
public void setTypePrice(String typePrice) {
this.typePrice = typePrice;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result
+ ((typeName == null) ? 0 : typeName.hashCode());
result = prime * result
+ ((typePrice == null) ? 0 : typePrice.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AccountBook other = (AccountBook) obj;
if (id != other.id)
return false;
if (typeName == null) {
if (other.typeName != null)
return false;
} else if (!typeName.equals(other.typeName))
return false;
if (typePrice == null) {
if (other.typePrice != null)
return false;
} else if (!typePrice.equals(other.typePrice))
return false;
return true;
}
@Override
public String toString() {
return "AccountBook [typeName=" + typeName + ", typePrice=" + typePrice
+ ", id=" + id + "]";
}
(3-3)增删改查(由于内容较多,故在此只说思路,代码将会在最后以百度网盘的形式给出)这就到了我们日常的业务逻辑了增删改查,其实也就是通过由web端给出的操作由后台来实现而已。
增加的话就是设置一个a标签,跳转到一个添加数据的页面,然后就是输入数据,把数据发送到对应的servlet中去,然后在servlet中接收去执行数据库操作。
删除其实就是也是设置一个a标签,点击之后在对应的servlet中把你点击的数据列删除了,然后在重新查询数据库这样就实现了删除效果。
修改其实是删除和增加的结合版本,就是设置一个a标签,点击之后跳转到对应的修改页面,同时显示你要修改数据的数据在对应的输入框内,然后在修改发送到对应的servlet中,执行修改操作,最后再重新查询数据库也就实现了修改效果。
查询其实可以说的上是最复杂的了,因为像上面的三个操作返回都是状态值,而查询返回来的却是结果值,一般通常都是用集合的方式来存储查询的结果。
(3-4)图书类型的管理其实是写在了管理者的页面内,因为涉及到了增加删除和修改功能,在用户层只需要最简单的查询即可。故在此也实现了第二部分的登录提到了用户层次分离。
(4)图书
(4-1)外键,既然涉及到了图书,前面我们就涉及出来了,图书其实是图书类型里面的一部分,也就是说,一个图书类型有很多种图书,一本图书只对应一本图书类型,只是一种典型的一对多的关系,那么这种关系,就要用到外键了,应该把图书类型的主键当做图书里面的外键来增加这两个的关联性。
(4-2)数据库
(4-3)实体类
// 图书id
private int bookid;
// 图书类型id
private int TypeName;
// 图书名称
private String bookName;
// 图书价格
private double bookPrice;
// 图书出版社
private String bookPub;
// 图书作者
private String bookAuthor;
// 图书库存
private int bookStock;
public Book517() {
super();
}
public Book517(int bookid, int typeName, String bookName, double bookPrice, String bookPub, String bookAuthor,
int bookStock) {
super();
this.bookid = bookid;
TypeName = typeName;
this.bookName = bookName;
this.bookPrice = bookPrice;
this.bookPub = bookPub;
this.bookAuthor = bookAuthor;
this.bookStock = bookStock;
}
public int getBookid() {
return bookid;
}
public void setBookid(int bookid) {
this.bookid = bookid;
}
public int getTypeName() {
return TypeName;
}
public void setTypeName(int typeName) {
TypeName = typeName;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getBookPrice() {
return bookPrice;
}
public void setBookPrice(double bookPrice) {
this.bookPrice = bookPrice;
}
public String getBookPub() {
return bookPub;
}
public void setBookPub(String bookPub) {
this.bookPub = bookPub;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public int getBookStock() {
return bookStock;
}
public void setBookStock(int bookStock) {
this.bookStock = bookStock;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + TypeName;
result = prime * result + ((bookAuthor == null) ? 0 : bookAuthor.hashCode());
result = prime * result + ((bookName == null) ? 0 : bookName.hashCode());
long temp;
temp = Double.doubleToLongBits(bookPrice);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((bookPub == null) ? 0 : bookPub.hashCode());
result = prime * result + bookStock;
result = prime * result + bookid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book517 other = (Book517) obj;
if (TypeName != other.TypeName)
return false;
if (bookAuthor == null) {
if (other.bookAuthor != null)
return false;
} else if (!bookAuthor.equals(other.bookAuthor))
return false;
if (bookName == null) {
if (other.bookName != null)
return false;
} else if (!bookName.equals(other.bookName))
return false;
if (Double.doubleToLongBits(bookPrice) != Double.doubleToLongBits(other.bookPrice))
return false;
if (bookPub == null) {
if (other.bookPub != null)
return false;
} else if (!bookPub.equals(other.bookPub))
return false;
if (bookStock != other.bookStock)
return false;
if (bookid != other.bookid)
return false;
return true;
}
@Override
public String toString() {
return "Book517 [bookid=" + bookid + ", TypeName=" + TypeName + ", bookName=" + bookName + ", bookPrice="
+ bookPrice + ", bookPub=" + bookPub + ", bookAuthor=" + bookAuthor + ", bookStock=" + bookStock + "]";
}
(4-4)增删改查,与(3-3)一致。
(4-5)与(3-4)一致。
(5)租赁
(5-1)用户模式,像前面我们说的图书类型和图书的增删改查其实都是体现在管理员模式上的,用户模式只需要查询即可,不需要增加删除修改,但是租赁信息是体现在用户层的。
(5-2)外键,租赁的关联不仅仅只是和你要租赁的图书了,因为涉及到用户层,那么也就要体现到每一个用户上,即,体现用户的独一性和图书的独一性才能实现租赁系统。故要把用户user数据库的主键和图书book数据库的主键当做租赁rent数据库的外键,才能让租赁和用户与图书产生关联性。
(5-3)数据库
(5-4)实体类,这个实体类和前面几个都不一样,也是我要重点介绍的。因为涉及到了时间模式(其实也学会一种更好的时间转换模式,即存毫秒值字符串转换过滤即可)
import java.util.Date;
// 租书编号
private int rentalBookId;
// 用户编号
private int userid;
// 图书编号
private int bookid;
// 租借天数
private int rentalDay;
// 总金额
private double totalAmount;
// 借阅日期
private Date borrowDate;
// 归还日期
private Date returnDate;
// 借阅状态
private int borrowingStatus;
public bookRental() {
super();
}
public bookRental(int rentalBookId, int userid, int bookid, int rentalDay,
double totalAmount, Date borrowDate, Date returnDate,
int borrowingStatus) {
super();
this.rentalBookId = rentalBookId;
this.userid = userid;
this.bookid = bookid;
this.rentalDay = rentalDay;
this.totalAmount = totalAmount;
this.borrowDate = borrowDate;
this.returnDate = returnDate;
this.borrowingStatus = borrowingStatus;
}
public int getRentalBookId() {
return rentalBookId;
}
public void setRentalBookId(int rentalBookId) {
this.rentalBookId = rentalBookId;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getBookid() {
return bookid;
}
public void setBookid(int bookid) {
this.bookid = bookid;
}
public int getRentalDay() {
return rentalDay;
}
public void setRentalDay(int rentalDay) {
this.rentalDay = rentalDay;
}
public double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(double totalAmount) {
this.totalAmount = totalAmount;
}
public Date getBorrowDate() {
return borrowDate;
}
public void setBorrowDate(Date borrowDate) {
this.borrowDate = borrowDate;
}
public Date getReturnDate() {
return returnDate;
}
public void setReturnDate(Date returnDate) {
this.returnDate = returnDate;
}
public int getBorrowingStatus() {
return borrowingStatus;
}
public void setBorrowingStatus(int borrowingStatus) {
this.borrowingStatus = borrowingStatus;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + bookid;
result = prime * result
+ ((borrowDate == null) ? 0 : borrowDate.hashCode());
result = prime * result + borrowingStatus;
result = prime * result + rentalBookId;
result = prime * result + rentalDay;
result = prime * result
+ ((returnDate == null) ? 0 : returnDate.hashCode());
long temp;
temp = Double.doubleToLongBits(totalAmount);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + userid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
bookRental other = (bookRental) obj;
if (bookid != other.bookid)
return false;
if (borrowDate == null) {
if (other.borrowDate != null)
return false;
} else if (!borrowDate.equals(other.borrowDate))
return false;
if (borrowingStatus != other.borrowingStatus)
return false;
if (rentalBookId != other.rentalBookId)
return false;
if (rentalDay != other.rentalDay)
return false;
if (returnDate == null) {
if (other.returnDate != null)
return false;
} else if (!returnDate.equals(other.returnDate))
return false;
if (Double.doubleToLongBits(totalAmount) != Double
.doubleToLongBits(other.totalAmount))
return false;
if (userid != other.userid)
return false;
return true;
}
@Override
public String toString() {
return "bookRental [rentalBookId=" + rentalBookId + ", userid="
+ userid + ", bookid=" + bookid + ", rentalDay=" + rentalDay
+ ", totalAmount=" + totalAmount + ", borrowDate=" + borrowDate
+ ", returnDate=" + returnDate + ", borrowingStatus="
+ borrowingStatus + "]";
}
在这里采用了date声明时间。这这个项目里握唯一出现问题的地方就是时间存不进去,后来上网找了方法才存进去,不过非常的不满意。
public int addRentBook(bookRental bookrental){
int i = 0;//0代表执行失败 1代表执行成功
try{
Connection con = db.getConn();
PreparedStatement pstmt = null;
String sql = "insert into rent (userid,bookid,rentalDay,totalAmount,borrowDate,returnDate,borrowingStatus) values(?,?,?,?,?,?,?)";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, bookrental.getUserid());
pstmt.setInt(2, bookrental.getBookid());
pstmt.setInt(3, bookrental.getRentalDay());
pstmt.setDouble(4, bookrental.getTotalAmount());
pstmt.setDate(5,new java.sql.Date (bookrental.getBorrowDate().getTime()));
pstmt.setDate(6,new java.sql.Date( bookrental.getReturnDate().getTime()));
pstmt.setInt(7, bookrental.getBorrowingStatus());
i=pstmt.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
}
return i;
}
这个方法其实是把实体类当做参数,通过set方法设置实体类的值,然后在这里通过new java.sql.Date(bookrental.getReturnDate().getTime())将数据库中datetime类型的值存进去即可。
(5-5)增删改查,和前面的增删改查的原理一样。
(5-6)租书和还书,租书和还书的原理就是租书了就改变租赁里面的租赁状态,租书和还书主要就是通过租赁状态来去判断是否是在租赁。但是租赁还涉及到一个库存方面的问题,也就是说,租书了库存就应该少一个,还书了库存也就应该多一个才对。
(6)模糊查询
(6-1)模糊查询原理,其实就是通过输入的简单关键字去查询到你想要的数据。
(6-2)模糊查询方法:
一,通过数据库的模糊查询 及 LIKE %你输入的值% 来查询到你想要的数据
二,先将所有的你想查找的数据查找出来放在一个数组中,然后通过你输入的值使用indexof方法进行比对,然后用符合条件的数据去查询你想要的值(麻烦)
5.项目总结
本项目设计到最基本的增删改查,不过仅仅只适用于练手而已,这个项目是我的第一个java-web项目,在完成这个项目之后我也学到了更多的方法去更好的完成这个项目。首先,更让我学到的是写项目之前应该先设计好整个项目,规划好这个项目的简单流程,然后分模块的一个模块一个模块的完成,其次,方法也应该更加的简单才对,然后就是要没完成一个小功能就写一个注释去说明是什么功能,方便后期阅读,最后,通过这个项目我也知道了什么方法是最简单的最有效的,比如模糊查询还有存储时间模式等等。
最后是本项目的源码,数据库在项目中,导入navicat即可使用,使用时仅需把数据库的连接信息换成自己的就可以。
链接:https://pan.baidu.com/s/1VYlNBwmae3nC9GcMs_Npkw
提取码:7tdf
.
内容总结
以上是互联网集市为您收集整理的java-web与jdbc简单的图书租赁系统全部内容,希望文章能够帮你解决java-web与jdbc简单的图书租赁系统所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。