后端杂七杂八系列篇一

后端杂七杂八系列篇一

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

java 复制代码
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并且可以使用的前提下"。

java 复制代码
@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;
}
java 复制代码
//前提:必须写入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)

java 复制代码
@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]

java 复制代码
        // 使用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);
java 复制代码
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个。若有多个结果,则报异常。此方法只用于只有一个结果的情况。(最常用)
java 复制代码
List<BannerItem> bannerItems = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getBannerId, id)
                        .list();
java 复制代码
BannerItem bannerItem = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getId, id)
                        .one();

QuryWrapper的用法

java 复制代码
   @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 并不是直接等价的,但它们都用于构建查询条件。

java 复制代码
//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 表达式或者其他的条件构造器,用于进一步定义查询条件。

java 复制代码
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=? 形式

java 复制代码
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().
eq("attr_id",key).
eq("catelog_id",catelogId);

② where A=? or B=? 形式

java 复制代码
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().
eq("attr_id",key).
or().
eq("catelog_id",catelogId);

③ where A=? and (B...)

java 复制代码
 SELECT
 *
 FROM project
 WHERE 
 type = 1 
 AND (DATE_FORMAT(create_time, '%Y-%m') <= '2022-01');
java 复制代码
projectMapper.selectList(new LambdaQueryWrapper<Project>()
                .eq(Project::getType,1)
                .and(qw -> qw.apply("DATE_FORMAT(create_time, '%Y-%m') <= '" + dateStr + "'")));
java 复制代码
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'
	);
java 复制代码
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

java 复制代码
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;
java 复制代码
// 示例二
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=?

java 复制代码
//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=?

java 复制代码
//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=?)

java 复制代码
//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=?)

java 复制代码
// 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=?))

java 复制代码
// 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 注解用于清空缓存。

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

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

相关推荐
二闹3 分钟前
三个注解,到底该用哪一个?别再傻傻分不清了!
后端
用户490558160812515 分钟前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白17 分钟前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端
码事漫谈18 分钟前
VS Code 终端完全指南
后端
该用户已不存在43 分钟前
OpenJDK、Temurin、GraalVM...到底该装哪个?
java·后端
怀刃1 小时前
内存监控对应解决方案
后端
HMBBLOVEPDX1 小时前
MySQL的多版本并发控制(MVCC):
数据库·mysql·mvcc
TT哇1 小时前
@[TOC](计算机是如何⼯作的) JavaEE==网站开发
java·redis·java-ee
码事漫谈1 小时前
VS Code Copilot 内联聊天与提示词技巧指南
后端
Tina学编程1 小时前
48Days-Day19 | ISBN号,kotori和迷宫,矩阵最长递增路径
java·算法