既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
</insert>
需要注意的是:namespace指的是Mapper.xml对应域也就是对应的Mapper接口 parameterType指的是接口方法的参数类型
前端代码:
注册
<div class="row">
<span>用户名</span>
<input type="text" id="username" name = "username">
</div>
<div class="row">
<span>密码</span>
<input type="password" id="password" name = "password">
</div>
<div class="row">
<span>确认密码</span>
<input type="password" id="password1" name = "password1">
</div>
<div class="row">
<span>上传头像</span>
<input type = "file" id="file" name = "file">
</div>
<div class="row">
<button id="submit" onclick = "mySubmit()">提交</button>
</div>
</div>
后端业务:
在UserController中先注入UserMapper类,然后写注册方法
@Autowired
//Autowired需要一个非空对象,而它引入的是Mybatis,IDEA不能很好识别
private UserMapper userMapper;
>
> 注意:这里使用Autowired注解后,userMapper会出现红色线,根据源码可以看出@Autowired是springframework中注解,它需要一个非空的对象,而在项目中我们用@Autowired引入的是Mybatis中的@Mapper注解,IDEA不能很好识别Mybatis注解,因此不能确定当前注入的对象是否为非空对象。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715173202857.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> `解决方案`:
> 1.给UserMapper接口添加@Repository注解,其他类似@Controller也是可以的。
> 2.在IDEA中进行设置,将注解提示关闭。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021071517415554.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> 3.使用Java本身注解@Resource,无需关闭IDEA注解提示
>
>
>
后端代码:
@RequestMapping(“/reg”)
//之前加了ResponseBody返回了Json字符串,没有返回视图,一定要记住
public String register(String username, String password, @RequestPart MultipartFile file
) throws IOException {
//Todo 非空效验
//1.动态获取当前项目的路径
String path = ClassUtils.getDefaultClassLoader().getResource("static").getPath();
// String path = imagePath;
path += AppFinal.IMAGE_PATH;
log.error(“path”+path); //打印出路径
//2.文件名(全局唯一,时间戳是不可以的,可以使用UUID) + 文件的原始类型(比如jpg/png)
String fileType = file.getOriginalFilename(); //例如拿到img.jpg
fileType = fileType.substring(fileType.lastIndexOf(".")); //拿到.jpg
String fileName = UUID.randomUUID().toString() + fileType; //拿到文件名称
//将文件保存在服务器
file.transferTo(new File(path+fileName)); //传入文件路径
User user = new User();
user.setUsername(username); //这里的username是前端传递过来的,password也是
user.setPassword(password);
user.setPhoto(AppFinal.IMAGE_PATH + fileName); //设置的头像地址,相对的url地址,前端将其和url拼接
int result = userMapper.addUser(user);
if(result > 0){
return "redirect:/reg.html";
}else{
return "redirect:/reg\_error.html";
}
}
启动springboot,在浏览器中访问注册页面
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715161146982.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715161623697.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
数据库中该数据已经正常插入:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715161851834.png)
在浏览器中访问我们刚才上传的头像:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715162033746.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
上述表明我们通过Mybatis框架已经初步实现了一个简单而又不简单的注册功能。。。
---
接下来我们继续学习
**设置Mapper.xml模板,避免后续机械般重复操作**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715175318549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
#### 单表操作
**插入用户数据:**
>
> **useGeneratedKeys**:为true时表示设置自增主键,**keyProperty**中的id代表
> User中ide属性主键,**keyColumn**中id代表数据库表中的id字段,表中的字段名称可以和User中id属性名称不相同。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715175643196.png)
> 设置了id自增主键后,插入数据后可以得到id;
> 在这里我们开启MySQL执行的日志:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716002850764.png)
> 在UserMapperTest类前加入@Transactional注解,这样正常执行了后端业务,但是在数据库中没有操作记录,也就是说执行的过程发生了回滚,这样一来没有污染数据。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715225517599.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> MySQL执行的日志:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/202107152256157.png)
> 单元测试类中添加用户方法返回的结果:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210715225658134.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
>
>
>
**查询数据:根据用户id查询**
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716013839612.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716014612812.png)
> 需要重点注意的是resultMap是映射结果集,将表中字段与实体类中属性对应起来,这样做就保证了实体类属性名称和表字段名称不一致时能完美对应起来。
> ![这里是引用](https://img-blog.csdnimg.cn/20210716013749454.png) 执行单元测试后结果:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716013951233.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716014028976.png)
> 结果表明根据id查询出了User对象的属性!
>
>
>
**查询数据:根据用户名和密码**
>
> 根据上面的id查询我们发现表中的字段可以和方法中的参数名一致,那么根据名字和密码查询的时候,是不是也同样适用呢,来看一下哈。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716091712380.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716091811227.png)
> 单元测试结果:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716091931654.png)
> 我们发现程序执行已经出现了异常,也就是说当方法中参数名和表中字段名不一致时,是没有办法执行相应查询操作滴。这是为啥呢?
> `原因分析`:在Mybatis中,当方法中参数只有一个,参数的名称叫什么都行;当参数的个数大于等于1时,Mapper.xml中字段名要和方法中参数名保持一致。
> 当然还有一种方式,给接口方法参数做映射,给username加@Param(“name”)注解,就可以正常查询了。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716093625289.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021071609363889.png)
>
>
>
**实现用户登录功能:**
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716110920716.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716110937258.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> 登录成功后跳转到个人文章列表页面
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021071611101727.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> **这里我们复习一下Session和Cookie**,登录成功后用户就有了对应的session会话保存在服务器端,而服务器端会给客户端一个JSESSIONID保存在浏览器的Cookie中,当我们不断访问登录后的页面时,页面依然存在,这是因为客户端访问时携带了JSESSIONID,此标识在服务器端找到了对应的Session,当删除了JSESSIONID时,就回到了最开始的登陆页面。
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716111204236.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
>
>
>
**查询多个用户信息:**
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716114122887.png)
> 执行单元测试后:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716114030467.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716114057841.png)
> 程序执行符合我们的预期,userinfo表中的用户信息都已经查了出来。
>
>
>
**删除用户数据:**
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021071611504928.png)![这里是引用](https://img-blog.csdnimg.cn/20210716115033284.png)
> 根据MySQL启动日志可以看出,成功更新了一条数据
>
>
>
**修改用户数据:**
>
> ![这里是引用](https://img-blog.csdnimg.cn/20210716120151996.png)
> 执行单元测试后:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716120211247.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716120303504.png)
> 从数据库中可以看出,原来id为10的username已经改为了打工人,更新操作成功。
>
>
>
---
#### Mybatis动态参数标识
#{ }:表示从接口声明的方法参数中获取参数,并设置到MySQL语句中
${ }:表示从接口声明的方法参数中获取参数,并设置到MySQL语句中
>
> `二者区别`:#{ }会将参数设置为‘xxx’,当替换参数为MySQL系统关键字时将查询失败报错;因此当替换信息为系统关键字时使用${ },当替换信息为非系统关键字时一定要使用#{ },这样可以预防SQL注入现象。
>
>
>
>
> 但进行模糊查询时,如果使用#{ }将报错!
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716145408988.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716145318556.png)
> 替换为${ }时,执行就不报错了,完成了模糊查询
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716145700577.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716145712489.png)
>
>
>
**但是!!!使用${ }会存在SQL注入问题**
>
> SQL注入:使用一个特殊的SQL查询到了本来不该查询到的内容
>
>
>
![这里是引用](https://img-blog.csdnimg.cn/20210716172329729.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716172353506.png)
通过执行单元测试的结果来看,发生了`SQL注入现象!`
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716172425361.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716172440898.png)
>
> 怎么解决SQL注入的问题呢?
> **1.尽量使用#{ }方式进行参数的替换,它的SQL会进行预处理,不会SQL注入。**
> **2.SQL注入一般发生在Mapper类中,该类是供开发人员调用的,因此我们可以手动排查SQL注入的关键字,比如`‘ or and`等,采取过滤方式。**
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716223534461.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716173312293.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716173327155.png)
> 此时从结果可以看出,防止了SQL注入,但与此同时也没有完成相应SQL操作。
> **3.使用系统提供的参数进行参数的拼接进行like模糊查询**
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716174315193.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716223617185.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210716223418284.png)
> 可以看出使用了concat进行拼接后防止了SQL注入现象的发生!
>
>
>
---
#### 多表联合查询
##### 一对一:查询文章信息与文章所属用户
>
> 步骤:
> 1.先创建实体对象articleinfo,包含了uer属性
> 2.在ArticleInfoMapper接口中定义查询方法
> 3.在Mapper.xml中写具体的SQL语句,要声明`resultMap`和`association`
>
>
>
>
> 查询文章信息以及文章所属的用户
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/202107171536578.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717153410482.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717153513929.png)
> 第一查询时由于在SQL中没有定义userinfo的photo属性,而UserMapper.xml中resultMap是存在photo字段映射的,因此user对象photo属性为null;
> 正常查询后结果:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717154118376.png)
> 当我们不设置columnPrefix时存在的问题:相同数据的字段变得不一致,进行了覆盖:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717160228497.png)
>
>
>
##### 一对多:查询用户以及用户的文章
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021071716364247.png)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717163720594.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> 执行单元测试后结果:
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717163621463.png)
> 成功实现了用户与用户文章信息的查询!
>
>
>
---
#### 动态SQL
>
> 动态SQL是Mybatis的强大特性之一,如果你使用JDBC或者其他类似的框架,你一定感受到根据不同条件进行拼接SQL的痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉最后一个列名的逗号,利用动态SQL,可以摆脱这种痛苦。
>
>
>
##### if标签
查询条件不确定,可能空,可能1个,可能多个
>
> 当title为必传参数,其他为非必传参数时:![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717172000311.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> ![这里是引用](https://img-blog.csdnimg.cn/20210717171921272.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> 可以发现SQL语句只拼接了title字段
> `if中动态变量不需要加#{ }`
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717172919836.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717173008340.png)
> 当所有参数都为非必传参数时,可以看出where后没有拼接的条件,因此这是错误的SQL!
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717173228905.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg3NDI2OQ==,size_16,color_FFFFFF,t_70)
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210717173619524.png)
> 此时当传入参数都为空时,SQL未出错,正常查询得到了表中文章信息!
>
>
>
##### trim标签
![img](https://img-blog.csdnimg.cn/img_convert/c7e8d0c5c88bf3a53cff15cbaac5740b.png)
![img](https://img-blog.csdnimg.cn/img_convert/8c782c3cb863e0429285ce26b68082ca.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
mg-blog.csdnimg.cn/20210717173619524.png)
> 此时当传入参数都为空时,SQL未出错,正常查询得到了表中文章信息!
>
>
>
##### trim标签
[外链图片转存中...(img-S4xKr2gT-1715403519831)]
[外链图片转存中...(img-Mghyux5Z-1715403519831)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**