基于IDEA的bs三层架构

1.在大学的老师讲课中,可能会用到myeclipse或者eclipse来进行编译运行。其中的缺点就是要自行去下载开发所需要的一些jar包,要考虑都版本的不同造成的影响,且ORACLE和MYSQL的链接容易出错。而目前为止企业开发基于IDEA编译器开发,maven进行自动导包减去了大量麻烦的操作;(Maven的核心功能便是合理叙述项目间的依赖关系,通俗点讲,就是通过pom.xml文件的配置获取jar包,而不用手动去添加jar包,而这里pom.xml文件对于学了一点maven的人来说,就有些熟悉了,怎么通过pom.xml的配置就可以获取到jar包呢?pom.xml配置文件从何而来?等等类似问题我们需要搞清楚,如果需要使用pom.xml来获取jar包,那么首先该项目就必须为maven项目,maven项目可以这样去想,就是在java项目和web项目的上面包裹了一层maven,本质上java项目还是java项目,web项目还是web项目,但是包裹了maven之后,就可以使用maven提供的一些功能了(通过pom.xml添加jar包)。)

  所以,根据上一段的描述,我们最终的目的就是学会如何在pom.xml中配置获取到我们想要的jar包,在此之前我们就必须了解如何创建maven项目,maven项目的结构是怎样,与普通java,web项目的区别在哪里,还有如何配置pom.xml获取到对应的jar包等等,这里提前了解一下我们如何通过pom.xml文件获取到想要的jar的,具体可以看一下这个视频链接https://www.bilibili.com/video/av29071483?p=1 只看第一集基本上就可以解决自己的困惑。

tomcat 服务器(用于解析jsp)

3.下面是代码的截图与解析(在这步之前先做到根据2的视频链接下载apache-maven-3.6.1或者最新版本并保存好路径配置好apache-maven-3.6.1/conf/settings.xml信息(它是用来设置maven参数的配置文件。并且,settings.xml是maven的全局配置文件。而pom.xml文件是所在项目的局部配置。 Settings.xml中包含类似本地仓储位置、修改远程仓储服务器、认证信息等配置。)

maven网上https://mvnrepository.com/上复制粘贴使用量高的两个配置到pom.xml里面

具体代码如下

package com.stu.pojo;
/*实体类alt+enter实现get/set方法,toString方法,有参无参构造函数
  https://blog.csdn.net/peng86788/article/details/80567548*/

public class User {
    private int id;
    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public User() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }
}

jdbc访问数据库的接口(目的就是连接mysql成功)

package com.stu.jdbc;

import com.stu.pojo.User;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main(String[] args)throws Exception {

        //1.动态加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        //2.获取连接对象
        String url = "jdbc:mysql://localhost:3306/stu?useUnicode=true&characterEncoding=UTF-8";
        String user = "root";
        String pwd = "123456";
        //DriverManager管理一组 JDBC 驱动程序的基本服务,getConnection试图建立到给定数据库 URL 的连接
        Connection conn = DriverManager.getConnection(url,user,pwd);


        //3.使用JDBC接口规范实现CRUD
        String sql = "insert into user(username,password) values(?,?)";
//        String sql = "select * from user";

        /*表示预编译的 SQL 语句的对象。 SQL 语句被预编译并存储在 PreparedStatement 对象中。
        然后可以使用此对象多次高效地执行该语句。*/
        PreparedStatement ps = conn.prepareStatement(sql);
//        ps.setString(1,"tom");
//        ps.setString(2,"123456");
        ps.setObject(1,"韩梅梅");
        ps.setObject(2,"lilei123");
        //将此连接的自动提交模式设置为给定状态。jdbc中默认自动提交,
        // commit或rollback不起作用,一般setAutoCommit改成false,commit或rollback才起作用进行事务处理。
        conn.setAutoCommit(false);
        int rel = ps.executeUpdate();
        System.out.println(rel);
        conn.commit();

//          ResultSet rs = ps.executeQuery();
//         List<User> list = new ArrayList<User>();
//          while(rs.next()){
//
//              int id = rs.getInt(1);
//              String username = rs.getString(2);
//              String password = rs.getString(3);
//
//              User u = new User(id,username,password);
//              list.add(u);
//          }
//
//
//        System.out.println(list);
    }

}

Servlet是在服务器端执行的Java程序,一个被称为Servlet容器的程序(其实就是服务器) 负责执行Java程序,

(servlet的方法中使用JDBC连接数据库)

package com.stu.servlet;

import com.stu.pojo.User;
import com.stu.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.SQLException;

