「笨鸟先飞」001-SpringWeb

SpringWeb

image-20210608174605562

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

HTTP协议

Hyper Text Transfer Protocol(超文本阐述协议)

image-20210608174439687

特点:

  • HTTP是无连接的:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。
  • HTTP是无状态:无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

HTTP请求:

​ 请求行 / 请求头 / 请求正文(请求体)

  • get没有请求正文,因为已经显示在地址栏中了;
  • post有请求正文,会将请求数据通过请求体传递给服务器

HTTP响应:

​ 状态行 / 消息报头 / 响应正文(浏览器中所看到的东西)

下面是常见的HTTP状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误
序号方法描述
1GET请求指定的页面信息,并返回实体主体。
2HEAD类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误
消息头

请求头:

  • Regerer:该请求头指明了请求的来源

    通常用于百度竞价广告(引流) / 邀请好友(邀请链接)

响应头:

  • Location:重定向

  • Refresh:自动跳转

    (1.每隔几秒刷新一次页面 / 2.几秒后跳转到新页面)

image-20210608193942815
Tomcat

Tomcat服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP程序的首选。

image-20210608195556885
Servlet
image-20210609131434975
servlet生命周期:

init创建:

image-20210609152219109

service调用:

image-20210609152049761

destory销毁:

image-20210609152320212

image-20210609163749903
获取请求的参数:
请求乱码问题:

get:不会乱码

post:中文会乱码(因为默认编码不支持中文)

​ 解决办法:request.setCharacterEncoding(UTF-8)

请求转发:

request.getRequestDispatcher(url).forward(request,response)

  • 服务端行为
  • 地址栏不发生改变
  • 从始至终只有一个请求
  • 数据可以共享
响应数据:

getWriter(): 字符输出流(输出字符串)

getOutputStream(): 字节输出流(输出任何数据)

响应乱码问题:

getWriter():中文会乱码(因为默认编码不支持中文)

getOutputStream():中文会乱码(因为默认编码不支持中文)

解决办法

  1. 先设置服务端的编码格式:

response.setCharacterEncoding(UTF-8)

  1. 再设置客户端的编码格式:

response.setHeader("context-type","text/html;charset=UTF-8")

  • 同时设置客户端和服务端的编码格式:

    response.setContentType("text/html;charset=UTF-8")

重定向

response.sendRedirect()

  • 客户端行为
  • 两次请求
  • 地址栏会发生改变
  • 数据不共享

客户端发出第一个请求,服务器收到请求后对其响应处理,并给客户端返回一个新的地址;当客户端收到响应时,会立刻发出第二个请求,服务器对其响应处理,重定向完成。

请求转发与重定向的区别
请求转发重定向
服务端行为客户端行为
地址栏不变地址栏改变
一次请求,数据共享两次请求,数据不共享
转发地址只能是当前项目下资源可以是任意地址,可以跨域
Cookie对象
//负整数
Cookie cookie1 = new Cookie("username","leehom1");
cookie1.setMaxAge(-1);//关闭浏览器即失效
response.addCookie(cookie1);
//正整数
Cookie cookie2 = new Cookie("username","leehom2");
cookie2.setMaxAge(30);//存活30秒
response.addCookie(cookie2);
//零
Cookie cookie3 = new Cookie("username","leehom3");
cookie3.setMaxAge(0);//删除cookie
response.addCookie(cookie3);

//作用:7天免登录 / 记住账户密码
Cookie设置到期时间
  • 负整数

    若为负数,则表示不存储该cookie;

    cookie的maxAge属性的默认值就是“-1”,表示只在浏览器内存中存活,一旦关闭浏览器窗口,那么cookie就会消失。

  • 正整数

    若为大于0的整数,则表示存储的秒数;

    当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,甚至重启客户端电脑,cookie也会存活相对应的时间。

  • 若为0,则表示删除该Cookie;

    如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie,无论是浏览器内存中,还是客户端硬盘上都会删除这个Cookie。

Cookie的注意点
  1. Cookie不能换电脑,不能换浏览器;
  2. Cookie无法存储中文;
  3. 重复Cookie会覆盖原来的Cookie;
  4. 浏览器存储Cookie的数量有限,大小也有限(4kb左右)。
Cookie的路径

