今天,我们要玩个大的!!!

我们把之前使用数组做的这个单身狗系统改版成数据库版本,并且使用面向对象里面的一些简单思想。如果有不知道这个系统的看官,请跳转到目录页,然后再选择单身狗系统(数组版)先围观五分钟吧。里面的功能很简单。。。。。。。。。

五分钟之后···

好了,五分钟到了,我们继续吧·


要完成的功能还是如上图所示,只不过实现的代码有翻天覆地的变化而已。。。


第一步:分析

一般做一个项目,根据侧重点不同,会把整个项目分成三大部分:界面、功能业务实现、数据库操作。具体三层架构的内容,等后面JSP的时候再来细讲哈。

所以首先要有三个不同的包来保存这三大部分的内容。

com.test:包含main方法的程序入口类放在这个包下。

com.dog.ui:界面相关的类文件放在这个包下。

com.dog.service:功能中的业务逻辑的处理放在这个包下。

com.dog.dao:和数据库打交道的类放在这个包下。

包分好了,我们再来分析要创建哪些类,根据引用顺序,ui要调用service,service要调用dao,而类与类之间的方法如何进行数据传递呢?一般使用实体类。所以我们还要再创建一个entity包存放所有的实体类。项目结构如下图:

昨天文章讲到了JDBC的常用操作分为两类,增、删、改是一样的操作,查询是一样的操作,所以我们可以再写一个通用操作类(DBManager),类中包含两个方法,分别用来操作数据和查询数据。最终的项目结构图如下:

分析过程就到这儿吧,下面进入编码环节。


二、编码

按照调用的先后顺序,我们先编写entity包中的实体类。

2.1 Dog类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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类是一个通用操作类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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类代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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方法:

1
2
3
4
5
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Face face = new Face();
    face.mainMenu();
}

到这儿,所有的代码就编写完成了,测试过程如下:









今天有很多地方因为懒病发作,所以···,大家懂的,一个完整的流程,很多步骤都需要进行判断,看官中的小萌新们,你们就不要懒了,把该补完整的代码补上吧,之后就可以去比你更新的萌新面前得瑟了,哈哈哈!

“软件思维”博客地址:51CTO博客园,感兴趣的小伙伴可以去看相关的其它博文。

《Java从入门到放弃》JavaSE入门篇:练习——单身狗租赁系统的更多相关文章

  1. 《Java从入门到放弃》JavaSE篇:综合练习——单身狗租赁系统(数组版)

    因为现在只学习了基本语法,所以在综合练习之前,先补充关于方法概念. 方法的作用:把一系列的代码放在一起,然后再取个别名.之后通过这个别名的调用,就相当于执行了这一系列的代码. 方法的语法:([]中的内 ...

  2. dotnet 从入门到放弃的 500 篇文章合集

    本文是记录我从入门到放弃写的博客 博客包括 C#.WPF.UWP.dotnet core .git 和 VisualStudio 和一些算法,所有博客使用 docx 保存 下载:dotnet 从入门到 ...

  3. 《Java从入门到放弃》入门篇:springMVC数据校验

    昨天我们扯完了数据传递,今天我们来聊聊数据校验的问题.来,跟着我一起读:计一噢叫,一按艳. 在springMVC中校验数据也非常简单,spring3.0拥有自己独立的数据校验框架,同时支持JSR303 ...

  4. 《Java从入门到放弃》入门篇:hibernate中的多表对应关系

    hibernate中的对应关系其实就是数据库中表的对应关系, 就跟某些电影中的某些场景是一样一样滴. 比如可以是一男一女,还可以是一男多女, 更可以是多男一女,最后最后最后还可以是多男多女!!! 有些 ...

  5. 《Java从入门到放弃》入门篇:hibernate查询——HQL

    不知不觉又到了hibernate的最后一篇了,只感觉时光飞逝~,岁月如梭~! 转眼之间,我们就···························,好吧,想装个X,结果装不下去了,还是直接开始吧· ...

  6. 《Java从入门到放弃》入门篇:springMVC数据传递

    springMVC中的数据传递方式与JSP和Struts2相比,更加的简单.具体有什么样的区别呢?我们通过下面这张图来对比就知道了. 随手画的,有些错别字,不用太在意..... 接下来,进入正题,sp ...

  7. Java性能测试从入门到放弃-详解篇

    Jmeter组件分类说明 Jmeter的组件可以放在任意位置 线程池:用于创建线程.每个线程会"批次顺序"执行任务,因此后面的任务可根据前面的任务决定具体的操作.          ...

  8. 函数响应式编程(FRP)从入门到”放弃”——基础概念篇

    前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...

  9. python从入门到放弃之线程篇

    一,什么是多线程? 1.多线程的概念? 说起多线程,那么就不得不说什么是线程,而说起线程,又不得不说什么是进程. 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分 ...

随机推荐

  1. Yii2 在模块modules间跳转时,url自动加模块名

    如目的地址product/detail, 当前模块是admin, 访问时如果目的url'product/detail',会变成'admin/product/detail'. 解决方法:url改成'/p ...

  2. JavaScript+html5 canvas实现本地截图教程

    这篇文章主要介绍了JavaScript+html5 canvas实现本地截图教程,对截图功能感兴趣的小伙伴们可以参考一下 最近有时间了解了下html5的各API,发现新浪微博的头像设置是使用canva ...

  3. Java内存原型分析

    Java虚拟机内存原型 寄存器:在程序中无法控制 栈:存放基本类型的数据和对象的引用,但是对象本身不存放在栈中,而是存放在堆中 堆:存放用new产生的数据 静态域:存放在对象中用static定义的静态 ...

  4. BootKit病毒——“异鬼Ⅱ”的前世今生

    七月底,一种名为"异鬼Ⅱ"的木马在全网大肆传播.一个多月过去了,风声渐渐平息,之前本来准备专门就这个木马写一篇博客的,结果拖到现在,幸好时间隔得还不算太久.闲话不多说,回到正题. ...

  5. 第3阶段——内核启动分析之make uImage编译内核(3)

    目标: 通过分析makefile,明白make uImage如何编译内核 把整个内核的makefile分成三类(makefile资料文档在linux-2.6.22.6/Documentation/bu ...

  6. makefile中":=","=","?=","+=" 之间的区别

    区别:  := 有关位置的等于,值取决于当时位置的值 = 无关位置的等于,值永远等于最后的值 ?= 是如果没有被赋值过就赋予等号后面的值+= 是添加等号后面的值 '=':无关位置的等于 比如: x = ...

  7. [js高手之路]gulp教程-从入门到项目中快速上手使用

    在这之前,我已经分享过一个webpack的全系列,相对于webpack, gulp使用和配置起来非常的简单. gulp是什么? gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能 ...

  8. Apache配置虚拟域名

    在作php本地调试的时候,一般都要打上localhost/,如果你的项目层级关系比较多,那你的url地址就会很长. 那我们能不能用一个简短的域名去替代那些一长串无用的字符呢? 那可能有人会问如果我没有 ...

  9. none,hidden和opacity="0"设置元素不可见的区别

    none,hidden和opacity="0"均可设置元素为不可见的状态.其中none属于display的属性值,hidden属于visibility的属性值.使用none时元素不 ...

  10. 关于js中单双引号以及转义符的理解

    关于js中单引号(')和双引号(")的使用以及转义的理解 这几天一直在画页面,身为开发人员的我之所以要画页面是因为当前项目中的页面上所有的东西都是从数据库中取得的,也就是动态的,类似于我们设 ...