java后端项目-尚融宝-学习笔记001-032

013项目的配置

创建默认的SpringBoot项目

pom.xml的配置里面添加依赖

resources的application.properties配置数据库连接,里面有四点

014

开发基于数据库的增删改查的时候第一步就是应该分析数据库的表,user表创建对象应该定义一个user类,创建到一个实体entity的包中

在user类中创建成员,这些成员应该对应数据库里的属性字段

自动生成了一些get、set、equals、hashcode方法,前提是安装了lombok插件

创建Usermapper接口,在mapper包里

这个接口需要继承Mybatis-Plus里的BaseMapper(通用Mapper,里面实现了一些基本的增删改查

BaseMapper需要一个泛型。你要管理什么,这个泛型就填什么,这里就填要管理的刚刚创建的User

现在的问题是怎么让他在Spring启动的时候运行起来,所以要让他被Spring扫描到,所以需要添加一个注解@MapperSc

扫描的名字就是Mapper所在的包,把它复制过来

测试

@SpringBootTest自动帮我们创建了Spring上下文环境,没有启动服务直接测试可以自动帮我们创建环境

然后把UserMapper注入进来--常用的注入注解Autowired,报错找不到bean,因为他是一个接口并不能创建真正的实体类,所以这里我们用@Resource比较好

Autowired是Spring的注解,Resource是J2EE的注解

然后就可以写测试方法了。BaseMapper里的方法都被UserMapper继承下来了,可以直接使用

015

补充日志查看到配置文件中,然后就可以看到==>是对MySQL的输入,<==是输出,这样打印显示就可以不写因为可以直接在日志里面看到

但是日志里是关系型数据库数据的二维结果,打印的是程序把它封装成一个个对象的结果

016根据通用BaseMapper里的方法写增删改查

创建测试类MapperTest

添加注释@SpringBootTest,配置上下文环境

@Resource注入类

@Test,然后在下面写测试方法

调用userMapper.insert,需要一个实体,还在前面创建一个实体,然后初始化

用int接收insert方法返回的结果,然后打印一下

这个通用Mapper里的查询方法都是单表查询,如果找到多个结果就会报错

数据更新,根据id修改User里的age属性。id的数据类型是long,所以赋值的时候是1L

017通用service,封装了常见的业务层逻辑

创建接口UserService,继承IService

创建实现类UserServiceImpl,有三点注意

//继承了ServiceImpl,目的是默认拥有IService里面定义的一些业务方法

//实现了UserService接口,如果以后自己在UserService接口里自己定义一些拓展方法,可以在UserServiceImpl里进行拓展实现

//两个泛型,因为ServiceImpl有两个泛型,要一一对应,<UserMapper,User>

写好之后不要忘记在前面加@Service注解,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中

然后在测试项目中就可以创建测试类测试实体了

@SpringBootTest,@Resource,创建实体private UserService userService

@Test,写测试方法,用userService.来调用

alt+回车快捷键定义方法的返回变量

记得运行之前把MySQL启动啊

快捷键5.for 自动生成for(inti=0;i<5;i++)

019自定义Mapper持久层

自定义的函数,sql语句就必须自己来完成了,所以下一步就是创建一个xml文件

默认属于资源文件,所以把他创建在Resource文件目录下,再新建一个包mapper

配置文件选file,名字和接口名字相同,扩展名是.xml

配置完成后就开始写sql语句,就是方法的具体实现

写完就测试,在MapperTest里

020自定义mapper目录

配置文件和自定义接口一定要能匹配上啊BindingException:Invalidbondstatement(no found)两种情况:一种是文件没找着,一种是方法没找着

如果没有定义在默认目录,需要额外配置mapper-locations,写在application.properties

021自定义service业务层

022常用注解@TableName

有时候数据库的表不是你设计的,有专门的数据库设计师架构工程师先设计完了,再给初级开发工程师来写。表的设计有一定的规范,比如所有和用户相关的数据表有一个前缀,所有和商品相关的数据表有一个前缀,

改了数据库中表的名字之后,从test方法里调用的接口到接口的配置文件,修改配置文件sql语句里的名字,就可以

如果是调用的通用Mapper,里面的sql语句不是我们自己写的,是通过反射机制在运行过程中动态产生的,那么他的列名和数据库中的表名一定是根据我们实体的属性名和实体的类名自动生成的。我们的实体叫User,所以自动生成的数据库的表名就叫User。

那如何将我们的实体的类名映射到一个形式不一样的数据库的表名上呢?

就在这个类名的上面加一个注解@TableName(value="t_user"),括号里把真正的表名写上

总结就是如果没有注解,表名=类名,有这个注解,表名=value属性的名字

023垂直分表和水平分表

雪花算法

背景是数据大规模增长需要扩展数据库,方式主要有:业务分库、主从复制、数据库分表

分表(单表拆分 有两种形式:垂直分表(婚恋网站按照年龄性别查询)和水平分表(微信淘宝数据访问量的需求)

垂直分表就是把不常用的字段和常用的查询字段划分到不同的表,可以提升查询的性能---隐含了数据库优化的一个方法

比如用户基本信息表user和用户简介表user_info,可以用用户id来进行关联。那user有主键自增长策略,user_info就没有,就user是什么他对应就是什么。这就叫主键一对一关联,是垂直分表的一种解决方案。

水平分表,适合表行数特别大、超千万级别的表,但关键还是要看表的性能。如果是并发量比较大的表,超过1000万就要分表了,不分的话可能带来很大的安全隐患;如果是像日志表,单纯存储数据的,平时也没人看,那多点不分也行。

水平分表相比垂直分表会引入更多的复杂性,垂直分表做一个一对一的关联查询就可以。

024、025水平分表的业务复杂性

主键自增。如果是一张表放满再放第二张,就会导致服务器访问压力不均衡,但优点是动态扩展,可以快用完了再买服务器

如果是轮流放,可能导致主键冲突。也可以分别定义起始id和步长,但是无法扩展,面临数据迁移的问题很麻烦。而且前面的表如果有数据删除再补上数据,可能会和新表冲突。

如果是每次添加前先查询一下,又存在性能问题

哈希。复杂点在于初始表数量的确定、每次扩充表都要重新算、而且id没有连续性,没有先后顺序,不能用MySQL的聚簇索引,用来做主键查询效率很低

026雪花算法twitter--19位分布式id

保证不同表的主键不重复性,且相同的表的主键有序

Mybatis-plus不设置主键策略,默认用的就是雪花算法

手动设置就是注解:@TableId(type =IdType.ASSIGN_ID)

这就是@TableId的type属性

027设置默认的id列

Mybatis-plus只认识id这个名字作为主键默认使用雪花算法,如果你叫uid就没有默认值了。具体叫什么名字是要看数据库表的设置的。

加入注解@TableId,告诉Mybatis-plus这个是id

需要改动的地方有数据库表里的名字和实体定义时的名字

028@TableId的value属性

如果数据库中叫uid,实体中叫id,就给注解设置一个value值,把表里的名字告诉他@TableId(value = "uid")

应用场景是代码已经写完了但数据库的字段更改了

@TableId的type属性还有一个是@TableId(type = IdType.AUTO)主键自增

在数据库层面也需要配合,要勾选自动递增,不然无效

再加入没有定义id的数据的话是根据当前最大的id值来递增

030@TableField属性

在数据库中新增字段create_time之后,也要在实体定义里加上createTime。时间最好不用Date类型因为里面有很多方法都被淘汰掉了,用LocalDateTime

数据库里的字段和实体的属性名字并没有对应上,因为Mybatis-plus数据库下划线和代码驼峰会做自动的转换,是普遍的规范来的

如果是别的情况的名字对应不上,就要使用@TableField(value= "数据库里的名字"),把数据库里的名字告诉他

031数据库字段的自动填充

作为一个业内规范,创建时间和更新时间如何像主键一样不需要主动维护而是自动更新呢?

首先在数据库里是可以设置默认值,时间可以勾选根据当前时间戳更新,每次对表进行维护的时候就会自动更新,但这个只适用于updateTime

createTime则在默认值的设置的地方添加一个关键字CURRENT_TIMESTAMP

在业务层并没有对数据进行操作但是在数据库中却实现了更新,新插入的数据也有这两个字段

但是这种方式只适用于MySQL,如果是别的类型的数据库比如SqlServer会有不一样的解决方式,那能不能数据库方面不设置而在业务层统一进行管理呢?

032在业务层实现自动填充功能

步骤1 注解填充字段

@TableField(fill

= FieldFill.INSERT)

private LocalDateTime createTime;

@TableField(fill = FieldFill.UPDATE)

private LocalDateTime updateTime;

还可以@TableField(fill

= FieldFill.INSERT_UPDATE)

但是这只是告诉他要填充、要改,具体填什么改什么?

步骤2实现元对象处理器接口(自定义类MyMetaObjectHandler实现MetaObjectHandler接口

@Component注解,在运行的时候自动加到Spring上下文当中,这个类的对象就会被Spring自动管理,不需要new

重写里面的两个方法

@Override

public void

insertFill(MetaObject metaObject) {

this.strictInsertFill(metaObject,"createTime",

LocalDateTime.class,LocalDateTime.now());

}

四个参数分别是(元数据对象,对哪个字段做填充,这个字段的数据类型,要填充的具体内容)

同理:

@Override

public void

updateFill(MetaObject metaObject) {

this.strictInsertFill(metaObject,"updateTime",

LocalDateTime.class,LocalDateTime.now());

}

为了清楚地看到结果,可以把日志打出来@Slf4j,然后log.info("填充");写在方法里。 是lombok插件的一个扩展

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值