springboot实战03
- 1.分页查询。
- 2.有一个bug:修改分类菜品时间不更新:更新时间不填充:
- 3.LambdaQueryWrapper查询条件封装对象
- 4.tomcat编码和反编码:omcat中默认采用iso-8859-1来解码
- 5.多表联合查询一次,和单表查询多次,那个效率高?
- 6.分解关联查询的方式重构查询的优点和缺点:
- 7.模糊查询的效率高吗,学习一下sql调优???
- 8.lang3是什么包。
- 9.集合做非空判断,每个层都要做非空判断吗?
- 10.看一下mybatis的封装原理:
- 11.mybatiplus能实现联表查询吗
- 12.如何对接第三方,比如阿里云对象存储OSS
- 13.xxxtemplet.java,一般是操作存储系统的工具类。
- 14.文件上传。
- 15.yaml文件,注意格式,新的配置,需要定格写。
- 16.上传完文件的注意事项:
- 17.多个表数据合成的实体类:
- 18.mybatis的主键返回
- 19.什么时候需要开启事务控制???
- 20.根据一个外键多个更新的思路:
- 21.@ConfigurationProperties(prefix = "reggie.oss")//读取配置信息的prefix是什么意思???
- 22.controller尽量不要写太多的东西,对象封装啥的都放到服务层去做。
- 23.注意:文件上传-当点击上传图片的时候就已经上传到阿里云服务器了,而不是点击保存的时候上传。
- 24.三层架构的方法名怎么取?
- 25.读写权限的账号密码是是谁的账号密码???
- 26.controller层方法怎么命名?
1.分页查询。
//配置分页拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//1 创建MybatisPlusInterceptor拦截器对象
MybatisPlusInterceptor mpInterceptor=new MybatisPlusInterceptor();
//2 添加分页拦截器
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mpInterceptor;
}
}
//分页
@Test
public void testFindByPage() {
//1. 设置分页条件
Integer pageNum = 2;
Integer pageSize = 3;
Page<User> page = new Page<>(pageNum, pageSize);
//2. 设置查询条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 1);
//3. 分页查询
//SELECT id,name,password,age,tel FROM user WHERE (age > 1) LIMIT 3,3
page = userMapper.selectPage(page, wrapper);
//4. 分页结果
System.out.println("总条数:" + page.getTotal());
System.out.println("总页数:" + page.getPages());
System.out.println("当前页数据:" + page.getRecords());
System.out.println("当前页码值:" + page.getCurrent());
System.out.println("每页显示数:" + page.getSize());
}
2.有一个bug:修改分类菜品时间不更新:更新时间不填充:
原因,mybatis和mybatisplus混用了。
持久层先过xml,生成sql,再进行字段的填充。
因为xml中写的是动态sql,可能某个自动填充字段为空,被if判断过滤了,导致sql中没有该字段,所以无法填充。导致某个数据不更新。
3.LambdaQueryWrapper查询条件封装对象
先分析是条件查询还是主键查询,主键操作基本是简单操作就不用写wrapper了。
4.tomcat编码和反编码:omcat中默认采用iso-8859-1来解码
http get方式的编码问题
网址:http://www.baidu.com/君山?name=君山
它大致分为三部分:
scheme协议:http
uri:www.baidu.com/君山
queryString请求参数:name=君山
后面两部分需要注意编码问题
对于uri来说,tomcat中对于uri默认的解码方式是通过iso-8859-1来解码,设置server.xml中connector的URIEncoding属性为UTF-8来解决。这样tomcat就会默认用utf-8来解析uri了。
对于queryString请求参数来说,它的编码方式和http头部的ContentType有关,tomcat中默认也会采用iso-8859-1来解码,设置server.xml中的useBodyEncodingForURI属性为true,那么他会根据请求头部中的contentType指定的相应编码解码。或者通过request.setCharacterEncoding(“UTF-8”);设置对请求参数的解码。
5.多表联合查询一次,和单表查询多次,那个效率高?
单表效率高。
在数据量不大的情况下多表连接查询和多次单表查询的效率差不多。
如果数据量足够大,那肯定是多次单表查询的效率更高。
在一些大的公司里面,都会禁用多表连接查询,原因就是一旦数据量足够大的时候多表连接查询效率会很慢,而且不利于分库分表的查询优化。
6.分解关联查询的方式重构查询的优点和缺点:
很多高性能的应用都会对关联查询进行分解,对每个表进行一次单表查询,然后将结果在应用程序中进行关联。
1) 让缓存的效率更高
许多应用程序可以方便地缓存单表查询对应的结果对象。另外对于MySQL的查询缓存来说,如果关联中的某个表发生了变化,那么就无法使用查询缓存了,而拆分后,如果某个表很少改变,那么基于该表的查询就可以重复利用查询缓存结果了。
2)减少锁的竞争
将查询分解后,执行单个查询可以减少锁的竞争。
3)易于对数据库拆分和扩展
在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
4)提高查询效率
查询本身效率也可能会有所提升
5)分解关联查询的方式重构查询的缺点
原本一条查询,这里却变成了多条查询,返回结果又是一模一样。
7.模糊查询的效率高吗,学习一下sql调优???
不高。学习一下sql调优。
8.lang3是什么包。
开源工具包。
lang3是Apache Commons 团队发布的工具包,要求jdk版本在1.5以上,相对于lang来说完全支持java5的特性,废除了一些旧的API。该版本无法兼容旧有版本,于是为了避免冲突改名为lang3
lang包可以说是废弃了,以后请不要使用。采用lang3直接代替即可
原文链接:https://blog.csdn.net/f641385712/article/details/82468927
9.集合做非空判断,每个层都要做非空判断吗?
我觉得主要还是在业务层做非空判断。
【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
1)返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。
2) 数据库的查询结果可能为 null。
3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。
4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
5) 对于 Session 中获取的数据,建议 NPE 检查,避免空指针。
6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。
正例:使用 JDK8 的 Optional 类来防止 NPE 问题。
10.看一下mybatis的封装原理:
1)通过反射,创建结果对象,其所有属性为默认值,例如,如果结果是实体对象,那么将通过无参构造函数创建对象,其所有属性一般为空,如果结果是List,则会创建一个空的List
2)为结果对象的属性赋值,这里也是通过反射,找到set方法赋值
11.mybatiplus能实现联表查询吗
不能,只能实现单表查询。
12.如何对接第三方,比如阿里云对象存储OSS
看产品文档:
1)安装sdk(软件开发工具包),可以通过maven引入依赖。
2)初始化和快速入门,根据文档提示,找到需要的业务对接代码,做一demoTest,进行测试。
3)找到合适的代码方案,写相关工具类,和配置文件yaml。
4)使用工具类,在项目中写出逻辑代码。
13.xxxtemplet.java,一般是操作存储系统的工具类。
package com.itheima.reggie.common;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
//阿里存储工具类
@Component
@ConfigurationProperties(prefix = "reggie.oss")//读取配置信息
@Data
public class OssTemplate {
private String key; //访问key
private String secret;//访问秘钥
private String endpoint;//端点
private String bucket;//桶名
private String url;//访问域名
//文件上传
public String upload(String fileName, InputStream inputStream) {
//创建客户端
OSS ossClient = new OSSClientBuilder().build(endpoint, key, secret);
//设置文件最终的路径和名称
String objectName = "images/" + new SimpleDateFormat("yyyy/MM/dd").format(new Date())
+ "/" + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));
//meta设置请求头,解决访问图片地址直接下载
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
//上传
ossClient.putObject(bucket, objectName, inputStream, meta);
//关闭客户端
ossClient.shutdown();
return url + "/" + objectName;
}
//文件后缀处理
private String getContentType(String FilenameExtension) {
if (FilenameExtension.equalsIgnoreCase(".bmp")) {
return "image/bmp";
}
if (FilenameExtension.equalsIgnoreCase(".gif")) {
return "image/gif";
}
if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
FilenameExtension.equalsIgnoreCase(".jpg") ||
FilenameExtension.equalsIgnoreCase(".png")) {
return "image/jpg";
}
return "image/jpg";
}
}
14.文件上传。
① 配置文件上传解析器
spring:
servlet:
multipart:
max-request-size: 100MB # 最大请求文件大小,默认10MB
max-file-size: 10MB # 单个请求文件大小,默认1MB
② 编写文件上传代码
package com.itheima.reggie.controller;
import com.itheima.reggie.common.OssTemplate;
import com.itheima.reggie.common.ResultInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@RestController
public class FileController {
@Autowired
private OssTemplate ossTemplate;
//文件上传
//注意:参数类型MultipartFile,参数名和前端的请求名保存一致
@PostMapping("/common/upload")
public ResultInfo uploadFile(MultipartFile file) throws IOException {
if (file.getSize() > 0){
//1. 将接收到的文件使用OssTemplate上传到阿里云
String filePath = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
//2. 上传之后访问地址返回给前端
return ResultInfo.success(filePath);
}
return ResultInfo.error("文件上传失败");
}
}
15.yaml文件,注意格式,新的配置,需要定格写。
16.上传完文件的注意事项:
注意:参数类型MultipartFile,参数名和前端的请求名保存一致。
17.多个表数据合成的实体类:
根据主键找到主表。
其他的表上的字段记得用主键:@TableField(exist = false)
18.mybatis的主键返回
能够在进行添加操作时,设置主键返回
useGeneratedKeys: 告诉mybatis我们需要使用mysql底层生成的主键了,要让mybatis给我们返回来
keyProperty: 将返回来的主键的值赋值到传入参数的指定属性上
<insert id="save" parameterType="com.itheima.pojo.User"
useGeneratedKeys="true" keyProperty="uid">
insert into user values(null,#{name},#{password},#{email},#{birthday})
</insert>
19.什么时候需要开启事务控制???
业务层,如果一个方法同时对多张表执行增删改方法,需要控制事务。
20.根据一个外键多个更新的思路:
根据外键全部删除,再根据外键插入。
21.@ConfigurationProperties(prefix = “reggie.oss”)//读取配置信息的prefix是什么意思???
22.controller尽量不要写太多的东西,对象封装啥的都放到服务层去做。
controller层在MVC设计中属于控制层;设计初衷:接受请求并响应请求;所以,该层尽量轻薄,避免编写涉及业务处理的代码。
23.注意:文件上传-当点击上传图片的时候就已经上传到阿里云服务器了,而不是点击保存的时候上传。
上传阿里云,然后返回图片的路径,再保存路径到数据库中。
24.三层架构的方法名怎么取?
1)Dao 接口命名:这里的方法名字最好对应着sql语句,这是最直接的。然后表示条件用By作为介词,表示查询列表用list前缀。
insert :插入
batchInsert :批量插入
selectOne :查询一个数据
selectById :查询通过xx条件
count :计数
selectList :查询多个数据
update :更新
deleteById :删除,通过某些条件
2)Service 接口命名:这里用的是解决人类的思维,查询就是find,添加是add,删除就是remove,修改是modify。然后条件也用by,大量用list后缀。
add :添加数据
findById :查找,也可以用query
findByXXX :查找
findXXXList :批量查找
modify :修改
remove : 简单删除
3)controller层在MVC设计中属于控制层;设计初衷:接受请求并响应请求;所以,该层尽量轻薄,避免编写涉及业务处理的代码。
其他命名规范
项目名全部小写.
包名全部小写.
类名:大驼峰,例如:UpperCamelCase
变量名,方法名:小驼峰:lowerCamelCase
常量名全部大写: public static final int REQUEST_KEY_CODE =1;
所有命名规则必须遵循以下规则 :
名称只能由字母、数字、下划线、$符号组成.
不能以数字开头.
名称不能使用Java中的关键字.
坚决不允许出现中文及拼音命名.