重温电商项目完整笔记(Undo)

这里写自定义目录标题

  • 一、数据库
    • decimal
    • bigint
    • 订单明细表
    • 唯一索引
    • 单索引及组合索引
  • 二、项目初始化
    • 为什么选择Mybatis
    • 详解SpringMVC
    • Maven/git
    • mybatis——Generator
    • mybatis——Plugin
    • spring-petclinic/greenhouse/springboot
    • idea快捷功能
  • 三、用户模块
    • 功能:
    • 学习重点
    • 搭建
    • 笔记
      • equal注意点
      • static
      • Md5加密工具对字符串进行加密的使用
      • 思考:为什么Dao层和Service层要设计成接口?
      • StringUtils.isNotBlank() StringUtils.isNotEmpty()
      • 忘记密码时的token使用
      • 在映射方法中传递的整数参数为什么是Integer类型而不是int
  • 四、分类模块
    • 通过SpringMVC配置默认值
    • 递归查询无限层级的树状结构
  • 五、商品模块
    • FTP服务对接
    • SpringMVC文件上传
    • 流读取Properties配置文件
    • 抽象POJO、BO、VO对象之间的转换关系及解决思路
    • 静态块
    • MyBatis-PageHelper高效准确地分页及动态排序
    • MyBatis对List集合遍历
    • MyBatis对where语句动态拼装
    • 其他笔记
  • 六、购物车模块
    • 封装高复用购物车核心方法
    • 解决商业运算中浮点型精度丢失问题 6.14
  • 七、收货地址模块
  • 八、Tomcat集群部署及单点登录session共享问题 6.12
    • redis基础

一、数据库

decimal

	数据库中表示较高精度的类型,eg:decimal(20,2) 20位有效位,保留两位小数。可用于表示价格、金额。
	在java中可以用BigDecimal类型,来进行数据运算。

Undo:商业运算精度丢失。

bigint

	可用于订单编号等较长数字的表示。
	在java中对应long类型。

订单明细表

	商品id、图片、详情,不可以直接去商品表查询,因为这里是一个快照。

唯一索引

  1. user表中的username
  2. order表中的order_no

单索引及组合索引

	使查询更加快速
  1. mall_order_item 中的order_no_index单索引
  2. mall_order_item 中的order_no_user_id_index组合索引

二、项目初始化

为什么选择Mybatis

参考:https://blog.csdn.net/leijie0322/article/details/124662041

详解SpringMVC

Maven/git

mybatis——Generator

快捷迅速的生成dao层接口、pojo层对象、表格的xml映射文件。
now() 获取当前时间戳的函数。

mybatis——Plugin

几年前第一次配这个项目的时候还在用,搜了一下现在居然闭源了,说是大佬转行了 现在是2022.03 裁员风很大,hc缩招风很大, anyway,我还是要做一个逆流勇进的,憨憨。

spring-petclinic/greenhouse/springboot

马克,尝试运行一下这个程序

idea快捷功能

/**+回车 注释
psvm + Tab2 主函数
sout + Tab
2 输出

三、用户模块

功能:

  1. 登录
  2. 用户名验证
  3. 注册
  4. 忘记密码
  5. 提交问题答案
  6. 重置密码「忘记密码、登录状态」
  7. 获取用户信息
  8. 更新用户信息
  9. 退出登录

学习重点

  1. 横向越权、纵向越权安全漏洞
    横向越权:攻击者尝试访问相同权限用户资源
    纵向越权:低级别攻击者尝试访问高级别用户的资源
  2. MD5明文加密、增加salt值
  3. Guava缓存使用
  4. 高复用服务响应对象的设计思想及抽象封装
  5. Mybatis-Plugin(MybatisX)使用技巧
  6. Session使用
  7. SpringMVC数据绑定(慕课视频)

搭建

  1. 在controller包中创建portal包,代表门户、前台
  2. 创建UserController类,添加@Controller以及@ResquestMapping注解
  3. 开始编写方法

笔记

1. 注解
2. session
为了保存用户状态而创建的变量
3.高复用的返回对象

equal注意点

注意避免有可能为空的字符串出现在前面

static

静态方法和静态变量一样,属于这个类,而不属于某个对象,所有对象共用,在类装载时装载。

Md5加密工具对字符串进行加密的使用

  1. 通过信息摘要单例的构造函数获取信息摘要对象MD5
MessageDigest md5 = MessageDigest.getInstance("MD5");
  1. 获取字符串的字节数组
    原因:信息摘要对象是对字节数组进行摘要。
byte[] digest = md5.digest(bytes);
  1. 将摘要数组中每字节转换成16进制并拼在一起

完整代码

public class MD5Tool {
   public static void main(String[] args) throws Exception {
       /*--------------字符串--------------*/
       String str = "12345";
       String md1 = getMD5(str);
       System.out.println(md1);//827ccb0eea8a706c4c34a16891f84e7b

       /*--------------文件--------------*/
       File file = new File("D:\\1.mp3");
       String md2 = getMD5(file);
       System.out.println(md2);//9068aaead9a5b75e6a54395d8183ec9
   }
   /**
    * 逻辑:
    *
    * 1.获取md5对象,通过"信息摘要"获取实例构造("MD5").
    * 2.md5对象对("字符串的"字节形式"-得到的数组)进行摘要",那么会返回一个"摘要的字节数组"
    * 3.摘要字节数组中的"每个二进制值"字节形式,"转成十六进制形式",然后再把这些值给拼接起来,就是MD5值了
    *      (PS:为了便于阅读,把多余的fff去掉,并且单个字符前加个0)
    *
    */
   public static String getMD5(String str) throws Exception {

       String MD5 = "";

       MessageDigest md5 = MessageDigest.getInstance("MD5");
       byte[] bytes = str.getBytes();
       byte[] digest = md5.digest(bytes);

       for (int i = 0; i < digest.length; i++) {
           //摘要字节数组中各个字节的"十六进制"形式.
           int j = digest[i];
            j = j & 0x000000ff;
           String s1 = Integer.toHexString(j);

           if (s1.length() == 1) {
               s1 = "0" + s1;
           }
           MD5 += s1;
       }
       return MD5;
   }
   //重载,所以用户传入"字符串"或者"文件"都可以解决.

   /**
    * 处理逻辑:
    * 1.现在传入的是"文件",不是字符串
    * 2.所以信息摘要对象.进行摘要得到数组不能像上面获得:md5.digest(bytes),因为不是str.getBytes得到bytes
    * 3.其实还是通过mdt.digest();获取到字节数组,但是前期必须要有一个方法必须是md5.update(),即"信息摘要对象"要先更新
    * 4."信息摘要更新"里面有(byte[] input),说明是读取流获取到的数组,所以我们就用这个方法.
    * 5.所以最终的逻辑就是:
    *
    *      1.获取文件的读取流
    *      2.不停的读取流中的"内容"放入字符串,放一部分就"更新"一部分.直到全部完毕
    *      3.然后调用md5.digest();就会得到有内容的字节数组,剩下的就和上边一样了.
    */
   public static String getMD5(File file) throws Exception {
       String MD5 = "";

       MessageDigest md5 = MessageDigest.getInstance("MD5");
       FileInputStream fis = new FileInputStream(file);

       byte[] bytes = new byte[1024 * 5];

       int len = -1;
       while ((len=fis.read(bytes))!=-1) {
           //一部分一部分更新
           md5.update(bytes, 0, len);
       }
       byte[] digest = md5.digest();
       for (int i = 0; i <digest.length; i++) {
           int n = digest[i] & 0x000000ff;
           String s = Integer.toHexString(n);

           MD5 += s;
       }
       return MD5;
   }
}

