0
点赞
收藏
分享

微信扫一扫

(springboot实战03)day52javaEE基础查漏补缺

悄然丝语 2022-02-16 阅读 53

springboot实战03

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直接代替即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3TV4v0az-1644944387311)(问题.assets/1644939873436.png)]

原文链接: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中的关键字.
坚决不允许出现中文及拼音命名.

25.读写权限的账号密码是是谁的账号密码???

26.controller层方法怎么命名?

举报

相关推荐

0 条评论