Cookie的setPath可以设置cookie的路径,这个路径决定服务器的请求是否会从浏览器中加载某些cookie。

  1. 当前服务器下任何项目都可以获取到Cookie对象
//当前项目路径为:s01
Cookie cookie = new Cookie ("name","leehom");
//设置路径为“/”,表示在当前服务器下任何项目都可以获取Cookie对象
cookie.setPath("/");
response.addCookie(cookie);
  1. 当前项目下的资源可以获取Cookie对象(默认不设置Cookie的path)
//当前项目路径为:s01
Cookie cookie = new Cookie ("name","leehom");
//设置路径为“/s01”,表示在当前项目下的资源才可以获取Cookie对象
cookie.setPath("/s01");//默认情况可以不设置path的值
response.addCookie(cookie);
  1. 指定项目下的资源可以获取Cookie对象
//当前项目路径为:s01
Cookie cookie = new Cookie ("name","leehom");
//设置路径为“/s02”,表示在当前项目下的资源才可以获取Cookie对象
cookie.setPath("/s02");
response.addCookie(cookie);
  1. 指定目录下的资源可以获取Cookie对象
//当前项目路径为:s01
Cookie cookie = new Cookie ("name","leehom");
//设置路径为“/s01/cook”,表示在s01/cook目录下才可以获取Cookie对象
cookie.setPath("/s01/cook");
response.addCookie(cookie);
HttpSession对象

HttpSession session = request.getSession()

如果存在则获取,如果不存在则创建

Session域对象
//获取session对象
HttpSession session = request.getSession();

//设置session域对象
session.setAttribute("uname","admin");
//获取指定名称的session域对象
String uname = (String) request.getSession().getAttribute("uname";

//设置request域对象
request.setAttribute("uname","leehom");
//获取指定名称的request域对象
String uname = (String) request.getAttribute("leehom";

//移除指定名称的session域对象
session.removeAttribute("uname");
Session的生命周期

⌛️:Tomcat中session默认存活30min(不操作界面情况下),一旦操作,则会重新计时。

  1. 默认到期时间

可以在Tomcat的conf目录下的web.cml文件中进行修改(不建议)

<!-- session的默认最大不活动时间。单位:min -->
<session-config>
	<session-timeout>30</session-timeout>
</session-config>
  1. 手动设置到期时间
//手动设置到期时间
session.setMaxInactiveInterval(15)//15秒到期
//查看到期时间
getMaxInactiveInterval()
  1. 立即销毁(常用)
session.invalidate();
  1. 关闭浏览器则失效

    session底层依赖cookie,则关闭浏览器即失效。

  2. 关闭服务器则失效

    当关闭服务器时,session会被销毁。

ServletContext对象

获取servletContext对象

//1.通过request对象获取
ServletContext servletContext = request.getServletContext();

//2.通过session对象获取
ServletContext servletContext = request.getSession().getServletContext();

//3.通过ServletConfig对象获取
ServletContext servletContext = getServletConfig().getServletContext();

//4.直接获取
ServletContext servletContext = getServletContext();

常用方法

//获取当前服务器的版本信息
String serverInfo = request.getServletContext().getServerInfo();

//获取项目的真实路径
String realPath = request.getServletContext().getRealPath("/");
ServletContext域对象
//获取ServletContext对象
ServletContext servletContext = request.getServletContext();
//设置域对象
servletContext.setAttribute("name","leehom");
//获取域对象
String name = (String) servletContext.getAttribute("name");
//移除域对象
servletContext.removeAttribute("name");
servlet三大域对象
  1. request域对象

    在一次请求中有效。请求转发有效,重定项失效。

  2. session域对象

    在一次会话中有效。请求转发和重定向都有效,session销毁后失效。

  3. servletContext域对象

    在整个应用程序中有效。服务器关闭后失效。

文件上传和下载

前台页面

<!--
    文件上传:
        1.准备表单
        2.设置表单的提交方式为post请求    method="post"
        3.设置表单类型为文件上传表单      enctype="multipart/form-data"
        4.准备文件提交地址
        5.准备表单元素
            * 普通的表单项   type="text"
            * 文件项        type="file"
        6.设置表单元素的name属性值(否则后台无法接受数据)
-->
<form action="uploadServlet" method="post" enctype="multipart/form-data">
    姓名:<input type="text" name="uname"> <br>
    文件:<input type="file" name="myfile"> <br>
    <!--button默认是提交类型 type="submit"-->
    <button>提交</button>
</form>

后台实现

使用@MultipartConfig将一个Servlet标识为支持文件上传。Servlet将mulipart/form-data的POST请求封装成Part,通过Part对上传的文件进行操作。

@MultipartConfig //如果是文件上传,则必须设置该注解;
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("文件上传");
        //设置请求的编码格式
        req.setCharacterEncoding("UTF-8");
        //获取普通表单项
        String uname = req.getParameter("uname");//表单中对应的name值
        System.out.println("uname:" + uname);
        //获取Part对象
        Part part = req.getPart("myfile"); //表单中file文件域的name属性值
        //通过Part得到上传的文件名
        String fileName = part.getSubmittedFileName();
        System.out.println("上传文件名:" + fileName);
        //得到文件存放路径
        String filePath = req.getServletContext().getRealpath("/");
        System.out.println("文件存放的路径:" + filePath);
        //上传文件到指定目录
        part.write(filePath + "/" + fileName);
    }
}
文件下载

