使用分层实现登录

登录是信息系统的基本功能,本章将使用Java实现用户登录功能,并以三层结构重构登录功能。登录功能主要涉及Java如何与MySQL数据库交互。

0 环境

(1)JDK1.6+
(2)编辑器:Eclipse
(3)数据库驱动:mysql-connector-java-5.1.24-bin.jar
(4)读者具有Java、数据库基础

1 需求分析

我们需要使用MySQL建立一个数据库(demo),并在数据库中建立一张用户表(t_user),同时需要有一个登录界面。
当用户在登录界面输入用户名和密码,点击登录,程序应该在用户表中查找匹配的用户,如果存在,在控制台输出“登录中…”语句;如果不存在,提示错误信息。

2 建立测试数据

在MySQL中新建数据库demo,在demo中新建用户表t_user,其结构如下图所示。


表结构


插入一条测试数据,如下图所示。


测试数据


3 Coding

编写登录界面代码,登录界面负责监听【登录】按钮是否被按下,如果按下,则连接demo数据库,并查找与输入的用户名和密码匹配的记录,如果查找成功,在控制台打印“登录…”语句。否则,在控制台打印提示错误信息。
代码清单1:LoginDig.java




public class LoginDig extends JFrame implements ActionListener{

    /*
     * 定义登录界面控件
     */

    //定义用户静态标签
    private JLabel lb_name;
    //定义密码静态标签
    private JLabel lb_psw;
    //定义用户文本框
    private JTextField txt_name;
    //定义密码文本框
    private JPasswordField txt_psw;
    //定义登录按钮
    private JButton btn_login;

