JavaWeb------Servlet+MySQl分层思想

回顾

在上篇文章中,讲述了如何建立一个简单的JavaWeb项目,并使用Servlet实现简单的前后端交互

但是还是很不规范的,而且数据也是写死的,今天来集成使用MySQL数据库,从数据库中获取验证数据

项目分层

项目分层的目的是为了增强代码的可维护性,在本次的项目中,分为以下几层

DAO层                     操作数据库,建立与数据库的连接,对数据库进行增删改查

                                 DAO层中有impl层,该层主要就是实现DAO层定义的接口中的方法

Entity(Bean)层    实体层,建立各种对象的实体,一般只有属性

Service层                 处理业务逻辑,从DAO层获取到数据库增删改查的数据

                                 Service层中有impl层,该层主要就是实现Service层定义的接口中的方法

Servlet层                  将Service层处理返回的结果打包好,发送给前端的页面

utils层                        提供各种工具类

                                                                                                       (个人理解)

分层架构理解

一个项目启动,可以分解为以下步骤

准备工作

Dbutils

在这里会使用一个工具,作用:将JDBC的返回映射成一个对象

主要是封装了JDBC的代码,简化dao层的操作

ORM:Object Relational Mapping

       对象关系映射

       实体和表示有关系的。

JDBC

参数、SQL、结果手动处理

Dbutils:半ORM、Mybatis

参数、SQL、自动映射

Hibernate:ORM

啥都不要写

XX.save(new User(“王麻子”,19,11));

需要下载相应的jar包并添加依赖,添加依赖具体步骤参考

https://blog.csdn.net/h1025372645/article/details/89406819

配置文件

在src目录下新建.xml文件,为Dbutils进行配置

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
	<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb01</property>
	<property name="user">root</property>
	<property name="password">123</property>
	<property name="initialPoolSize">5</property>
	<property name="maxPoolSize">20</property>
  </default-config>

</c3p0-config>

开始项目

数据库表的建立

create table mydb01.tb_user(
                               userId varchar(50),
                               userName varchar(50),
                               password varchar(50)
  );

insert into mydb01.tb_user value ("1","zs","123456");
insert into mydb01.tb_user value ("2","ls","123456");

Entity层

建立操作对象,User类

package com.entity;

public class User {
    private String userId;
    private String userName;
    private String password;

    public User() {
    }

    public User(String userId, String userName, String password) {
        this.userId = userId;
        this.userName = userName;
        this.password = password;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String 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;
    }

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

DAO层

建立一个接口,并在impl中实现该接口

引入MySQL包并使用可参考以下链接

https://blog.csdn.net/h1025372645/article/details/89191301

接口:

package com.dao;

import com.entity.User;

import java.util.List;

public interface UserDao {

    public User getUserById(String id);

}

实现接口的类,查找对应用户,并返回用户数据:

import com.dao.UserDao;
import com.entity.User;
import com.utils.C3p0Utils;
import com.utils.JDBCUtils;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

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

public class UserDaoImpl implements UserDao {
    @Override
    public User getUserById(String id) {
        Connection connection =null;
        PreparedStatement statement = null;
        User user = null;
        try {
            connection = C3p0Utils.getConnection();
            String sql = "select * from tb_user where userId= ?";
            Object[] ob = {id};
            QueryRunner queryRunner = new QueryRunner();
            user = queryRunner.query(connection, sql, new BeanHandler<User>(User.class),ob);

        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            try {
                DbUtils.close(connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return user;
    }
}

Service层

接口:

package com.service;

import com.entity.User;

import java.util.HashMap;
import java.util.List;

public interface UserService {
    public HashMap<String,Object> login (String userId,String password);

 
}

实现接口,处理Servlet传入的数据:

package com.service.impl;

import com.dao.UserDao;
import com.dao.impl.UserDaoImpl;
import com.entity.User;
import com.service.UserService;

import java.util.HashMap;
import java.util.List;

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    @Override
    public HashMap<String, Object> login(String userId, String password) {
        User user = userDao.getUserById(userId);
        HashMap<String, Object> resultMap = new HashMap<>();

        if(user ==null){
            resultMap.put("code","1");
            resultMap.put("msg","用户不存在");
        }else if(!user.getPassword().equals(password)) {
            resultMap.put("code", "2");
            resultMap.put("msg", "密码错误");
        }else{
            resultMap.put("code", "0");
            resultMap.put("msg", "登录成功");
            resultMap.put("data", user);

        }
        return resultMap;
    }
}

Servlet层

建立servlet,获取前端传入数据

package com.servlet;

import com.alibaba.fastjson.JSONObject;
import com.service.UserService;
import com.service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

public class LoginServlet extends HttpServlet {

    UserService userService = new UserServiceImpl();
    //当有POST请求时,该函数会执行
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doPost........"); //控制台打印
    }
    //当有GET请求时,该函数会执行
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet........"); //控制台打印

        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        System.out.println(userName+"-->"+password);

        response.setContentType("text/html;charset=utf-8");
        HashMap<String, Object> login = userService.login(userName, password);

        PrintWriter writer = response.getWriter();
        writer.print(JSONObject.toJSONString(login));
        writer.flush();
        writer.close();

    }
}

前端jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Servlet+MySQL</title>
  </head>
  <body>
    