超链接下载

默认下载

<!-- 当超链接遇到浏览器不识别的资源时,会自动下载 -->
<a href="test.zip">超链接下载</a>

指定download属性下载(download不设置值时,会使用默认文件名)

<!-- 当超链接遇到浏览器可识别的资源时,可通过download属性下载 -->
<a href="test.txt" download="test02.txt">超链接下载</a>

后台实现下载

@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("文件下载...");

        //设置请求的编码格式
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //获取参数(得到要下载的文件名)
        String fileName = req.getParameter("fileName");
        //参数的非空判断 trim():去除字符串的前后空格
        if (fileName != null || "".equals(fileName.trim())) {
            resp.getWriter().write("请输入要下载的文件名!");
            resp.getWriter().close();
            return;
        }
        //得到图片存放的路径
        String path = req.getServletContext().getRealPath("/download/");
        //通过路径得到file对象
        File file = new File(path + fileName);
        //判断文件对象是否存在并且是一个标准文件
        if (file.exists() && file.isFile()){
            //设置浏览器无法激活的响应类型
            resp.setContentType("application/x-msdownload");
            //设置响应头
            resp.setHeader("Content-Disposition","attachment;filename=" + fileName);
            //得到file文件的输入流
            InputStream in = new FileInputStream(file);
            //得到字节输出流
            ServletOutputStream out = resp.getOutputStream();
            //定义byte数组
            byte[] bytes = new byte[1024];
            //定义长度
            int len = 0;
            //循环输出
            while ((len = in.read(bytes))!=-1){
                //输出
                out.write(bytes,0,len);
            }
            //闭流
            out.close();
            in.close();
        }else {
            resp.getWriter().write("文件不存在,请重试!");
            resp.getWriter().close();
        }
    }
}
JSP和JSTL
image-20210613202646690

JSP:(Java Server Page),是Sun公司提供的动态网页编程技术,是JavaWeb服务端的动态资源。

  • HTML只能提供静态数据,而JSP可以在页面中嵌套java代码,为用户提供动态数据。
  • Servlet很难对数据进行排版,而JSP很容易排版。

现在,servlet一般作为web应用中的控制器组建来使用,而把JSP技术作为数据显示模版来使用。

JSP注释
  • 显式注释(客户端可以看见,继承HTML风格的注释)

    <!-- HTML注释 -->

  • 隐式注释(客户端无法看见)

    • JSP自己的注释<%-- JSP自己的注释 -->
    • 继承Java风格的注释//单行注释/*多行注释*/

不建议在JSP中写Java代码(耦合度会非常高)

Scriptlet
  1. 第一种:<% %>:Java脚本段,可以定义局部变量、编写语句
  2. 第二种:<%! %>:声明,可以定义全局(成员)变量、方法、类
  3. 第三种:<%= %>:表达式,输出一个变量或者具体内容
