后端杂七杂八系列篇一

news2024/9/24 13:24:11

后端杂七杂八系列篇一

  • ① MySQL选择合适的数据类型
    • ① Char与Varchar
    • ② Text与Blob
  • ② @EqualsAndHashCode(callSuper = true)的作用
  • ③ mybatis-plus 相关
    • ① 主键生成策略
    • ② 使用Model实现CRUD
    • ③ Wrapper的用法
      • ① Wrapper的继承关系
      • ② 项目中最常用的warpper [LambdaQueryWrapper]
      • ③ 项目中第二常用的warpper [LambdaQueryChainWrapper]
    • ③ Java 中的lambdaQuery()
    • ④ and 和 or的用法(Wrapper)
      • ① where A=? and B=? 形式
      • ② where A=? or B=? 形式
      • ③ where A=? and (B...)
      • ④ where A=? and (B...) or C
    • ⑤ and 和 or的用法(lambdaQuery())
      • where A=? and B=?
      • where A=? or B=?
      • where A=? or(C=? and D=?)
      • where (A=?andB=?)or(C=?andD=?)
      • whert A =? or (B=? and ( C=? or D=?))
  • ④ @CacheEvict 注解

① MySQL选择合适的数据类型

① Char与Varchar

char与varchar都是用来存储字符串的,但他们保存和检索的方式不同


char属于固定长度的字符类型,varchar属于可变长度的字符类型。

char是固定长度的,所以它的处理速度比varchar快得多,但是其缺点是浪费存储空间。对于长度变化不大并且对查询速度有较高要求的数据可以考虑使用char类型来存储。

② Text与Blob

在保存较大文本时,通常会使用text或者blob。二者之间的主要差别是blob能用来保存二进制数据text只能保存字符数据

删除操作时(delete):MySQL并不会回收这条记录占据的存储空间以及索引位,而是空在那里等待新的数据来弥补这个空洞。若一时半会没有数据来填补这个空洞,就会形成资源浪费。

Blob和Text值因为占据大量空间,特别是在执行了大量的删除操作时,如果不采取操作一定会造成性能问题。

因此存在Blob或者Text等占大量空间的表,当执行大量删除操作的时候建议定期使用OPTIMIZE TABLE功能对这类表进行碎片整理,避免因为“空洞”导致性能问题。

查询的时候(select):使用select * 就不是很好的操作,会遍历大量数据,造成性能问题。最好用的时候查,不用的时候不用查。

如果优化的话,建议将这些Blob的数据,都放到一张表中,例如文件表,这样哪怕业务表select * 也无所谓了。

② @EqualsAndHashCode(callSuper = true)的作用

@EqualsAndHashCode是java的自带的注解,通常用于在子类中自动生成 equals 和 hashCode 方法,同时考虑到了父类的成员变量

class Person {
    private String name;
    private int age;
}

@EqualsAndHashCode(callSuper = true)
class Student extends Person {
    private int studentId;
}

如果你使用了 @EqualsAndHashCode(callSuper = true),那么在生成 equals 和 hashCode 方法时,会考虑到Person 类中的 name 和 age字段。


如果你使用了 @EqualsAndHashCode(callSuper = false),只会考虑 studentId 字段。

③ mybatis-plus 相关

① 主键生成策略

@TableId , 该注解提供了各种的主键生成策略

自动生成策略(AUTO策略)
@TableId(value=“id”,type = IdType.AUTO) // value:指定的是表中主键名称。

跟随数据库表的主键递增策略前提是数据库表的主键要设置为自增。

INPUT策略
@TableId(type = IdType.INPUT)

需要 我们手动的插入id

ASSIGN_ID策略(使用雪花算法生成)
@TableId(type = IdType.ASSIGN_ID)

由雪花算法,生成Long 类型的id

ASSIGN_UUID策略(使用uuid生成主键)
@TableId(type = IdType.ASSIGN_ID)

由UUID的编码规则,生成String 类型的id

NONE策略(不指定主键生成策略)
@TableId(type = IdType.NONE)

NONE策略表示不指定主键生成策略,所以这个注释加不加无所谓

② 使用Model实现CRUD

直接定义Bean的时候实现Model类,该类的作用是能通过实体直接进行crud操作而不需要进行调用dao

