demo_2

业务层

 1 package com.demo.service;
 2 
 3 import com.demo.pojo.User;
 4 
 5 public interface IUserService {
 6     /**
 7      * 用户登录
 8      * @param user 用户信息
 9      * @return 返回数据
10      */
11     User reg(User user);
12 }

实现类

创建`com.demo.service.Impl.UserServiceImpl`类,使用`@Service("userService")`对类注解,声明`private UserMapper userMapper`成员,并使用`@Autowired`注解,实现`IUserService`,实现抽象方法:

 1 package com.demo.service.Impl;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Service;
 5 
 6 import com.demo.dao.UserMapper;
 7 import com.demo.pojo.User;
 8 import com.demo.service.IUserService;
 9 
10 //实现类
11 @Service("userService")
12 public class UsertServiceImpl implements IUserService{
13     @Autowired
14     private UserMapper userMapper;
15 
16     public User reg(User user) {
17         userMapper.insert(user);
18         return user;
19     }
20     
21 }

 

在业务层,关于操作的成功与否,推荐:只要能把方法顺利执行结束,就是成功,如果中途出错,则抛出异常,后续,方法的调用者(控制器层的某个方法)通过try...catch来处理。

##  关于密码

 1 package 测试;
 2 
 3 import java.util.UUID;
 4 
 5 import org.springframework.util.DigestUtils;
 6 
 7 public class 设计密码 {
 8     public static void main(String[] args) {
 9         //文摘
10         System.out.println("Digest");
11         //密码
12         String[] password = {"123456","000000","654321"};
13         UUID salt = UUID.randomUUID();//随机盐
14         System.out.println(salt.toString().length());//长度
15         for (int i = 0; i < password.length; i++) {//双重加盐
16             String md5Str = DigestUtils.md5DigestAsHex(password[i].getBytes());
17             md5Str = DigestUtils.md5DigestAsHex((salt+md5Str).getBytes());
18             System.out.println(md5Str.toUpperCase());
19         }
20     }
21 }

##  查询用户信息--持久层

实现根据用户名查询用户信息,所以,在`UserMapper`接口中添加新的抽象方法:

 1 /**
 2      * 查询用户信息
 3      * @param where WHERE子句,不要包含WHERE关键字
 4      * @param orderBy OrderBy子句,不要包含Order By关键字
 5      * @param offset 偏移量,用于Limit子句的第一个值
 6      * @param countPerPage 每页显示的数据量,用于Limit子句的第二个值,仅当参数offset有效时,该参数才有效,如果没有提供offset值,则该参数没有意义
 7      * @return 配置的用户信息的集合
 8      */
 9     List<User> select (
10             @Param("where") String where,
11             @Param("orderBy") String orderBy,
12             @Param("offset") Integer offset,
13             @Param("countPerPage") Integer countPerPage
14             );

然后,在`UserMapper.xml`中添加映射:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" 
 3     "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
 4 
 5 <!-- namespace:匹配的接口 -->
 6 <mapper namespace="com.demo.dao.UserMapper">
 7 
 8 
 9     <!-- 查询用户信息 -->
10     <!-- List<User> select(
11         @Param("where") String where,
12         @Param("orderBy") String orderBy,
13         @Param("offset") Integer offset,
14         @Param("countPerPage") Integer countPerPage);
15      -->
16     <select id="select" resultType="com.demo.pojo.User">
17     SELECT 
18         id,username,password,gender,phone,email,uuid,
19         created_user AS createdUser,
20         created_time AS createdTime,
21         modified_user AS modifiedUser,
22         modified_Time AS modifiedTime
23     FROM 
24         t_user
25     <if test="where != null">
26     WHERE ${where}
27     </if>
28     <if test="orderBy != null">
29     ORDER BY ${orderBy}
30     </if>
31     <if test="offset != null">
32     LIMIT ${offset},${countPerPage}
33     </if>
34     </select>
35 </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`接口中添加抽象方法:

 1 package com.demo.service;
 2 
 3 import com.demo.pojo.User;
 4 
 5 //业务层
 6 public interface IUserService {
 7     
 8     /**
 9      * 根据用户名查询信息
10      * 
11      * @param username 用户名
12      * @return 用户信息,如果没有匹配的用户信息,则返回null
13      */
14     User findUserByUsername(String username);
15 
16     /**
17      * 获取加密的密码
18      * 
19      * @param password 明文密码
20      * @param salt     盐
21      * @return 密文密码
22      */
23     String getEncrpytedPassword(String password, String salt);
24 }

 

##  在实现类`UserServiceImpl`中实现以上方法(更新注册方法--业务层逻辑):

 1 package com.demo.service.Impl;
 2 
 3 import java.util.Date;
 4 import java.util.List;
 5 import java.util.UUID;
 6 
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.stereotype.Service;
 9 import org.springframework.util.DigestUtils;
10 
11 import com.demo.dao.UserMapper;
12 import com.demo.pojo.User;
13 import com.demo.service.IUserService;
14 import com.demo.service.ex.UsernameConflictException;
15 
16 //实现类
17 @Service("userService")
18 public class UsertServiceImpl implements IUserService {
19     @Autowired
20     private UserMapper userMapper;
21 
22     public User reg(User user) {
23         //根据尝试注册的用户名进行查询
24         User u = findUserByUsername(user.getUsername());
25         //判断用户名是否被占用
26         if (u !=null) {
27             //用户名被占用,则:
28             throw new UsernameConflictException("用户名" + user.getUsername() + "已经被注册!");
29         } else {
30             //用户名没有被占用,则执行注册相关任务
31             //把密码加密
32             String salt = UUID.randomUUID().toString().toUpperCase();
33             String md5Password = getEncrpytedPassword(user.getPassword(), salt);
34             user.setPassword(md5Password);
35             //保存uuid,即盐
36             user.setUuid(salt);
37             //保存日志信息
38             Date now = new Date();
39             user.setCreatedUser("System");
40             user.setCreatedTime(now);
41             user.setModifiedUser("System");
42             user.setModifiedTime(now);
43             //使用Mybatis处理insert后
44             //数据的id将被封装到参数对象中
45             //在执行以下代码之前,参数user中并没有id
46             //执行完后,Mybatis将把id封装到参数对象user中
47             userMapper.insert(user);
48             return user;
49         }
50     }
51 
52     public User findUserByUsername(String username) {
53         // 确定WHERE子句的内容
54         String WHERE = "username='" + username + "'";
55         // 调用持久层对象执行查询
56         List<User> users = userMapper.select(WHERE, null, null, null);
57         // 判断查询结果
58         if (users.size() == 0) {
59             // 没有找到数据,则用户名不存在
60             return null;
61         } else {
62             // 找到数据,由于用户名唯一
63             // 则集合中的第一个元素就是要查询的数据
64             return users.get(0);
65         }
66     }
67 
68     public String getEncrpytedPassword(String password, String salt) {
69         // 把密码与盐拼接起来
70         String str = password + salt;
71         // 获取拼接后的字符串的消息摘要
72         String md5 = DigestUtils.md5DigestAsHex(str.getBytes()).toUpperCase();
73         // 返回摘要字符串,即密文
74         return md5;
75     }
76 
77 }

  

 

posted @ 2018-11-02 19:56  國仕無雙  阅读(258)  评论(0编辑  收藏  举报