来源:https://blog.csdn.net/mp624183768/article/details/80575843

优化:
md5虽然无法破解,但可以通过字典和穷举去尝试,随着字符集的强大,危险性也会显露,为避免此问题可以在密码上添加盐值。

思考:为什么Dao层和Service层要设计成接口?

DAO接口
为每个DAO声明接口的好处在于:
可以在尚未实现具体DAO的时候编写上层代码,如Service里对DAO的调用
可以为DAO进行多实现,例如有JDBCDAO实现,MyBatisDAO实现,而不需要更改上层代码,只需要简单的在Spring的IoC配置里修改一下注入的DAO实现
Service接口
可以在尚未实现具体Service情况下编写上层改代码,如Controller对Service的调用
Spring无论是AOP还是事务管理的实现都是基于动态代理的,而动态代理的实现依赖于接口,所以必须有接口的定义才能使用这些功能
可以对Service进行多实现

来源:https://blog.csdn.net/wxljmy77/article/details/88415310

StringUtils.isNotBlank() StringUtils.isNotEmpty()

isNotBlank() 在传入空格时,判断为空

忘记密码时的token使用

  1. 使用UUID生成随机token,并使用tostring转化成字符串
  2. 将forgetToken放入本地Cache,并设置有效期
  3. 回答对问题时将token存入缓存
  4. 修改密码时同时传入token,并进行验证

在映射方法中传递的整数参数为什么是Integer类型而不是int

此处主要原因:在数据库字段与java类映射时需要用引用类型
另:使用Integer包装类,没有数据时默认为null,使用int时没有数据默认0,无法确认是传入了0还是未传递数据;
Integer可以作为对象传入,并且拥有一些封装好的处理数据的方法

**一个拓展:**ArrayList集合类中只能存储类对象,即所有基本类型要使用包装类进行存储
重温电商项目完整笔记(Undo)_第1张图片

参考:https://blog.csdn.net/a1051031961/article/details/119996372?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5.pc_relevant_aa&utm_relevant_index=8

四、分类模块

通过SpringMVC配置默认值

@RequestParam(value = “categoryId”, defaultValue = “0”)注解配置默认值

递归查询无限层级的树状结构

五、商品模块

FTP服务对接

SpringMVC文件上传

MutipartFile
参考文章:http://t.zoukankan.com/luffyu-p-6145086.html

流读取Properties配置文件

抽象POJO、BO、VO对象之间的转换关系及解决思路

重温电商项目完整笔记(Undo)_第2张图片

静态块

MyBatis-PageHelper高效准确地分页及动态排序

MyBatis对List集合遍历

MyBatis对where语句动态拼装

其他笔记

StringBuffer、StringBuilder的区别
参考:https://blog.csdn.net/changgebuyu/article/details/86523998

六、购物车模块

功能:加入商品、更新商品数量、查询商品数、移除商品、单选/取消、全选/取消、购物车列表

封装高复用购物车核心方法

限制库存数、计算总价、封装购物车产品VO

解决商业运算中浮点型精度丢失问题 6.14

浮点型在运算时先转换成二进制,但有些浮点数不能精确转换,所以会造成精度丢失问题,在需要确保高精度的商业运算中,使用BigDecimal的String构造器可以避免这一问题。
本项目中封装了可复用的BigDecimalUtil工具类

七、收货地址模块

八、Tomcat集群部署及单点登录session共享问题 6.12

redis基础

你可能感兴趣的:(JAVA,笔记整理,java,intellij-idea,后端)