目录
学习目标:
在春招时可以拿出一项值得出手的项目,顺便将毕业设计完成
学习内容:
基本功能模块
实现用户登录(后端)
新思想:以前都是用用户名和密码一起去数据库找,两个都需要找一遍,现在换一种思想先去搜索用户名有没有用户记录,然后再去用密码去数据库寻找,只需要遍历一次数据库。
整理思路确认如何实现
一、用户登录 后端实现 整体思路: 1.参数判断 用户姓名 非空判断 用户密码 非空判断 2.通过用户名查询用户记录,返回用户对象 3.判断用户对象是否为空 4.如果用户对象不为空,则将前台传递的用户密码与数据库的密码作比较 5.判断密码是否正确 6.如果密码正确,则登录成功,返回结果 Controller层 (控制层:接受请求、响应结果) 1.通过形参接受客户端传递的参数 2.调用业务逻辑层的登录方法,得到登录结果 3.响应数据给客户端 Service层 (业务逻辑层:非空判断、条件判断等业务逻辑) 1.参数判断,判断用户姓名、用户密码非空 如果参数为空,抛出异常(异常被控制层捕获并处理) 2.调用数据访问层,过用户名查询用户记录,返回用户对象 3.判断用户对象是否为空 如果参数为空,抛出异常(异常被控制层捕获并处理) 4.判断密码是否正确,比较客户端传递的用户密码与数据空中查询的用户对象密码 如果密码不相等,抛出异常(异常被控制层捕获并处理) 5.如果密码正确,登陆成功 Dao层 (数据访问层:数据库中增删改查操作) 通过用户名查询用户记录,返回用户对象
导入自定义的工具类和异常类
使用generator工具来实现根据表来生成代码
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 数据库驱动 -->
<classPathEntry location="C:\soft\maven\libstorage\mysql\mysql-connector-java\8.0.18\mysql-connector-java-8.0.18.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除日期那行注释 -->
<property name="suppressDate" value="true"/>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 数据库链接地址账号密码 -->
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/crm?serverTimezone=GMT%2B8"
userId="root"
password="qqxlq219229">
</jdbcConnection>
<!--
java类型处理器
用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和NUMERIC数据类型;
true:使用 BigDecimal对应DECIMAL和NUMERIC数据类型
false:默认,把JDBC DECIMAL和NUMERIC类型解析为Integer
-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成Model类存放位置 -->
<javaModelGenerator targetPackage="com.xxxx.crm.vo" targetProject="src/main/java">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true"/>
<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xxxx.crm.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="t_user" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>
自动生成了UserMapper、UserService、UserMapper.xml、User
根据思路开始从下往上构建
Dao层
实现通过用户名查询用户记录,返回用户对象的功能
UserMapper
基础类有大部分功能,将原有删除后,继承BaseMapper类然后再写根据用户记录查询用户对象的方法
package com.xxxx.crm.dao;
import com.xxxx.crm.base.BaseMapper;
import com.xxxx.crm.vo.User;
public interface UserMapper extends BaseMapper<User,Integer> {
//通过用户名查询用户记录返回用户对象
public User queryUserByName(String userame);
}
在UserMapper.xml中加入SQL语句
<!-- 通过用户名查询用户记录,返回用户对象 -->
<select id="queryUserByName" parameterType="string" resultType="com.xxxx.crm.vo.User">
select
<include refid="Base_Column_List"/>
from
t_user
where
user_name = #{userName}
</select>
Service层
先创建是否为空的方法来验证用户名和用户密码,抛出异常,创建一个UserModel来存储用户名,用户ID和用户真实名字来返回告诉UserController。
PS:这里用到AssertUtil类之中的方法,可以根据条件满足来抛出异常
然后根据UserName来查询用户记录,返回用户对象,再判断是否为空
新思想:加密密码,用MD5来加密算法,数据库中显示的不是密码而是加密后的密码,所以需要先将密码加密然后再和数据库中的密码相比较
最后返回UserModel
@Service
public class UserService extends BaseService<User, Integer> {
@Resource
private UserMapper userMapper;
/**
* @param userName 用户名
* @param userPwd 用户密码
* @return UserModel
* @author QQ星
* 1.参数判断,判断用户姓名、用户密码非空
* 如果参数为空,抛出异常(异常被控制层捕获并处理)
* 2.调用数据访问层,过用户名查询用户记录,返回用户对象
* 3.判断用户对象是否为空
* 如果参数为空,抛出异常(异常被控制层捕获并处理)
* 4.判断密码是否正确,比较客户端传递的用户密码与数据空中查询的用户对象密码
* 如果密码不相等,抛出异常(异常被控制层捕获并处理)
* 5.如果密码正确,登陆成功
* @Date 2022/2/22 16:35
*/
public UserModel userLogin(String userName, String userPwd) {
// 1.参数判断,判断用户姓名、用户密码非空
checkLoginParams(userName, userPwd);
// 2.调用数据访问层,过用户名查询用户记录,返回用户对象
User user = userMapper.queryUserByName(userName);
//3.判断用户对象是否为空
AssertUtil.isTrue(user == null, "用户姓名不存在");
//4.判断密码是否正确,比较客户端传递的用户密码与数据空中查询的用户对象密码
checkUserPwd(userPwd, user.getUserpwd());
//返回构建用户对象
return buildUserInfo(user);
}
/**
* @param user
* @return com.xxxx.crm.model.UserModel
* @author QQ星
* 构建需要返回给客户端的用户对象
* @Date 2022/2/22 19:31
*/
private UserModel buildUserInfo(User user) {
UserModel userModel = new UserModel(user);
return userModel;
}
/**
* @param userPwd
* @param pwd
* @return void
* @author QQ星
* 密码判断
* 先将客户端传递的代码加密,在与数据库中查询到的代码作比较
* @Date 2022/2/22 18:56
*/
private void checkUserPwd(String userPwd, String pwd) {
//先将客户端传递的代码加密
userPwd = Md5Util.encode(userPwd);
//在与数据库中查询到的代码作比较
AssertUtil.isTrue(!userPwd.equals(pwd), "用户密码不正确");
}
/**
* @param userName
* @param userPwd
* @return void
* @author QQ星
* 参数判断
* @Date 2022/2/22 16:39
*/
private void checkLoginParams(String userName, String userPwd) {
//验证用户姓名
AssertUtil.isTrue(StringUtils.isBlank(userName), "用户名不能为空");
//验证用户密码
AssertUtil.isTrue(StringUtils.isBlank(userPwd), "用户密码不能为空");
}
}
Controller层
通过try catch捕获service层的异常,如果service层抛出异常,表示登录失败,否则登录成功
@Controller
public class UserController extends BaseController {
@Resource
private UserService userService;
/**
* @author QQ星
* 登录功能
* @param userName
* @param userPwd
* @return com.xxxx.crm.base.ResultInfo
* @Date 2022/2/22 19:37
*/
@GetMapping("login")
@ResponseBody
public ResultInfo userLogin(String userName, String userPwd) {
ResultInfo resultInfo = new ResultInfo();
//通过try catch捕获service层的异常,如果service层抛出异常,表示登录失败,否则登录成功
try {
//调用service层登录方法
UserModel userModel=userService.userLogin(userName, userPwd);
//设置ResultInfo的result的值 将数据返回给请求
resultInfo.setResult(userModel);
} catch (ParamsException p) {
resultInfo.setCode(p.getCode());
resultInfo.setMsg(p.getMsg());
p.printStackTrace();
} catch (Exception e) {
resultInfo.setCode(500);
resultInfo.setMsg("登录失败");
}
return resultInfo;
}
}
测试:
都为空
用户密码为空用户密码错误
登录成功
数据库:
遇到问题:
启动失败
寻找原因,因为generator生成实体类和数据库字段名不一致
全部改成对应名字即可
学习时间:
2022.2.22 10:45-12:24、15:34-17:26、18:48-0.18
学习心得:
今天登录界面后端代码主要是接触到了新的generator来生成代码,里面有许多问题,大小写转换不了,_消失,一直启动不了项目也是干着急,一天就这么时间浪费掉去了,还是挺难受的,看着报错信息自己有的时候真的看不出来,还是得继续努力,加油把!