业务层

 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的更多相关文章

  1. Demo_2:Qt实现猜字小游戏

    1  环境 系统:windows 10 代码编写运行环境:Qt Creator 4.4.1 (community) Github: 2  简介 参考视频:https://www.bilibili.co ...

  2. Java 零基础之作业小练习

    [练习1] 需求:输入学员的名称及总科目数并显示每项科目成绩的分数,算出总成绩. package demo2; import java.util.Scanner; //先import Scanner语 ...

  3. 类Collections的静态方法的使用(代码)

    package cn.itcast.p2.toolclass.collections.demo; import java.util.ArrayList; import java.util.Collec ...

  4. 黑马程序员_Java基础:多线程总结

    ------- android培训.java培训.期待与您交流! ---------- 一.多线程的概念 进程和线程经常会被人混淆,那是因为对它们的概念不明确.就拿我们平时使用的操作系统来说,它是多任 ...

  5. java-API中的常用类,新特性之-泛型,高级For循环,可变参数

    API中的常用类 System类System类包含一些有用的类字段和方法.它不能被实例化.属性和方法都是静态的. out,标准输出,默认打印在控制台上.通过和PrintStream打印流中的方法组合构 ...

  6. Mysql存储过程语法

    一口气弄完了! 一.条件语句if-then-else: create procedure demo_1(in param int) begin declare var int; ; then inse ...

  7. canvas 2d 贴图技术实践

    最近在公司内部的技术协会论坛里闲逛的时候,无意中发现了一篇手淘前端大牛岑安两年前写的博文,讲述了canvas的2d贴图技术.看到后觉得相当神奇.于是就自己实现了一下.不过岑安前辈的那篇博文也只是大概讲 ...

  8. java异常类

    package shb.java.exception; /** * 测试异常类 * @Package:shb.java.exception * @Description: * @author shao ...

  9. Vue.js相关知识2-组件

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. MySQL之爱之初体验

    写在前言:本篇博客从mysql的安装开始说起,至于什么是数据库以及数据的由来什么的,不在详谈!!! 第一:mysql安装 linux安装:两种方式 1.apt安装 apt install mysql- ...

  2. MVC编程模型

    MVC 编程模型 MVC 是三个 ASP.NET 开发模型之一. MVC 是用于构建 web 应用程序的一种框架,使用 MVC (Model View Controller) 设计: Model(模型 ...

  3. python语法_json_pickle

    ---恢复内容开始--- dic = {"name":"kevin","age":"20"} f = open(&quo ...

  4. 最快效率求出乱序数组中第k小的数

    题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k 的元素值 思路:这里很容易想到直接排序然后顺序查找,可以使用效率较高的快排,但是它的时间复杂度是O(nlgn),我们这里可以用一种简便的方法,不 ...

  5. Java面试大纲-java面试该做哪些准备,java开发达到这样的水平可以涨工资

    Java培训结束,面临的就是毕业找工作.在找工作时,就要针对性地做充分的面试准备.准备不充分的面试,完全是浪费时间,更是对自己的不负责. 上海尚学堂Java培训整理出Java面试大纲,其中大部分都是面 ...

  6. 浅谈Java中的锁:Synchronized、重入锁、读写锁

    Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...

  7. [Swift]LeetCode770. 基本计算器 IV | Basic Calculator IV

    Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...

  8. [Swift]LeetCode943. 最短超级串 | Find the Shortest Superstring

    Given an array A of strings, find any smallest string that contains each string in A as a substring. ...

  9. kubernetes---docker-image

    imagePullPolicy  <String> Always : 总是从仓库下载 , 如果是image的tag是latest ,如果需要一直保持最新,则应设为Always ,从仓库下载 ...

  10. 好用的函数,assert,random.sample,seaborn tsplot, tensorflow.python.platform flags 等,持续更新

    python 中好用的函数,random.sample等,持续更新 random.sample random.sample的函数原型为:random.sample(sequence, k),从指定序列 ...