前提是“必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下”。

@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
public class User extends Model<User> {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
//前提:必须写入mapper
public interface UserMapper extends BaseMapper<User> {
 
}

Model类 自身实现了 insert() ,insertOrUpdate(),deleteById(Serializable id),deleteById() ,delete(Wrapper queryWrapper),updateById(),update(Wrapper updateWrapper),selectAll(),selectList(Wrapper queryWrapper),selectOne(Wrapper queryWrapper),selectPage(E page, Wrapper queryWrapper),selectCount(Wrapper queryWrapper)

@RunWith(SpringRunner.class)
@SpringBootTest
public class SampleTest {
 
    @Test
    public void aInsert() {
        User user = new User();
        user.setName("咩咩");
        user.setAge(5);
        user.setEmail("miemie@mp.com");
        Assert.assertTrue(user.insert());
        // 成功可以直接获取 ID
        System.err.println("\n插入成功 ID 为:" + user.toString());
    }
 
 
    @Test
    public void bDelete() {
        Assert.assertTrue(new User().setId(3L).deleteById());
        Assert.assertTrue(new User().delete(new QueryWrapper<User>()
                .lambda().eq(User::getName, "Sandy")));
        List<User> userList=new User().selectAll();
        userList.forEach(u->System.out.print(u));
    }
 
 
    @Test
    public void cUpdate() {
        Assert.assertTrue(new User().setId(1L).setEmail("ab@c.c").updateById());
        Assert.assertTrue(new User().update(new UpdateWrapper<User>().lambda()
                        .set(User::getAge, 3).eq(User::getId, 2)));
    }

③ Wrapper的用法

① Wrapper的继承关系

在这里插入图片描述

在这里插入图片描述

② 项目中最常用的warpper [LambdaQueryWrapper]

        // 使用lambdaQuery
		LambdaQueryWrapper<SysDroneInfo> wrapper = Wrappers.lambdaQuery();

		// 无人机名称
		if (StrUtil.isNotBlank(sysDroneInfo.getDroneName())) {
			wrapper.eq(SysDroneInfo::getDroneName, sysDroneInfo.getDroneName());
		}

		// 无人机型号
		if (StrUtil.isNotBlank(sysDroneInfo.getDroneManufacturer())) {
			wrapper.eq(SysDroneInfo::getDroneManufacturer, sysDroneInfo.getDroneManufacturer());
		}

		// 无人机状态
		if (StrUtil.isNotBlank(sysDroneInfo.getStatus())) {
			wrapper.eq(SysDroneInfo::getStatus, sysDroneInfo.getStatus());
		}

		return baseMapper.selectPage(page, wrapper);
LambdaQueryWrapper<MerchantApply> lambdaQueryWrapper = new LambdaQueryWrapper();
       
lambdaQueryWrapper.eq(MerchantApply::getStatus, MerchantApplyEnums.STATUS.CONFIRM.getCode())
                    .eq(MerchantApply::getIsDelete, MerchantApplyEnums.DEL_FLAG.NOT_DELETE.getCode())
                    .and(wrapper ->{wrapper.eq(MerchantApply::getUniscid, uniscid)
                    .or().eq(MerchantApply::getApplicant, merchantInformation.getCreateBy());})
                    .last("limit 1");

(status = ? AND is_delete = ? AND (uniscid = ? OR applicant = ?)) limit 1



③ 项目中第二常用的warpper [LambdaQueryChainWrapper]


LambdaQueryChainWrapper有以下方法获取数据:

  1. page():分页
  2. list():列表(常用)
  3. one():获取1个。若有多个结果,则报异常。此方法只用于只有一个结果的情况。(最常用)
List<BannerItem> bannerItems = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getBannerId, id)
                        .list();
BannerItem bannerItem = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getId, id)
                        .one();




QuryWrapper的用法

   @Test
   public void testQueryWrapper() {
       // 查询条件构造器
    QueryWrapper<BannerItem> wrapper = new QueryWrapper<>();
    wrapper.eq("banner_id", id);
    // 查询操作
    List<BannerItem> bannerItems = bannerItemMapper.selectList(wrapper)
   }

③ Java 中的lambdaQuery()

