day36、37 java Spring 模拟登录逻辑(二)


I know, i know
地球另一端有你陪我




一、单机版

package com.fgh.spring.test;

import com.fgh.spring.util.JDBCUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/*
    @RestController   返回数据
    @Controller       返回页面(即文件夹)
    一般存放于resources\templates(html)
    需要下载包和指定路径

    Spring自动识别注解
    @RestController当前类与前段地址绑定
    @RequestMapping("/name") 把类下的方法,与注解路径绑定
    http://localhost/8080/name
    name不可重复!被注释了也不行!

    http://localhost:8080/login?name=root&pass=123456
    传参的格式

    第一种方式:全堆在一起
 */
@RestController
public class UserController {
    
    

    @RequestMapping("/test")
    public String test() {
    
    
        return "start2";
    }

    @RequestMapping("/login")
    public String login(String name, String pass) {
    
    
        if (!"root".equals(name) || !"123456".equals(pass)) {
    
    
            return "失败";
        }
        return "成功";
    }

    @RequestMapping("/userlogin")
    public String userlogin(String name, String pass) {
    
    

        try {
    
    

            JDBCUtil.getConn();
            String sql = "select * from user where username=?";
            PreparedStatement ps = JDBCUtil.getPs(sql);
            ps.setString(1,name);
            ResultSet rs = JDBCUtil.getRs();

            if (!rs.next()) {
    
    
                return "用户名不存在";
            }

            User user = new User(rs.getString("id"),
                    rs.getString("username"),
                    rs.getString("password"));

            if (!user.getPassword().equals(pass)) {
    
    
                return "密码错误";
            }

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return "登录成功";
    }

}

二、引入分层

bean :存放资源文件
controller :表现层 / 前端交互
service :业务逻辑层 / 逻辑验证
dao :持久层 / 连接SQL

bean
存储对象类的基本信息
需要导包
lombok.jar

package com.fgh.spring.mvc.bean;
/*
    lombok.jar
    可以在自定义类中自动添加
    有(无)参构造
    get、set方法
    tosString方法等
 */
import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
    
    
    private String id;
    private String username;
    private String password;
}

dao :持久层 / 连接SQL

package com.fgh.spring.mvc.dao;

import com.fgh.spring.mvc.bean.User;
import com.fgh.spring.util.JDBCUtil;

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

public class UserDao {
    
    

    //连接数据库
    //按照输入的name从数据库中获得对应的数据
    //存储到 user 对象之中,并返回
    public User getuser(String username){
    
    
    User user=null;
    try {
    
    
        Connection conn = JDBCUtil.getConn();
        String sql = "select * from user where username=?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1,username);
        ResultSet rs = ps.executeQuery();
        if(rs.next()){
    
    
        	user = new User();
            user.setId(rs.getString("id"));
            user.setUsername(rs.getString("username"));
            user.setPassword(rs.getString("password"));
            rs.close();
            ps.close();
            //此处连接的关闭,是将连接放回连接池
            conn.close();
        }
    } catch (SQLException e) {
    
    
        e.printStackTrace();
    }
    return user;
    }
}

service :业务逻辑层 / 逻辑验证

package com.fgh.spring.mvc.service;

import com.fgh.spring.mvc.bean.User;
import com.fgh.spring.mvc.dao.UserDao;
//业务逻辑层 验证
public class UserService {
    
    
    public String checkUser(String username, String password) {
    
    
        if (username == null) {
    
    
            return "请填写用户名";
        }

        UserDao ud = new UserDao();
        User user = ud.getuser(username);

        if (user == null) {
    
    
            return "用户名不存在";
        }

        if (!user.getPassword().equals(password)) {
    
    
            return "用户名或密码错误";
        }
        return "登陆成功";
    }
}

controller :表现层 / 前端交互

package com.fgh.spring.mvc.controller;

import com.fgh.spring.mvc.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    
    
    @RequestMapping("/login")
    public String login(String username,String password){
    
    
        UserService us = new UserService();
        String message = us.checkUser(username, password);
        return message;
    }
}