    //构造方法,初始化控件,将控件加入框架中
    public LoginDig() {

        //创建控件
        lb_name = new JLabel("用户:");
        txt_name = new JTextField(10);
        lb_psw = new JLabel("密码:");
        txt_psw = new JPasswordField(10);
        btn_login = new JButton("登录");
        //注册按钮事件,当点击按钮时,执行actionPerformed方法
        btn_login.addActionListener(this);
        //设置表格布局结构,3行2列
        this.setLayout(new GridLayout(3, 2));
        this.add(lb_name);
        this.add(txt_name);
        this.add(lb_psw);
        this.add(txt_psw);
        this.add(btn_login);
        //显示框架
        this.setVisible(true);
        this.pack();
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        //获取输入的用户名和密码
        String name = txt_name.getText();
        String password = txt_psw.getText();
        try {
            //加载Mysql驱动
            Class.forName("com.mysql.jdbc.Driver");
            //创建数据库连接
            //数据库相关属性
            String url = "jdbc:mysql://localhost/demo";
            String user = "root";
            String psw= "";
            Connection conn = DriverManager.getConnection(url, user, psw);
            //创建执行sql语句的statement对象
            Statement stmt = conn.createStatement();
            //执行sql语句,返回查询结果
            String sql = "select * from t_user where name = '"
                    + name + "' and password = '"
                    + password + "'";
            ResultSet rs = stmt.executeQuery(sql);
            //如果存在表中存在和输入用户和密码匹配用户
            if(rs.next()){
                System.out.println("登录中...");
            }else{
                System.out.println("用户或密码错误!");
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

测试类,负责创建登录界面。
代码清单2:Test.java


public class test {
    public static void main(String[] args) {
        new LoginDig();
    }
}

运行程序,登录界面如下所示。


登录界面


输入不存在的用户或错误的密码;输入正确的用户和密码,将会在控制台看到相应的提示。


登录信息


4 界面难于承受

在上面的代码清单1中,可以看到LoginDig类负责【UI(界面显示)】、【业务处理(组装SQL语句,依据数据库访问返回结果做处理)】、【数据库交互(连接数据库,访问数据)】三大功能。其逻辑关系如下图所示。


登录界面柔和三种功能


特别是数据库访问那一推凌乱的代码,让人昏昏欲睡,除了编写此代码的程序猿才有心情去看。
上面将三种不相关功能通过登录界面很紧密的关联在一起,【也就是说程序员既要懂界面美工,又要知道业务处理,且数据库知识也很厉害】。我们希望将界面中的三种不同的功能:界面、业务处理和数据库交互分离出来,让界面层只负责界面显示;让业务层专门处理和业务相关的事情;让数据库层专门处理数据库交互。下面将一步一步将登录界面中的三种功能解耦出来。

5 解耦数据库层

首先将那一堆难啃的数据库代码解耦出来,我们需要专门新建一个数据库助手类DBHelper,其负责所有数据库相关操作,并提供接口(方法)供界面层(登录界面)调用,其关系如下图所示。


解耦数据库层


依据上图分层要求,要将程序分为界面层、数据操作层,初步缓解LoginDig的烦恼,让其只负责界面显示与业务处理,抛弃那烦人的数据库交互代码。
将LoginDig中负责数据库操作的代码抽取出,编写数据库操作类DBHelper。
代码清单3:DBHelper.java


public class DBHelper {

    //数据库相关属性
    private String url = "jdbc:mysql://localhost/demo";
    private String user = "root";
    private String pwd = "";

    //获取数据库连接
    public Connection getConn() throws Exception{
        Connection conn;
        //加载Mysql驱动
        Class.forName("com.mysql.jdbc.Driver");
        //创建数据库连接
        conn = DriverManager.getConnection(url, user, pwd);
        //返回连接
        return conn;
    }
    //依据用户名和密码查找用户,如果存在返回true,否则false
    public Boolean findUser(String name, String password) throws Exception{
        String sql = "select * from t_user where name = '"
                + name + "' and password = '"
                + password + "'";
        //创建连接
        Connection conn = getConn();
        //创建执行sql语句statement对象
        Statement stmt = conn.createStatement();
        //依据sql语句获取结果集
        ResultSet rs = stmt.executeQuery(sql);
        //如果存在用户,返回true
        if(rs.next()){
            return true;
        }else{
            return false;
        }
    }
}

DBhelper类负责连接数据库,并提供数据库基本操作方法(创建连接、查找用户)供登录界面对象调用。此时,登录界面代码如代码清单4所示。
代码清单4:LoginDig.java



public class LoginDig extends JFrame implements ActionListener{

    /*
     * 定义登录界面控件
     */

    //定义用户静态标签
    private JLabel lb_name;
    //定义密码静态标签
    private JLabel lb_psw;
    //定义用户文本框
    private JTextField txt_name;
    //定义密码文本框
    private JPasswordField txt_psw;
    //定义登录按钮
    private JButton btn_login;

    //构造方法,初始化控件,将控件加入框架中
    public LoginDig() {

        //创建控件
        lb_name = new JLabel("用户:");
        txt_name = new JTextField(10);
        lb_psw = new JLabel("密码:");
        txt_psw = new JPasswordField(10);
        btn_login = new JButton("登录");
        //注册按钮事件,当点击按钮时,执行actionPerformed方法
        btn_login.addActionListener(this);
        //设置表格布局结构,3行2列
        this.setLayout(new GridLayout(3, 2));
        this.add(lb_name);
        this.add(txt_name);
        this.add(lb_psw);
        this.add(txt_psw);
        this.add(btn_login);
        //显示框架
        this.setVisible(true);
        this.pack();
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        //获取输入的用户名和密码
        String name = txt_name.getText();
        String password = txt_psw.getText();
        //创建数据库助手类
        DBHelper db = new DBHelper();
        //调用数据库助手提供的接口findUser,并将用户名和密码作为参数传递
        try {
            if(db.findUser(name, password)){
                System.out.println("登录...");
            }else{
                System.out.println("用户不存在或密码错误!");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

在登录界面,当点击登录按钮,获取用户名和密码,调用数据库层方法,并依据返回的结果进行相应的业务处理。
目前登录界面代码立马靓仔多了,其只负责界面显示和业务处理,至于数据库相关处理都丢给了DBHelper对象负责。相当于完成登录功能这件事由一个人变成了两个人,其中一个专门负责和数据库交互。

6 解耦业务层

在界面层,我们希望其只负责界面显示,业务处理(login业务)应该由用户业务类(UserService)处理。这样登录功能就由三个人协力完成,各自负责自己擅长的事情,且出现错误也好定位是在那一层,缩小了找错范围。完成三层解耦的结构如下图所示。


三层结构


将登录界面中负责登录业务的代码抽离出来,编写一个用户业务处理类,如代码清单5所示。
代码清单5:UserService.java


public class UserService {

    // 负责处理登录业务
    public void login(String name, String password) {
        // 调用数据库层,处理登录
        DBHelper db = new DBHelper();
        // 调用数据库助手提供的接口findUser,并将用户名和密码作为参数传递
        try {
            if (db.findUser(name, password)) {
                System.out.println("登录...");
            } else {
                System.out.println("用户不存在或密码错误!");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

此时登录界面类如代码清单6所示。
代码清单6:LoginDig.java


public class LoginDig extends JFrame implements ActionListener{

    /*
     * 定义登录界面控件
     */

    //定义用户静态标签
    private JLabel lb_name;
    //定义密码静态标签
    private JLabel lb_psw;
    //定义用户文本框
    private JTextField txt_name;
    //定义密码文本框
    private JPasswordField txt_psw;
    //定义登录按钮
    private JButton btn_login;

    //构造方法,初始化控件,将控件加入框架中
    public LoginDig() {

        //创建控件
        lb_name = new JLabel("用户:");
        txt_name = new JTextField(10);
        lb_psw = new JLabel("密码:");
        txt_psw = new JPasswordField(10);
        btn_login = new JButton("登录");
        //注册按钮事件,当点击按钮时,执行actionPerformed方法
        btn_login.addActionListener(this);
        //设置表格布局结构,3行2列
        this.setLayout(new GridLayout(3, 2));
        this.add(lb_name);
        this.add(txt_name);
        this.add(lb_psw);
        this.add(txt_psw);
        this.add(btn_login);
        //显示框架
        this.setVisible(true);
        this.pack();
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        //获取输入的用户名和密码
        String name = txt_name.getText();
        String password = txt_psw.getText();
        //调用业务层
        UserService userService = new UserService();
        userService.login(name, password);
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值