Lambda 查询条件是通过 Java 的 lambda 表达式来构建的,它提供了更加灵活和可读性更高的查询条件构建方式。Lambda 查询条件可以与实体类中的属性进行绑定,并且能够自动推断属性类型,减少了代码的冗余。


lambdaQuery() 方法与MybatisPlus中的 wrapper 并不是直接等价的,但它们都用于构建查询条件。

//SELECT id,name,age,sex FROM student WHERE (name = ? AND age = ?)
List<Student> list = studentService.lambdaQuery().eq(Student::getName, "1").eq(Student::getAge, 1).list();     

lambdaQuery和MP对应关系




④ and 和 or的用法(Wrapper)

在 MybatisPlus 中,and() 和or() 方法是一个常用的链式调用方法,用于构建复杂的查询条件。它接受一个参数,通常是 Lambda 表达式或者其他的条件构造器,用于进一步定义查询条件。

QueryWrapper<User> queryWrapper = new QueryWrapper<>();  
queryWrapper.and(i -> i.eq(User::getName, "John").like(User::getEmail, "example@email.com"));  
List<User> users = userService.list(queryWrapper);

在上面的示例中,and() 方法传入了三个参数,分别代表年龄等于20、状态不等于0和地址模糊匹配 “street”。

需要注意的是,and() 方法只是用于组合多个查询条件,它本身并不执行查询操作。最终的查询操作需要调用相应的 Mapper 或 Service 层的方法来执行。


① where A=? and B=? 形式

QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().
eq("attr_id",key).
eq("catelog_id",catelogId);

② where A=? or B=? 形式

QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().
eq("attr_id",key).
or().
eq("catelog_id",catelogId);

③ where A=? and (B…)

 SELECT
 *
 FROM project
 WHERE 
 type = 1 
 AND (DATE_FORMAT(create_time, '%Y-%m') <= '2022-01');
projectMapper.selectList(new LambdaQueryWrapper<Project>()
                .eq(Project::getType,1)
                .and(qw -> qw.apply("DATE_FORMAT(create_time, '%Y-%m') <= '" + dateStr + "'")));
SELECT
*
FROM
	employee_project
WHERE
	state IS NOT NULL
	AND flag = 1
	AND (
		under_project_time IS NULL
		OR DATE_FORMAT(under_project_time, '%Y-%m-%d') >= '2022-07-27'
	);
employeeProjectMapper.selectList(new LambdaQueryWrapper<EmployeeProject>()
                .isNotNull(EmployeeProject::getState)
                .eq(EmployeeProject::getFlag, 1)
                .and(qw -> qw.isNull(EmployeeProject::getUnderProjectTime)
                        .or().apply("DATE_FORMAT(under_project_time, '%Y-%m-%d') >= DATE_FORMAT(NOW(),'%Y-%m-%d')")));

④ where A=? and (B…) or C

SELECT
*
FROM
	customer
WHERE
	taxpayer_identification_number = '912102113000000000'
	AND (
		parent_id = 111
		OR contact_number = '88'
	)
	AND NAME = '啦啦啦'
	OR number <> 1
	AND company_type = 1;
// 示例二
customerMapper.selectList(new LambdaQueryWrapper<Customer>()
        .eq(Customer::getTaxpayerIdentificationNumber,"912102113000000000")
        .and(qw -> qw.eq(Customer::getParentId,111).or().eq(Customer::getContactNumber,"88"))
        .eq(Customer::getName, "啦啦啦")
        .or()
        .ne(Customer::getNumber, 1)
        .eq(Customer::getCompanyType,1));

⑤ and 和 or的用法(lambdaQuery())

where A=? and B=?

//SELECT id,name,age,sex FROM student WHERE (name = ? AND age = ?)
List<Student> list = studentService.lambdaQuery().eq(Student::getName, "1").eq(Student::getAge, 1).list();     

where A=? or B=?

//SELECT id,name,age,sex FROM student WHERE (name = ? OR age = ?)
List<Student> list = studentService.lambdaQuery().eq(Student::getName, "1").or().eq(Student::getAge, 12).list();

where A=? or(C=? and D=?)

//SELECT id,name,age,sex FROM student WHERE (name = ? OR (name = ? AND age = ?)) 
List<Student> list =
          studentService
              .lambdaQuery()
              .eq(Student::getName, "1")
              .or(wp -> wp.eq(Student::getName, "1").eq(Student::getAge, 12))
              .list();      

