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" ...
随机推荐
- oracle数据库完全卸载步骤
1.关闭oracle所有的服务.可以在windows的服务管理器中关闭; 2.打开注册表:regedit 打开路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlS ...
- Android Studio 全局内替换字符串
Ctrl+Shift+R
- Oracle SQL性能优化的40条军规
1. SQL语句执行步骤 语法分析> 语义分析> 视图转换 >表达式转换> 选择优化器 >选择连接方式 >选择连接顺序 >选择数据的搜索路径 >运行“执 ...
- Java开发快速上手
Java开发快速上手 前言 1.我的大学 2.对初学者的建议 3.大牛的三大特点 4.与他人的差距 第一章 了解Java开发语言 前言 基础常识 1.1 什么是Java 1.1.1 跨平台性 1.2 ...
- [Swift]LeetCode332. 重新安排行程 | Reconstruct Itinerary
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...
- [Swift]LeetCode466. 统计重复个数 | Count The Repetitions
Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc&qu ...
- [Swift]LeetCode890. 查找和替换模式 | Find and Replace Pattern
You have a list of words and a pattern, and you want to know which words in words matches the patter ...
- Hystrix概念设计
1. Hystrix概念设计 1.1. 大纲 1.2. 基本的容错模式 1.3. 断路器模式 1.4. 舱壁隔离模式 1.5. 容错理念 凡事依赖都可能失败 凡事资源都有限制 网络并不可靠 延迟是应用 ...
- C++函数重载,重写,重定义
目录 1 重载 2 重写 3 重定义 4 函数重载二义性 笔者原创,转载请注明出处 C++中经常会提到重载,除了重载,还有重写,重定义,下面对这三个概念逐一进行区分 1 重载 函数重载是同 ...
- ubuntu中环境变量的几个问题思考
问题一:export PATH=$PATH:/usr/local和export PATH=/usr/local:$PATH这两个的区别是什么?可以随便用吗? 这两个都是要把该目录加到环境变量中,一般的 ...