1、优化:连接池

需要导包
dbcp2.jar
一个池子里塞多个连接

JDBCUtil JDBC工具

package com.fgh.spring.util;

/*
    连接池,同时储存多个连接
    可以让系统在使用连接的时候
    拥有一定的容错
        例如当网络中断后,
        原本的静态代码块只会运行一次,所有就会彻底中断连接
        而连接池可以保证再次联网后,可以使用另一个连接
 */

import org.apache.commons.dbcp2.BasicDataSource;

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

public class JDBCUtil {
    
    

    private static BasicDataSource bds;

    //创建连接池
    static{
    
    
        //创建连接池对象
        bds = new BasicDataSource();
        //配置连接池大小
        bds.setInitialSize(5);

        //配置连接信息
        bds.setUrl("jdbc:mysql://master:3306/fghdata?useUnicode=true&characterEncoding=utf-8");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUsername("root");
        bds.setPassword("123456");
    }

    public static Connection getConn(){
    
    
        try {
    
    
            return bds.getConnection();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }
}

2、优化:加入缓冲

缓冲是应对被高频访问的对象
将对象提前提前取出并储存,跳过搜索数据库步骤
可以大幅度提高效率
考虑到其特性,此处使用 HashMap 实现

service

    //创建 HashMap 作为缓冲区
    private static HashMap<String, User> map = new HashMap<String, User>();
    public String selectUser(String id) {
    
    
        /**
         * 1.先查缓存
         *  1.1有:直接返回数据
         *  1.2没有:去数据库中查,并把结果保存到缓存
         */
        // 先查缓存 有:直接返回数据
        if (map.containsKey(id)) {
    
    
            System.out.println("存在");
            return map.get(id).toString();
        }
        //1.2没有:去数据库中查,并把结果保存到缓存
        UserDao userDao = new UserDao();
        User students = userDao.select(id);
        if (students == null) {
    
    
            return "用户不存在";
        }
        map.put(students.getId(), students);
        System.out.println("存储到缓存" + map.get(id).getId());
        return students.toString();
    }

3、优化:加入接口

为了应对不同场景下的自由切换,如 mysql 和其他数据库的切换
尽可能的减少代码的修改,会使用不同的类来加载同名的方法
此时引入接口,将会让代码变得更为规范和易处理

interface UserDao {
    
    
    //连接数据库
    //按照输入的name从数据库中获得对应的数据
    //存储到 user 对象之中,并返回
    public abstract User getuser(String username);
    
    public User select(String id);
}
public class UserDaoMySqlImp implements UserDao{
    
    
    //连接数据库
    //按照输入的name从数据库中获得对应的数据
    //存储到 user 对象之中,并返回
    public User getuser(String username){
    
    

        User user=null;

        try {
    
    

            Connection conn = JDBCUtil.getConn();

            String sql = "select * from user where username=?";

            PreparedStatement ps = conn.prepareStatement(sql);

            ps.setString(1,username);

            ResultSet rs = ps.executeQuery();

            if(rs.next()){
    
    
                user = new User();
                user.setId(rs.getString("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));

                rs.close();
                ps.close();
                conn.close();
            }
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return user;
    }


    public User select(String id){
    
    

        User user=null;

        try {
    
    
            Connection conn = JDBCUtil.getConn();
            PreparedStatement ps = 
            conn.prepareStatement("select * from students where id=?");

            ps.setString(1,id);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
    
    
                user = new User();
                user.setId(rs.getString("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                rs.close();
                ps.close();
                conn.close();
            }

        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return user;
    }
}

总结

1、@RequestMapping 不允许重名

2、地址中,使用?username=xxx&password=xxx,进行传参

3、executequarry() 返回的并不是一个集合,可以理解为是一个 sql 表格
      可以通过列名获得一整列元素

4、连接池中的 close,是将连接放回连接池中

Guess you like

Origin blog.csdn.net/qq_41464008/article/details/121288581