JSP指令标签
  • 静态包含

    格式:

    <%@include file="要包含的页面路径"%>

    特点:

    1. 将内容进行了直接替换
    2. 静态包含只会生成一个源码文件
    3. 不能出现同名变量
    4. 运行效率高一点点,但是耦合度较高,不够灵活
  • 动态包含

    格式:

    <jsp:include page="要包含的页面路径"></jsp:include>

    特点:

    1. 动态包含相当于方法的调用
    2. 动态包含会生成多个源码文件
    3. 可以定义同名变量
    4. 效率高,耦合度低

    ⚠️注意:当动态包含不需要传递参数时,include双标签之间不要有任何内容,包括空格和换行,否则会报错。

    使用动态包含传递参数:

    <jsp:include page="要包含的页面路径">
        <jsp:param name="参数名" value="参数值"/>
    </jsp:include>
    

    ⚠️注意:name属性不支持表达式,value属性支持表达式。

JSP的四大域对象
  1. pageContext(当前页面有效,跳转后失效)

    pageContext.setAttribute("name1","zhangsan");

  2. request(常用)(一次请求中有效,服务端跳转有效,客户端跳转失效)

    request.setAttribute("name2","lisi");

  3. session(一次会话中有效,服务端和客户端跳转都有效)

    session.setAttribute("name3","wanger");

  4. application(在整个应用中有效)

    application.setAttribute("name4","mazi");

JSP中的跳转方式:

  • 服务端跳转:

    <jsp:forward page="跳转的地址"></jsp:forward>

  • 客户端跳转:

    <a href="跳转的地址">跳转</a>

EL表达式

${域对象的名称}

EL表达式一般操作的都是域对象中的数据,操作不了局部变量。

⚠️注意:

​ 1. 如果EL表达式获取的域对象的值为空,则默认显示空字符串。

​ 2. EL表达式默认从小到大去找,找的即止,没找到显示空字符串。

获取指定范围的域对象

  • page范围:${pageScope.uname}
  • request范围:${requestScope.uname}
  • session范围:${sessionScope.uname}
  • application范围:${applicationScope.uname}
JSTL

Java Server Pages Standard Tag Library(JSTL)

JSP标准标签库,用于解决一些常见的问题,比如迭代一个映射或者集合、条件测试、XML处理,甚至数据库和访问数据库操作等。

用户登录小练习

  1. 数据库对应的用户表 tb_user

  2. 前端

  • 登录页面 login.jsp

    用户登录 js校验

    登录表单验证

    1. 给登录按钮绑定点击事件(通过id选择器绑定)

    2. 获取用户名和密码的值

    3. 判断姓名是否为空

      如果姓名为空,提示用户(span标签赋值),并且return;

    4. 判断密码是否为空

      如果密码为空,提示用户(span标签赋值),并且return;

    5. 如果都不为空,则手动提交表单

  • 首页

  1. 后端
  • 登录功能

    思路:

    1. 接收客户端的请求(接收参数:用户名、密码)

    2. 参数的非空判断

      如果参数为空:

      ​ 通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)

      ​ 将消息模型对象设置到request作用域中

      ​ 请求转发跳转到登录界面

      ​ return;

    3. 通过用户名查询用户对象

    4. 判断用户对象是否为空

      如果为空:

      ​ 通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)

      ​ 将消息模型对象设置到request作用域中

      ​ 请求转发跳转到登录界面

      ​ return;

    5. 将数据库中查询到的用户密码与前台传递的密码作比较

      如果不相等:

      ​ 通过消息模型对象返回结果(设置状态、设置提示信息、回显数据)

      ​ 将消息模型对象设置到request作用域中

      ​ 请求转发跳转到登录界面

      如果相等,表示登录成功:

      ​ 将用户信息设置到session作用域中

      ​ 重定向跳转到首页;

controlelr层:(接收请求,响应结果)

  1. 接收客户端的请求(接收参数:用户名、密码)

  2. 调用service层的方法,返回消息模型对象

  3. 判断消息模型的状态码

    如果状态码 = 失败

    ​ 将消息模型对象设置到request作用域中,请求转发跳转到login.jsp

    如果状态码 = 成功

    ​ 将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp

service层:(业务逻辑)

  1. 参数的非空判断

    如果参数为空

    ​ 将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象

  2. 调用dao层的查询方法,通过用户名查询用户对象

  3. 判断用户对象是否为空

    如果为空:

    ​ 将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象

  4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较

    如果不相等:

    ​ 将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象

  5. 登录成功,成功状态、提示信息、用户对象设置消息模型对象,并return。

mapper层(Dao层):

定义对应的接口。

分层思想(解耦:高内聚,低耦合)

controller层:

