demo_2
业务层
package com.demo.service;
import com.demo.pojo.User;
public interface IUserService {
/**
* 用户登录
* @param user 用户信息
* @return 返回数据
*/
User reg(User user);
}
实现类
创建`com.demo.service.Impl.UserServiceImpl`类,使用`@Service("userService")`对类注解,声明`private UserMapper userMapper`成员,并使用`@Autowired`注解,实现`IUserService`,实现抽象方法:
package com.demo.service.Impl; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.demo.dao.UserMapper;
import com.demo.pojo.User;
import com.demo.service.IUserService; //实现类
@Service("userService")
public class UsertServiceImpl implements IUserService{
@Autowired
private UserMapper userMapper; public User reg(User user) {
userMapper.insert(user);
return user;
} }
在业务层,关于操作的成功与否,推荐:只要能把方法顺利执行结束,就是成功,如果中途出错,则抛出异常,后续,方法的调用者(控制器层的某个方法)通过try...catch来处理。
## 关于密码
package 测试;
import java.util.UUID;
import org.springframework.util.DigestUtils;
public class 设计密码 {
public static void main(String[] args) {
//文摘
System.out.println("Digest");
//密码
String[] password = {"123456","000000","654321"};
UUID salt = UUID.randomUUID();//随机盐
System.out.println(salt.toString().length());//长度
for (int i = 0; i < password.length; i++) {//双重加盐
String md5Str = DigestUtils.md5DigestAsHex(password[i].getBytes());
md5Str = DigestUtils.md5DigestAsHex((salt+md5Str).getBytes());
System.out.println(md5Str.toUpperCase());
}
}
}
## 查询用户信息--持久层
实现根据用户名查询用户信息,所以,在`UserMapper`接口中添加新的抽象方法:
/**
* 查询用户信息
* @param where WHERE子句,不要包含WHERE关键字
* @param orderBy OrderBy子句,不要包含Order By关键字
* @param offset 偏移量,用于Limit子句的第一个值
* @param countPerPage 每页显示的数据量,用于Limit子句的第二个值,仅当参数offset有效时,该参数才有效,如果没有提供offset值,则该参数没有意义
* @return 配置的用户信息的集合
*/
List<User> select (
@Param("where") String where,
@Param("orderBy") String orderBy,
@Param("offset") Integer offset,
@Param("countPerPage") Integer countPerPage
);
然后,在`UserMapper.xml`中添加映射:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> <!-- namespace:匹配的接口 -->
<mapper namespace="com.demo.dao.UserMapper"> <!-- 查询用户信息 -->
<!-- List<User> select(
@Param("where") String where,
@Param("orderBy") String orderBy,
@Param("offset") Integer offset,
@Param("countPerPage") Integer countPerPage);
-->
<select id="select" resultType="com.demo.pojo.User">
SELECT
id,username,password,gender,phone,email,uuid,
created_user AS createdUser,
created_time AS createdTime,
modified_user AS modifiedUser,
modified_Time AS modifiedTime
FROM
t_user
<if test="where != null">
WHERE ${where}
</if>
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
<if test="offset != null">
LIMIT ${offset},${countPerPage}
</if>
</select>
</mapper>
##SQL语句中#{ }和${ }的区别
#将传入的数据都当成字符串,会对自动传入的数据加一个双引号。如:order by #{user_id},如果传入的值是123,那么解析成SQL时的值为order by "123",如果传入的值是id,则解析成的SQL为order by "id"。
$将传入的数据直接显示生成在SQL中。如:order by ${user_id},如果传入的值是123,那么解析成SQL时的值为order by user_id,如果传入的值是id,则解析成的SQL为order by id。
#方式能够很大程度防止sql注入;$方式无法防止Sql注入。
$方式一般用于传入数据库对象,例如传入表名。
一般能用#的就别用$。MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。
比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName};
这里MyBatis不会修改或转义字符串。
接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
## 查询用户信息--业务层
在业务层接口`IUserService`接口中添加抽象方法:
package com.demo.service; import com.demo.pojo.User; //业务层
public interface IUserService { /**
* 根据用户名查询信息
*
* @param username 用户名
* @return 用户信息,如果没有匹配的用户信息,则返回null
*/
User findUserByUsername(String username); /**
* 获取加密的密码
*
* @param password 明文密码
* @param salt 盐
* @return 密文密码
*/
String getEncrpytedPassword(String password, String salt);
}
## 在实现类`UserServiceImpl`中实现以上方法(更新注册方法--业务层逻辑):
package com.demo.service.Impl; import java.util.Date;
import java.util.List;
import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils; import com.demo.dao.UserMapper;
import com.demo.pojo.User;
import com.demo.service.IUserService;
import com.demo.service.ex.UsernameConflictException; //实现类
@Service("userService")
public class UsertServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper; public User reg(User user) {
//根据尝试注册的用户名进行查询
User u = findUserByUsername(user.getUsername());
//判断用户名是否被占用
if (u !=null) {
//用户名被占用,则:
throw new UsernameConflictException("用户名" + user.getUsername() + "已经被注册!");
} else {
//用户名没有被占用,则执行注册相关任务
//把密码加密
String salt = UUID.randomUUID().toString().toUpperCase();
String md5Password = getEncrpytedPassword(user.getPassword(), salt);
user.setPassword(md5Password);
//保存uuid,即盐
user.setUuid(salt);
//保存日志信息
Date now = new Date();
user.setCreatedUser("System");
user.setCreatedTime(now);
user.setModifiedUser("System");
user.setModifiedTime(now);
//使用Mybatis处理insert后
//数据的id将被封装到参数对象中
//在执行以下代码之前,参数user中并没有id
//执行完后,Mybatis将把id封装到参数对象user中
userMapper.insert(user);
return user;
}
} public User findUserByUsername(String username) {
// 确定WHERE子句的内容
String WHERE = "username='" + username + "'";
// 调用持久层对象执行查询
List<User> users = userMapper.select(WHERE, null, null, null);
// 判断查询结果
if (users.size() == 0) {
// 没有找到数据,则用户名不存在
return null;
} else {
// 找到数据,由于用户名唯一
// 则集合中的第一个元素就是要查询的数据
return users.get(0);
}
} public String getEncrpytedPassword(String password, String salt) {
// 把密码与盐拼接起来
String str = password + salt;
// 获取拼接后的字符串的消息摘要
String md5 = DigestUtils.md5DigestAsHex(str.getBytes()).toUpperCase();
// 返回摘要字符串,即密文
return md5;
} }
demo_2的更多相关文章
- Demo_2:Qt实现猜字小游戏
1 环境 系统:windows 10 代码编写运行环境:Qt Creator 4.4.1 (community) Github: 2 简介 参考视频:https://www.bilibili.co ...
- Java 零基础之作业小练习
[练习1] 需求:输入学员的名称及总科目数并显示每项科目成绩的分数,算出总成绩. package demo2; import java.util.Scanner; //先import Scanner语 ...
- 类Collections的静态方法的使用(代码)
package cn.itcast.p2.toolclass.collections.demo; import java.util.ArrayList; import java.util.Collec ...
- 黑马程序员_Java基础:多线程总结
------- android培训.java培训.期待与您交流! ---------- 一.多线程的概念 进程和线程经常会被人混淆,那是因为对它们的概念不明确.就拿我们平时使用的操作系统来说,它是多任 ...
- java-API中的常用类,新特性之-泛型,高级For循环,可变参数
API中的常用类 System类System类包含一些有用的类字段和方法.它不能被实例化.属性和方法都是静态的. out,标准输出,默认打印在控制台上.通过和PrintStream打印流中的方法组合构 ...
- Mysql存储过程语法
一口气弄完了! 一.条件语句if-then-else: create procedure demo_1(in param int) begin declare var int; ; then inse ...
- canvas 2d 贴图技术实践
最近在公司内部的技术协会论坛里闲逛的时候,无意中发现了一篇手淘前端大牛岑安两年前写的博文,讲述了canvas的2d贴图技术.看到后觉得相当神奇.于是就自己实现了一下.不过岑安前辈的那篇博文也只是大概讲 ...
- java异常类
package shb.java.exception; /** * 测试异常类 * @Package:shb.java.exception * @Description: * @author shao ...
- Vue.js相关知识2-组件
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
随机推荐
- 你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域
原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到 ...
- 树莓派3B+上运行.Net Core项目
最近买了个树莓派3B+,准备把自己写的一个.Net Core爬虫挂在上面跑 买之前没有想到树莓派因为是今年新出的,导致驱动以及系统啥的都不是很完善,导致走了很多弯路,早知道买树莓派3就不用那么多折腾了 ...
- 删除API
Delete API 删除API允许根据ID从指定索引中删除一个类型化的JSON文档. DELETE /twitter/_doc/1 返回结果如下: { "_index": &qu ...
- centos7 mysql自动备份
MySQL自动备份shell脚本 在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分 ...
- python os.walk()方法--遍历当前目录的方法
前记:有个奇妙的想法并想使用代码实现,发现了一个坑,百度了好久也没发现的"填坑"的文章~~~~~~~~~ 那就由我来填 os.walk()支持相对路径 例如 os.walk(&qu ...
- DOS命令(二)
1. findstr “要查找的字符串” 文件,用来从文件中检索包含相关内容的字符串集合. [例如:查找包含“TTL”的字符串] 2. del 要删除的文件,用来删除某个文件. 3. pause,用 ...
- nova boot from volume代码分析
首先要创建一个bootable volume curl -i http://16.158.166.197:8776/v1/c24c59846a7f44538d958e7548cc74a3/volume ...
- SUSE12Sp3-Nginx安装
1.安装pcre(nginx 依赖) 把安装包pcre-8.12.tar.gz复制到服务器指定目录 tar -zxvf pcre-8.12.tar.gz # 解压 cd pcre-8.12 #进入目录 ...
- [Swift]LeetCode826. 安排工作以达到最大收益 | Most Profit Assigning Work
We have jobs: difficulty[i] is the difficulty of the ith job, and profit[i] is the profit of the ith ...
- [Swift]LeetCode919. 完全二叉树插入器 | Complete Binary Tree Inserter
A complete binary tree is a binary tree in which every level, except possibly the last, is completel ...