今天,我们要玩个大的!!!
我们把之前使用数组做的这个单身狗系统改版成数据库版本,并且使用面向对象里面的一些简单思想。如果有不知道这个系统的看官,请跳转到目录页,然后再选择单身狗系统(数组版)先围观五分钟吧。里面的功能很简单。。。。。。。。。
五分钟之后···
好了,五分钟到了,我们继续吧·
要完成的功能还是如上图所示,只不过实现的代码有翻天覆地的变化而已。。。
第一步:分析
一般做一个项目,根据侧重点不同,会把整个项目分成三大部分:界面、功能业务实现、数据库操作。具体三层架构的内容,等后面JSP的时候再来细讲哈。
所以首先要有三个不同的包来保存这三大部分的内容。
com.test:包含main方法的程序入口类放在这个包下。
com.dog.ui:界面相关的类文件放在这个包下。
com.dog.service:功能中的业务逻辑的处理放在这个包下。
com.dog.dao:和数据库打交道的类放在这个包下。
包分好了,我们再来分析要创建哪些类,根据引用顺序,ui要调用service,service要调用dao,而类与类之间的方法如何进行数据传递呢?一般使用实体类。所以我们还要再创建一个entity包存放所有的实体类。项目结构如下图:
昨天文章讲到了JDBC的常用操作分为两类,增、删、改是一样的操作,查询是一样的操作,所以我们可以再写一个通用操作类(DBManager),类中包含两个方法,分别用来操作数据和查询数据。最终的项目结构图如下:
分析过程就到这儿吧,下面进入编码环节。
二、编码
按照调用的先后顺序,我们先编写entity包中的实体类。
2.1 Dog类
public class Dog {
private int did; //编号
private String nickname; //昵称
private int gender; //性别
private String outDate; //租出日期
private int state; //状态
public int getDid() {
return did;
}
public void setDid(int did) {
this.did = did;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
if(gender==1 || gender==0){
this.gender = gender;
}
else{
this.gender = 1;
}
}
public String getOutDate() {
return outDate;
}
public void setOutDate(String outDate) {
this.outDate = outDate;
}
public int getState() {
return state;
}
public void setState(int state) {
if(state==1 || state==0){
this.state = state;
}
else{
this.state = 0;
}
}
}
再编写dao包下面的类。
2.2 DBManager类是一个通用操作类,代码如下:
public class DBManage {
static Connection con = null;
static PreparedStatement ps = null;
static ResultSet rs = null;
//连接MySQL
static String driver = "com.mysql.jdbc.Driver";
static String url = "jdbc:mysql://127.0.0.1:3306/singledogdb";
//创建连接对象
private static Connection getConnect(){
try {
Class.forName(driver);
con = DriverManager.getConnection(url,"root","root"); //连接mysql
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
//执行查询后返回ResultSet对象(不带参数)
public static ResultSet getResultSet(String sql){
con = getConnect();
try {
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
//执行查询后返回ResultSet对象(带参数)
public static ResultSet getResultSet(String sql,Object[] params){
con = getConnect();
try {
ps = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++)
ps.setObject(i+1, params[i]);
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
//执行增、删、改操作,返回受影响的行数
public static int modifyEntiy(String sql, Object[] params){
int num = 0;
con = getConnect();
try {
ps = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
ps.setObject(i+1, params[i]);
}
num = ps.executeUpdate();
closeAll();
} catch (SQLException e) {
e.printStackTrace();
}
return num;
}
//关闭连接
public static void closeAll(){
if (ps != null){
try {
ps.close();
ps = null;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con != null){
try {
con.close();
con = null;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
后面主要使用getResultSet()方法和modifyEntiy()方法。
2.3 DogDao类代码如下:
public class DogDAO {
//查询所有单身狗
public List<Dog> findAll(){
List<Dog> list = new ArrayList<Dog>();
String strSql = "select did,nickname,gender,DATE_FORMAT( outDate,'%Y-%m-%d') outDate,state from dogtbl";
try {
ResultSet rs = DBManage.getResultSet(strSql);
while (rs.next()) {
Dog dog = new Dog();
dog.setDid(rs.getInt("did"));
dog.setNickname(rs.getString("nickname"));
dog.setGender(rs.getInt("gender"));
dog.setOutDate(rs.getString("outDate"));
dog.setState(rs.getInt("state"));
list.add(dog);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
//新增
public int insert(Dog dog){
int result = 0;
String strSql = "INSERT INTO dogTbl (did, nickname, gender ) VALUES (?, ?, ?)";
Object[] params = new Object[3];
params[0] = dog.getDid();
params[1] = dog.getNickname();
params[2] = dog.getGender();
result = DBManage.modifyEntiy(strSql, params );
return result;
}
//删除(result的值:-1.查无此狗 0.删除失败 1.删除成功)
public int delete(int dogid){
int result = 0;
String strSql = "select state from dogTbl where did=?";
Object[] params = new Object[1];
params[0] = dogid;
//1.查询是否有该记录
ResultSet rs = DBManage.getResultSet(strSql, params);
try {
if(rs.next()){
int state = rs.getInt("state");
//2. 如果是未借出状态则可以删除
if(state==0){
strSql = "delete from dogTbl where did=? and state=0";
result = DBManage.modifyEntiy(strSql, params );
}
}
else{
result = -1;
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
//更新借出状态
public int update(Dog dog){
int result = 0;
String strSql;
//判断要更新的状态,同时更新借出日期
if(dog.getState()==1){
strSql = "update dogTbl set state=1,outdate=now() where did=?";
}
else{
strSql = "update dogTbl set state=0,outdate=null where did=?";
}
Object[] params = new Object[1];
params[0] = dog.getDid();
result = DBManage.modifyEntiy(strSql, params );
return result;
}
}
主要包括四个操作,添加、删除、更新借出状态和日期、查询所有。等所有功能实现后,小伙伴们可以自己尝试写一写搜索功能。
接下来编写service中的类。
2.4 DogService类
public class DogService {
private DogDAO dogDAO = new DogDAO(); //数据访问对象
//查询所有
public List<Dog> findAll(){
return dogDAO.findAll();
}
//添加
public int add(Dog dog){
return dogDAO.insert(dog);
}
//删除
public String delete(int dogid){
String msg = "删除成功!";
int result = dogDAO.delete(dogid);
if(result==-1){
msg = "查无此狗";
}
else if(result==0){
msg = "该单身狗已租出还未归还,不能删除!";
}
return msg;
}
//借出
public int loan(Dog dog){
int result = 0;
result = dogDAO.update(dog);
return result;
}
//归还:是不是发现和借出的代码一样,这就对了,方法名不同,方便上层的人调用
public int repay(Dog dog){
int result = 0;
result = dogDAO.update(dog);
return result;
}
}
再接下来写UI包中的类
2.5 Face类
public class Face {
// 因为在很多方法中都需要使用输入对象,所以定义到最外面,那么在每个方法中都可以使用了
private Scanner input = new Scanner(System.in);
//创建业务逻辑对象
private DogService dogService = new DogService();
// 显示主菜单
public void mainMenu() {
System.out.println("======================");
System.out.println(" 欢迎使用单身狗租赁系统");
System.out.println(" 1.查看");
System.out.println(" 2.新增");
System.out.println(" 3.删除");
System.out.println(" 4.借出");
System.out.println(" 5.归还");
System.out.println(" 6.退出");
System.out.println("======================");
// 注意,如果用户输入了1~6之外的数字,需要让他重新输入
int num = 6;
do {
System.out.print("请选择:");
num = input.nextInt();
switch (num) {
case 1:
show();
break;
case 2:
add();
break;
case 3:
delete();
break;
case 4:
loan();
break;
case 5:
repay();
break;
case 6:
System.out.println("客官,下次再来玩哟~!");
break;
default:
System.out.println("输入的啥玩意啊,我只认识1,2,3,4,5,6!!!");
break;
}
} while (num > 6 || num < 1);
}
//查看
public void show() {
System.out.println("======================");
System.out.println("====>查看");
System.out.println();
showDog();
goMainMenu();
}
//新增
public void add(){
System.out.println("======================");
System.out.println("====>添加");
System.out.println();
Dog dog = new Dog();
System.out.print("请输入昵称:");
dog.setNickname(input.next());
System.out.print("请选择性别(0.女|1.男):");
dog.setGender(input.nextInt());
//调用添加方法
dogService.add(dog);
System.out.println("添加完毕!");
goMainMenu();
}
//删除
public void delete(){
System.out.println("======================");
System.out.println("====>删除");
System.out.println();
System.out.print("请输入编号:");
int dogid = input.nextInt();
//调用删除方法
System.out.println(dogService.delete(dogid));
goMainMenu();
}
//借出
public void loan(){
System.out.println("======================");
System.out.println("====>借出");
System.out.println();
showDog(); //显示所有单身狗(按道理应该在DAO包中的类编写一个find(state)方法来根据状态查询对应的记录,但我懒癌发作了,没办法···)
System.out.print("请输入编号");
int no = input.nextInt();
//按道理,在这儿应该先根据ID查询出对应的记录,再判断这条记录中的借出状态之后再决定是否能借出,但···,懒癌继续发作中···
Dog dog = new Dog();
dog.setDid(no);
dog.setState(1);
if(dogService.loan(dog)>0){
System.out.println("借出成功!");
}
else{
System.out.println("借出失败!");
}
goMainMenu();
}
//归还
public void repay(){
System.out.println("======================");
System.out.println("====>归还");
System.out.println();
showDog(); //显示所有单身狗(懒癌还在发作···)
System.out.print("请输入编号");
int no = input.nextInt();
//懒癌持续发作中···
Dog dog = new Dog();
dog.setDid(no);
dog.setState(0);
if(dogService.repay(dog)>0){
System.out.println("归还成功!");
}
else{
System.out.println("归还失败!");
}
goMainMenu();
}
//返回主菜单
public void goMainMenu(){
System.out.print("按任意键后回车返回主菜单:");
String in = input.next();
mainMenu();
}
/**
* 显示所有单身狗
*/
private void showDog() {
//查看时注意不要把数组中的空元素进行输出了
System.out.println("编号\t昵称\t性别\t状态\t借出日期");
System.out.println("===========================================");
List<Dog> list = dogService.findAll();
for (int i = 0; i < list.size(); i++) {
Dog dog = list.get(i);
System.out.println(dog.getDid()+"\t"+dog.getNickname()+"\t"+
(dog.getGender()==0?"女":"男") + "\t"+
(dog.getState()==0?"未借出":"已借出\t"+
dog.getOutDate()));
}
System.out.println("===========================================");
}
}
注意代码中有些方法的注释,大家如果要做完整版的,可以自行优化!!!
最后,main方法:
public static void main(String[] args) {
// TODO Auto-generated method stub
Face face = new Face();
face.mainMenu();
}
到这儿,所有的代码就编写完成了,测试过程如下:
今天有很多地方因为懒病发作,所以···,大家懂的,一个完整的流程,很多步骤都需要进行判断,看官中的小萌新们,你们就不要懒了,把该补完整的代码补上吧,之后就可以去比你更新的萌新面前得瑟了,哈哈哈!