​ 接收请求

​ (调用service层,返回结果)

​ 返回结果

service层:

​ 处理业务逻辑判断

mapper层:

​ 接口类

​ mapper.xml mybatis与数据库的相关操作

entity层(pojo、model)

​ JavaBean实体类

util:

​ 工具类(通用的方法/类)

test:

​ 测试类/方法

项目文件目录截图:
image-20210618224534122
前端页面:

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
<div style="text-align: center">
    <form action="login" method="post" id="loginForm">
        用户名:<input type="text" name="uname" id="uname" value="${messageModel.object.userName}"> <br>
        密码:<input type="password" name="upwd" id="upwd" value="${messageModel.object.userPwd}"> <br>
        <span id="msg" style="font-size: 12px;color: red">${messageModel.msg}</span> <br>
        <button type="button" id="loginBtn">登录</button>
        <button type="button">注册</button>
    </form>
</div>
</body>

<%--引入Jquery的js文件--%>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript"></script>
<script type="text/javascript">
   /* * 登录页面 login.jsp
        用户登录 js校验
        登录表单验证
        1. 给登录按钮绑定点击事件(通过id选择器绑定)
        2. 获取用户名和密码的值
        3. 判断姓名是否为空
            如果姓名为空,提示用户(span标签赋值),并且return;
        4. 判断密码是否为空
            如果密码为空,提示用户(span标签赋值),并且return;
        5. 如果都不为空,则手动提交表单
    */

    $("#loginBtn").click(function (){
        //获取用户名和密码
        var uname = $("#uname").val();
        var upwd = $("#upwd").val();
        //判断用户名是否为空
        if (isEmpty(uname)){
            // 判断姓名是否为空
            // 如果姓名为空,提示用户(span标签赋值),并且return;
            $("#msg").html("用户名不可为空!");
            return ;
        }
        //判断密码是否为空
        if (isEmpty(upwd)){
            // 判断密码是否为空
            // 如果密码为空,提示用户(span标签赋值),并且return;
            $("#msg").html("密码不可为空!");
            return ;
        }
        //如果都不为空,则手动提交表单
        $("#loginForm").submit();

    });

    // 判断字符串是否为空。
    // 如果为空,返回true,
    // 如果不为空,返回false;
    function isEmpty(str){
        if (str == null || str.trim() === ""){
            return true;
        }
            return false;
    }
</script>
</html>

后端实现:

UserServlet

@WebServlet("/login")
public class UserServlet extends HttpServlet {
    //实例化UserService对象
    private UserService userService = new UserService();