where (A=?andB=?)or(C=?andD=?)

// SELECT id,name,age,sex FROM student WHERE ((name = ? AND age = ?) OR (name = ? AND age = ?)) 
List<Student> list =
        studentService
            .lambdaQuery()
            .and(wp -> wp.eq(Student::getName, "1").eq(Student::getAge, 12))
            .or(wp -> wp.eq(Student::getName, "1").eq(Student::getAge, 12))
            .list();  

whert A =? or (B=? and ( C=? or D=?))

// SELECT * FROM student WHERE ((name <> 1) OR (name = 1 AND (age IS NULL OR age >= 11)))
List<Student> list =
        studentService
            .lambdaQuery()
            .and(wp -> wp.ne(Student::getName, "1"))
            .or(
                wp ->
                    wp.eq(Student::getName, "1")
                        .and(wpp -> wpp.isNull(Student::getAge).or().ge(Student::getAge, 11)))
            .list();

④ @CacheEvict 注解

@CacheEvict 注解用于清空缓存。

@CacheEvict(value = "myCache", key = "#id")
public void deleteById(Long id) {
    // 删除操作
}

我们定义了一个 deleteById 方法,它用于删除指定 id 的数据。在方法上使用了 @CacheEvict 注解,表示在删除操作执行后清空名为 myCache 的缓存中的 key 为 id 的缓存数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1353152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据Doris(四十九):Doris数据导出介绍

文章目录 Doris数据导出介绍 一、​​​​​​​使用示例

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于回溯搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

【人工智能】为什么说大模型会有「幻觉」问题,又如何去解决呢

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】序列文章&#xff0c;这一次的话题是《如何解决大模型的幻觉问题》 目录 大模型模型幻觉模型预训练庞大文本数据集语义关系 模型微调特定任务少量标签数据 如何解决普遍方法 大模型 先来…

C# 反射 入门到详解

1.什么是反射 首先看一张流程图 反射最最要的关注的地方 就在metadata 元数据 元数据&#xff1a;描述DLL/EXE文件中有什么内容 点击生成之后&#xff0c;就会在文件中生成DLL/EXE文件 点击打开文件夹 在bin/Debug 文件下就会生成该文件 exe/dll文件的区别&#xff1a;…

Allegro看不到PCB元件的丝印和装配层

#创作灵感# PCB板到处Gerber文件加工回来&#xff0c;板子上没有元件边框丝印&#xff0c;但是有元件编号。因为只是样板&#xff0c;影响不大&#xff0c;就没有当回事。直到发出去贴片&#xff0c;发送了钢网层和装配层&#xff0c;反馈说不知道元器件的极性。这就纳闷了&…

常用Java Lambda表达式示例

文章目录 1. **实现Runnable接口**&#xff1a;2. **事件监听器**&#xff08;如Swing中的ActionListener&#xff09;&#xff1a;3. **集合遍历**&#xff08;使用forEach方法&#xff09;&#xff1a;4. **过滤集合**&#xff08;使用Stream API&#xff09;&#xff1a;5. …

网络安全 | 我国网络安全保险发展初期阶段的主要挑战及应对

党的二十大报告指出&#xff1a;“坚决维护国家安全&#xff0c;防范化解重大风险。 ”网络安全保险是承保于网络安全相关风险的新险种&#xff0c;在分散网络安全风险、弥补经济损失、优化网络安全生态等方面有基础性作用&#xff0c;是治理网络安全风险&#xff0c;维护国家…

Docker、Docker-compose安装

安装Docker 1.卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2.配置Docker的yum库 首先…

什么是 NAS?

一、什么是 NAS&#xff1f; 在数字化时代&#xff0c;小型企业面临着日益增长的数据存储需求。为了应对这一挑战&#xff0c;网络附加存储&#xff08;NAS&#xff09;系统成为了许多企业的首选解决方案。NAS系统是一种连接到网络的存储设备&#xff0c;允许授权网络用户和异…

Paddle3D 2 雷达点云CenterPoint模型训练