    <div>
      用户名:<input type="text" name = "userName" id="userName"><br>
      密  码:<input type="password" name="password" id="password"><br>
      <input type="button" value="提交" id="btn1">

    </div>
  <div id="data">

  </div>
  </body>
  <script src="lib/jquery-1.9.1.min.js"></script>
  <script>
    $("#btn1").click(function () {
      var userName = $("#userName").val();
      var password = $("#password").val();
      $.ajax({
        url:"loginServlet",
        method:"GET",
        data:{
          userName:userName,
          password:password
        },
        success:function (result) {

          result = result || "{}";
          var resultObj = JSON.parse(result);
          var code = resultObj.code;
          if(code==0){
            var msg = resultObj.msg;
            location.href = "success.jsp";//页面跳转
            alert(msg);

          }
          else{
            var  msg = resultObj.msg;
            alert(msg);
          }
          },
          error:function (result) {
            console.log(result);
        }
      });
    });
  </script>
</html>

此时运行项目,就可以从数据库中读取并验证数据

源码:提取码:rlhi

连接池

介绍

目前JDBC做法,每次查询、插入数据之前,需要建立连接、数据处理完成之后,有关闭连接。打开连接和关闭连接非常耗费资源,性能。

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

常见的连接池工具框架

1 dbcp

dbcp可能是使用最多的开源连接池,原因大概是因为配置方便,而且很多开源和tomcat应用例子都是使用的这个连接池吧。
这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。这个连接池的配置参见附件压缩包中的:dbcp.xml
使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性还是可以,不过速度稍慢,在大并发量的压力下稳定性
有所下降,此外不提供连接池监控

2 c3p0

c3p0是另外一个开源的连接池,在业界也是比较有名的,这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。
这个连接池的配置参见附件压缩包中的:c3p0.xml。
使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性相当不错,在大并发量的压力下稳定性也有一定保证,
此外不提供连接池监控。 

3 proxool

proxool这个连接池可能用到的人比较少,但也有一定知名度,这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。
这个连接池的配置参见附件压缩包中的:proxool.xml。
使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性有一定问题,有一个需要长时间跑批的任务场景任务,同样的代码
在另外2个开源连接池中成功结束,但在proxool中出现异常退出。
但是proxool有一个优势–连接池监控,这是个很诱人的东西,大概的配置方式就是在web.xml中添加如下定义:
<servlet>
<servlet-name>admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
并在应用启动后访问:http://localhost:8080/myapp/admin这个url即可监控
不过proxool本身的包在监测使用中会有编码问题,附件中有一个
解决此问题的包,参见附件压缩包中的:proxool-0.9.0RC3.jar。另外需要jdk1.5以上的环境

数据库连接池详解见下链接

http://blog.songchunmin.com/522.html

Jsq基础知识

Java server page缩写,在JSP里面上可以嵌入java 代码。

它实现了Html语法中的java扩展

JSP三大指令

指令:指导页面编译和加载

Page指令

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

contentType:页面的类型和字符编码

language:JSP脚本中嵌套的是什么语言

pageEncoding:当前JSP文件的本身编码

import:导入Java的包

errorPage:当前页面如果出错,跳转哪个页面

isErrorPage="true":当前页面是一个处理错误的页面

include指令

页面包含指令,可以将一个JSP页面包含到另外一个JSP页面中

格式:

作用:

         (1)不用写重复的代码

         (2)代码容易维护。

Taglib指令

在JSP页面中引入标签库(JSTL标签、Struts2标签库)

<%@ taglib prefix="前缀" uri="标签库地址" %>

嵌入Java代码

输出

<%=Java变量或者表达式%> :用户输出在页面上

注释

<%.......%>中使用  // 注释

jsp中使用<%--  --%> 注释

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无名一小卒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值