    /**
     * 用户登录
     * controlelr层:(接收请求,响应结果)
     *                     1. 接收客户端的请求(接收参数:用户名、密码)
     *                     2. 调用service层的方法,返回消息模型对象
     *                     3. 判断消息模型的状态码
     *                         如果状态码 = 失败
     *                             将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
     *                         如果状态码 = 成功
     *                             将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 接收客户端的请求(接收参数:用户名、密码)
        String uname = req.getParameter("uname");
        String upwd = req.getParameter("upwd");
        //2. 调用service层的方法,返回消息模型对象
        MessageModel messageModel = userService.userLogin(uname,upwd);
        //3. 判断消息模型的状态码
        if (messageModel.getCode() == 1){
            //将消息模型中的用户信息设置到session作用域中,重定向跳转到index.jsp
            req.getSession().setAttribute("user",messageModel.getObject());
            resp.sendRedirect("index.jsp");
        }else {
            //将消息模型对象设置到request作用域中,请求转发跳转到login.jsp
            req.setAttribute("messageModel",messageModel);
            req.getRequestDispatcher("login.jsp").forward(req,resp);
        }
    }
}

MessageModel

/**
 * 消息模型对象(数据响应)
 *  状态码:
 *      1:成功 ,0:失败
 *  提示信息:
 *      字符串
 *  回显数据:
 *      Object对象
 */
public class MessageModel {
    private Integer code = 1;//状态码:(1=成功,0=失败)
    private String msg = "成功";//提示信息
    private Object object;//回显对象(基本数据类型,字符串类型,List,Map等)

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
}

User

public class User {
    private Integer userId;
    private String userName;
    private String userPwd;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
}

UserMapper

public interface UserMapper {
    public User queryUserByName(String userName);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 首先解析 namespace:命名空间,此属性通常用来映射Dao(Mapper)层接口 -->
<mapper namespace="com.nanfu.mapper.UserMapper">
    <!-- id:对应Dao(Mapper)层接口方法名;parameterType:指定输入参数类型 -->
    <!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->
    <select id="queryUserByName" parameterType="string" resultType="com.nanfu.entity.User">
        select * from tb_user where userName = #{userName}
    </select>
</mapper>

UserService

/**
 * 业务逻辑
 * 用户登录
 */
public class UserService {
    /**
     * service层:(业务逻辑)
     *                     1. 参数的非空判断
     *                         如果参数为空
     *                             将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
     *                     2. 调用dao层的查询方法,通过用户名查询用户对象
     *                     3. 判断用户对象是否为空
     *                             如果为空,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
     *                     4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较
     *                             如果不相等,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
     *                     5. 登录成功,成功状态、提示信息、用户对象设置消息模型对象,并return。
     * @param uname
     * @param upwd
     * @return
     */
    public MessageModel userLogin(String uname, String upwd) {
        MessageModel messageModel = new MessageModel();

        //回显数据
        User u = new User();
        u.setUserName(uname);
        u.setUserPwd(upwd);
        messageModel.setObject(u);
        //1. 参数的非空判断
        if (StringUtil.isEmpty(uname) || StringUtil.isEmpty(upwd)) {
            //将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
            messageModel.setCode(0);
            messageModel.setMsg("用户名和密码不能为空!");
            return messageModel;
        }

        //2. 调用dao层的查询方法,通过用户名查询用户对象
        SqlSession session = GetSqlSession.createSqlSession();
        UserMapper usermapper = session.getMapper(UserMapper.class);
        User user = usermapper.queryUserByName(uname);

        //3. 判断用户对象是否为空
        if (user == null) {
            //将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
            messageModel.setCode(0);
            messageModel.setMsg("用户不存在!");
            return messageModel;
        }

        //4. 判断数据库中查询到的用户密码与前台传递过来的密码作比较
        if (!upwd.equals(user.getUserPwd())){
            //如果不相等,将状态码、提示信息、回显数据设置到消息模型对象中,返回消息模型对象
            messageModel.setCode(0);
            messageModel.setMsg("用户密码不正确!");
            return messageModel;
        }

        //5. 登录成功,成功状态、提示信息、用户对象设置消息模型对象,并return。
        messageModel.setObject(user);
        return messageModel;

    }
}

Test

public class Test {
    public static void main(String[] args) {
        //获取sqlSession对象
        SqlSession session = GetSqlSession.createSqlSession();
        //得到对应的Mapper
        UserMapper userMapper = session.getMapper(UserMapper.class);
        //调用方法,返回用户对象
        User user = userMapper.queryUserByName("admin");
        System.out.println(user);
    }
}

GetSqlSession

public class GetSqlSession {

    //获取SqlSession对象

    public static SqlSession createSqlSession(){
        SqlSessionFactory sqlSessionFactory = null;
        InputStream input = null;
        SqlSession session =null;
        try {
            //获得mybatis的环境配置文件
            String resource = "mybatis-config.xml";
            //以流的方式获取resource(mybatis的环境配置文件)
            input = Resources.getResourceAsStream(resource);
            //创建会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
            //通过工厂得到SqlSession
            session = sqlSessionFactory.openSession();
            return session;
        }catch (IOException e){
            e.printStackTrace();
            return null;
        }
    }


    public static void main(String[] args) {
        System.out.println(createSqlSession());
    }
}

StringUtil

/**
 * 字符串工具类
 *  判断字符串是否为空:
 *      如果为空,则返回true;
 *      如果不为空,则返回false;
 */
public class StringUtil {
    public static boolean isEmpty(String str){
        if (str == null || "".equals(str.trim())){
            return true;
        }else {
            return false;
        }
    }
}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--对事物的管理和链接池的配置-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/java_test?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--mappers映射器-->
    <mappers>
        <!--方式1:一个一个的配置mapper-->
<!--        <mapper resource="mapper/userMapper.xml"/>-->

        <!--方式2:自动扫描包内的mapper接口与配置文件-->
        <package name="com.nanfu.mapper"></package>
    </mappers>



</configuration>

mysql.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/java_test?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC"
username=root
password=root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值