/*@WebServlet用注解来实现servlet和url的映射jsp页面 通过action提交到此处:
 <form action="/login" method="post" >*/

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    /*帮助自己检查是否正确的复写了父类中已有的方法有时候写错了会提示错误原因
    告诉读代码的人,这是一个复写的方法*/
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //接收请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        //查询数据
        UserService us = new UserService();
        User u = null;
        try {
            u = us.login(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //跳转
        if(u==null){
            req.setAttribute("mess","账号或密码错误");
            req.getRequestDispatcher("login.jsp").forward(req,resp);
        }else{
            HttpSession session =  req.getSession();
            session.setAttribute("user",u);
            resp.sendRedirect("main.jsp");
        }
    }
}

index.jsp动态页面显示网络端口连接成功

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

login.jsp显示登入成功

<%--
  Created by IntelliJ IDEA.
  User: 123
  Date: 2019/4/22
  Time: 0:42
  To change this template use File | Settings | File Templates.
--%>
<!--设置编写语言为java,编写内容为txt或者html设置编码格式为UTF-8-->
<%--在page directive中的isELIgnored属性用来指定是否忽略。格式为: <%@ page isELIgnored="true|false"%>--%>
<%--如果设定为真,那么JSP中的表达式被当成字符串处理。比如下面这个表达式${2000 % 20}, 在isELIgnored="true"--%>
<%--时输出为${2000 % 20},而isELIgnored="false"时输出为100。Web容器默认isELIgnored="false"。--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

<html>
<head>
    <title>登入</title>
</head>
<body>
     <h1>用户登入</h1>
     <hr>
    <form action="/login" method="post"/>
    <p>
        用户名:<input type="text" name="username">
    </p>
     <p>
         密码:<input type="password" name="password">
     </p>
    <p>
        <input type="submit" value="登入">
    </p>
</form>
    ${mess}<!--获取后端传输过来的数据-->
</body>
</html>

截止到以上内容jdbc+jsp+servlet的一个例子已经完成(JSP就是视图,其本质就是一个servlet,先有servlet后出现的jsp),这些内容表示的是控制器的运行原理

重点

B/S结构下,用户工作界面是通过浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器(Server)实现,形成所谓三层结构。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本(TCO)。

mvc三层架构(model模型对应service和dao控制访问和修改这些数据的业务规则,view视图对应于jsp,它从模型那里获得数据并指定这些数据如何表现。当模型变化时,视负责维持数据表现的一致性。视同时将用户要求告知控制器(Controller)。控制器(Controller)定义了应用程序的行为;它负责对来自视的用户要求进行解释,并把这些要求映射成相应的行为,这些行为由模型负责实现。)注意,MVC不是Java的东西,几乎现在所有B/S结构的软件都采用了MVC设计模式。但是要注意,MVC在B/S结构软件并没有完全实现,例如在我们今后的B/S软件中并不会有事件驱动!

下面是继续增加的代码,数据库处理的dao层,业务逻辑service

package com.stu.dao;