2 Paddle3D 雷达点云CenterPoint模型训练–包含KITTI格式数据地址 2.0 数据集 百度DAIR-V2X开源路侧数据转kitti格式。 2.0.1 DAIR-V2X-I\velodyne中pcd格式的数据转为bin格式 参考源码&#xff1a;雷达点云数据.pcd格式转.bin格式 def pcd2bin():import numpy as npimport…

阶段二-Day10-日期类

日期类结构: 1.java.util.Date是日期类 2.DateFormat是日期格式类、SimpleDateFormat是日期格式类的子类 Timezone代表时区 3.Calendar是日历类&#xff0c;GregorianCalendar是日历的子类 一. 常用类-Date 1.1 Date构造方法 Date(long date) 使用给定的毫秒时间价值构建…

阿里云服务器开放端口Oracle 1521方法教程

阿里云服务器ECS端口是在安全组设置的&#xff0c;Oracle数据库1521端口号开放是在安全组中添加规则来实现的&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说下阿里云服务器开放Oracle 1521端口方法教程&#xff1a; 阿里云服务器开放Oracle 1521端口 在阿里云服务器ECS…

虚幻UE 材质-进阶边界混合之距离场限制PDO范围

基础边界混合那篇文章&#xff1a;虚幻UE 材质-边界混合之PDO像素深度偏移量 可以通过抖动来进行混合&#xff0c;但是有问题的点在与抖动发生的位置只需要在两物体的交界处 所以本篇文章会通过距离场限制来限制抖动的位置&#xff0c;防止其他地方发生抖动影响画面。 文章目录…

MySQL主从复制案例实现

使用Sharding-JDBC实现读写分离&#xff1a; 1、导入maven坐标 2、 在配置文件中配置读写分离规则 3、在配置文件中配置允许bean定义覆盖配置项 1、导入maven坐标 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jd…

openGauss学习笔记-184 openGauss 数据库运维-升级-升级验证

文章目录 openGauss学习笔记-184 openGauss 数据库运维-升级-升级验证184.1 验证项目的检查表184.2 升级版本查询184.2.1 验证步骤 184.3 检查升级数据库状态184.3.1 验证步骤 openGauss学习笔记-184 openGauss 数据库运维-升级-升级验证 本章介绍升级完成后的验证操作。给出验…

从科学角度分析,探索选择智能酒精壁炉的原因

酒精壁炉作为一种现代家居取暖方式&#xff0c;引人关注。从科学角度来看&#xff0c;为何选择酒精壁炉成为一个值得探讨的问题。酒精壁炉的燃料—乙醇&#xff0c;是一种简单化合物&#xff0c;其燃烧过程在化学上较为干净。当乙醇燃烧时&#xff0c;其主要产物是二氧化碳和水…

Day22 112路径总和 113路径总和II 106中后构造二叉树/中前构造二叉树 654最大二叉树

给定一个二叉树和一个目标和&#xff0c;判断该树中是否存在根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和。 递归&#xff1a; 可以采用深度优先的递归方式&#xff0c;前中后序都可以&#xff08;因为中节点没有处理逻辑&#xff09;。首先确定参…

Go Lang Fiber介绍

利用GoLang Fiber进行高性能Web开发 在不断发展的Web开发世界中&#xff0c;选择合适的框架至关重要。速度、简洁性和强大的功能集是每个开发者都追求的品质。在使用Go构建Web应用时&#xff0c;“Fiber”作为一个强大且轻量级的框架在众多选择中脱颖而出。在这份全面的指南中…

一个list 里面存放实体类,根据多个字段进行分组,最后将结果都保存,返回一个map 集合,一层一层的map 集合

目录 1 需求2 实现 1 需求 现在从数据库查询出一个list 集合的数据&#xff0c;是一个实体类&#xff0c;现在需要根据多个字段进行分组&#xff0c;最后只是返回一个map 集合。 一层一层的 2 实现 如果你想在最后一层的列表数据上进行计算&#xff0c;并将计算结果保存并返…

day 57 算法训练|动态规划part17

参考&#xff1a;代码随想录 647. 回文子串 1. dp数组&#xff08;dp table&#xff09;以及下标的含义 是不是能找到一种递归关系&#xff0c;也就是判断一个子字符串&#xff08;字符串的下表范围[i,j]&#xff09;是否回文&#xff0c;依赖于&#xff0c;子字符串&#x…