import com.stu.jdbc.JDBCUtils;
import com.stu.pojo.User;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {
   /*JDBCUtils是对jdbc连接数据库做了一个封装,而getConnection这个方法就可以
    实现对数据库的连接*/
    private Connection conn = JDBCUtils.getConnection();

    /*和 Statement一样,PreparedStatement也是用来执行sql语句的
    与创建Statement不同的是,需要根据sql语句创建PreparedStatement*/
    private PreparedStatement ps;

    /**
     * 添加用户
     * @param user 要添加的用户对象
     * @throws SQLException
     */
    public int add(User user) throws SQLException {//自动抛出异常
        String sql = "insert into user(username,password) values(?,?)";

        //来将参数化的 SQL 语句发送到数据库
        ps = conn.prepareStatement(sql);

        //使用给定对象设置指定参数的值。
        ps.setObject(1,user.getUsername());
        ps.setObject(2,user.getPassword());

        /*在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言
        (Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 语句;
        或者是无返回内容的 SQL 语句,比如 DDL(数据库模式定义语言)语句。返回对象为int类型*/
        return ps.executeUpdate();
    }

    /**
     * 删除
     * @param id
     * @return
     * @throws SQLException
     */
    public int delete(int id) throws SQLException {
        String sql = "delete from user where id=?";
        ps = conn.prepareStatement(sql);
        ps.setObject(1,id);
        return ps.executeUpdate();
    }

    /**
     * 修改
     * @param user
     * @return
     * @throws SQLException
     */
    public int update(User user) throws SQLException {
        String sql = "update user set username=? and password=? where id=?";
        ps = conn.prepareStatement(sql);
        ps.setObject(1,user.getUsername());
        ps.setObject(2,user.getPassword());
        ps.setObject(3,user.getId());
        return ps.executeUpdate();
    }

    /**
     * 查询所有
     * @return
     * @throws SQLException
     */
    public List<User> findAll() throws SQLException {
        String sql = "select * from user";
        ps = conn.prepareStatement(sql);

        /*表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
        ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。
        next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,
        所以可以在 while 循环中使用它来迭代结果集。默认的 ResultSet 对象不可更新,
        仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。*/
        /*要用statement类的executeQuery()方法来下达select指令以查询数据库,
        executeQuery()方法会把数据库响应的查询结果存放在ResultSet类对象中供我们使用*/
        ResultSet rs = ps.executeQuery();
        /*代码尽量依赖于抽象,不依赖于具体”。形式就是依赖具体,这种形式就是依赖于抽象。
        因为List是接口。代码依赖于抽象的好处是,代码可以方便替换。*/
        List<User> list = new ArrayList<User>();
        while(rs.next()){
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            User u = new User(id,username,password);
            list.add(u);//集合列表中添加对象
        }
        return list;
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     * @throws SQLException
     */
    public User findByID(int id) throws SQLException {
        String sql = "select * from user where id=?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1,id);

        ResultSet rs = ps.executeQuery();
        User u = null;
        while(rs.next()){
            int uid = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            u = new User(uid,username,password);
        }
        return u;
    }

    /**
     * 登录的方法
     */
    public User login(User user) throws SQLException {
        String sql = "select * from user where username=? and password=?";
        ps = conn.prepareStatement(sql);
        ps.setObject(1,user.getUsername());
        ps.setObject(2,user.getPassword());
        ResultSet rs = ps.executeQuery();
        User u = null;
        while(rs.next()){
            int uid = rs.getInt("id");
            String username = rs.getString("username");
            String password = rs.getString("password");
            u = new User(uid,username,password);
        }
        return u;
    }

}
package com.stu.service;

import com.stu.dao.UserDao;
import com.stu.pojo.User;

import java.sql.SQLException;
import java.util.List;

public class UserService {

    private UserDao userDao = new UserDao();

    /**
     * 添加用户
     * @param user 要添加的用户对象
     * @throws SQLException
     */
    public int add(User user) throws SQLException {
        return userDao.add(user);
    }

    /**
     * 删除
     * @param id
     * @return
     * @throws SQLException
     */
    public int delete(int id) throws SQLException {
        return userDao.delete(id);
    }

    /**
     * 修改
     * @param user
     * @return
     * @throws SQLException
     */
    public int update(User user) throws SQLException {
        return userDao.update(user);
    }

    /**
     * 查询所有
     * @return
     * @throws SQLException
     */
    public List<User> findAll() throws SQLException {
        return userDao.findAll();
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     * @throws SQLException
     */
    public User findByID(int id) throws SQLException {
        return userDao.findByID(id);
    }

    /**
     * 登录
     */
    public User login(User user) throws SQLException {
        return userDao.login(user);
    }

}

补充的代码为

package com.stu.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCUtils {

    public static Connection connection;
    private static String url = "jdbc:mysql://localhost:3306/stu?useUnicode=true&characterEncoding=UTF-8";
    private static String user = "root";
    private static String pwd = "123456";

    static{
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(url,user,pwd);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection(){
        return connection;
    }


}

控制层servlet应用程序对其注册的代码

package com.stu.servlet;

import com.stu.pojo.User;
import com.stu.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;

@WebServlet("/reg")
public class RegUserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //接收请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        //存储数据
        UserService us = new UserService();
        int i = 0;
        try {
            i = us.add(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //跳转
        if(i>0){
            req.setAttribute("mess","注册成功");
            req.getRequestDispatcher("reg.jsp").forward(req,resp);
        }else{
            req.setAttribute("mess","注册失败");
            req.getRequestDispatcher("reg.jsp").forward(req,resp);
        }

    }
}

对应与reg.jsp

<%--
  Created by IntelliJ IDEA.
  User: 123
  Date: 2019/4/22
  Time: 0:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>用户注册</title>
</head>
<body>
<h1>用户注册</h1>
<hr>
<form action="/reg" method="post"/>
<p>
    用户名:<input type="text" name="username">
</p>
<p>
    密码:<input type="password" name="password">
</p>
<p>
    <input type="submit" value="注册">
</p>
</form>
${mess}
</body>
</html>

main.jsp用于登入成功后实现跳转后出现的消息

<%--
  Created by IntelliJ IDEA.
  User: 123
  Date: 2019/4/22
  Time: 0:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
    <h1>欢迎使用本系统</h1>
    当前用户:${sessionScope.user.username}
</body>
</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券