mybatis-plus
- 1.UUID算法简介:
- 2.mybatis-plus的id自动生成策略:默认使用雪花算法
- 3.怎么实现自动增长的?这需要先查询一次吗?
- 4.uuid算法(生成字符串id),雪花算法(生成数字id)。
- 5.MybatisPlus提供了单表的增删改查方法,程序员可以直接使用
- 6.复杂操作
- 7.MybatisPlus支持使用多种格式组装条件,我们推荐使用Lambda格式
- 8.语句的原理:
- 9.wrapper的设置条件:
- 10.重点掌握:
- 11.::是啥来着?
- 12.wrapper为空时会查询出数据吗?
- 13.注意: .默认是and() , 写成.or(),逻辑关系就变成or()了。
- 14.查询所有,必须要使用条件查询,wrapper
- 15.投影(指定列):select * from aaa,的*叫做投影。
- 16.分组统计(用的很少):
- 17.书写格式:推荐lamada,设置条件的用链式编程,分组几乎不用。
- 18.mybatis-plus内置了分页插件,但不是pagehelper,原理基本相同都是拦截器。
- 19.使用分页时:要先注册mybatis-plus拦截器,mybatis-plus拦截器要包含分页拦截器。(大的套小的)
- 20.注解:@TableField
- 21.注意:mybatis-plus要求,最好数据库的字段和实体的字段一一对应,实体类字段不能多但是可以少。
- 22.为什么要用逻辑删除:
- 23:逻辑删除:
- 24.给别人复制项目:先clean一下,然后直接在父项目上复制,再粘贴到其他文件中,就可以了。
- 25.自动填充注解:@TableField(fill = FieldFill.Insert)
- 26.MyMetaObjectHandle编写自动填充逻辑时,metaObject是employeeMapper吗?
- 27.ThreadLocal:
- 28.ConcurrentHashMap和ThreadLocal的区别:
- 29.jwt:
- 30.多线程之间的内存是什么样的。
- 31.写代码小技巧:可以直接.returen .if .for等。
- 32.在mapper接口打断点,项目会跑不起来,卡到断点上。所以不要在mapper接口上打方法断点。
- 32.IDEA的全局搜索的对勾是啥
- 33.IDEA自动删除类中无用的import包:
- 34.怎么自动生成测试用例。
- 35.一个接口可以继承多个接口.
- 36.interface接口是否有父类?
- 37.mybatis起别名:
- 38:mybatis-plus常用注解:
1.UUID算法简介:
UUID 的十六个八位字节被表示为 32个十六进制数字,以连字号分隔的五组来显示,形式为 8-4-4-4-12,总共有 36个字符(即三十二个英数字母和四个连字号)。例如:
123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
组成部分:
1)当前日期及时间
2)时钟序列
3)全局唯一的IEEE机器识别号。
数字 M的四位表示 UUID 版本,当前规范有5个版本,M可选值为1, 2, 3, 4, 5 ;
数字 N的一至四个最高有效位表示 UUID 变体( variant ),有固定的两位10xx因此只可能取值8, 9, a, b
UUID版本通过M表示,当前规范有5个版本,M可选值为1, 2, 3, 4, 5。这5个版本使用不同算法,利用不同的信息来产生UUID,各版本有各自优势,适用于不同情景。具体使用的信息
version 1, date-time & MAC address
version 2, date-time & group/user id
version 3, MD5 hash & namespace
version 4, pseudo-random number
version 5, SHA-1 hash & namespace
使用较多的是版本1和版本4,其中版本1使用当前时间戳和MAC地址信息。版本4使用(伪)随机数信息,128bit中,除去版本确定的4bit和variant确定的2bit,其它122bit全部由(伪)随机数信息确定。
因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5。
原文链接:https://blog.csdn.net/weichi7549/article/details/107825300
2.mybatis-plus的id自动生成策略:默认使用雪花算法
3.怎么实现自动增长的?这需要先查询一次吗?
自动增长:根据上一个数据的id+1
是的
需要先获取id,存到对象中,再存入数据库。
使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。
4.uuid算法(生成字符串id),雪花算法(生成数字id)。
数据库表设计的id类型是:
1)varchar,用uuid
2)int,可以用雪花算法。
注意:自动增长,用的越来越少,分库分表会有问题。
5.MybatisPlus提供了单表的增删改查方法,程序员可以直接使用
int insert(T entity);// 插入一条记录
T selectById(Serializable id);// 主键查询
List<T> selectBatchIds(Collection idList); // 主键批量查询
int updateById(T entity);// ID修改
int deleteById(Serializable id); // ID删除
int deleteBatchIds(Collection idList);// ID批量删除
6.复杂操作
List<T> selectList(Wrapper<T> queryWrapper);// 条件查询,返回值为多条记录
T selectOne(Wrapper<T> queryWrapper);// 条件查询,返回值为一条记录
int delete(Wrapper<T> wrapper);// 条件删除
int update(T entity,Wrapper<T> updateWrapper);// 条件更新
7.MybatisPlus支持使用多种格式组装条件,我们推荐使用Lambda格式
//4. 条件查询(age > 18) age有可能传递 也有可能不传递
//使用LambdaQueryWrapper对象封装条件 [掌握]
@Test
public void testSelectList4() {
//1. 定义查询条件
//Integer ageParam = 18;
Integer ageParam = null;
//2. 封装查询条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();//用于封装查询条件的对象,泛型为要操作的实体类
wrapper.gt(ageParam != null, User::getAge, ageParam);//参数一位置其实一个判断条件,如果它不成立,这个语句相当于没有
//3. 执行查询
List<User> userList = userMapper.selectList(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
}
8.语句的原理:
1)批量查询是用的where id in(,).
2)mybait-plus,的更新使用的是动态sql。
9.wrapper的设置条件:
Wrapper(包装)对象来封装各种条件,比如条件、分页、排序、分组、过滤等等
查询方法 | 说明 | 例子 |
---|---|---|
eq、ne、gt、ge、lt、le、isNull、isNotNull | 比较运算 | eq(“name”, “老王”)---> name = ‘老王’ |
like、notLike、likeLeft、likeRight | 模糊查询 | likeRight(“name”, “王”)---> name like ‘王%’ |
in、notIn、between、notBetween | 范围运算 | in(“age”,{1,2,3})---> age in (1,2,3) |
or、and | 拼接 | eq(“id”,1).or().eq(“name”,“老王”)---> id = 1 or name = ‘老王’ |
e:等于,g大于(greater than),l小于(less than)
like(模糊)、notLike(不模糊)、likeLeft(模糊符%,在左边)、likeRight(模糊符%,在右边)
10.重点掌握:
传递age条件查询。
//6. 查询条件演示(链式编程写法)
@Test
public void testSelectList6() {
//1. 封装查询条件
//SELECT * FROM user WHERE (name = ? AND age BETWEEN ? AND ? OR tel LIKE ?)
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//链式编程写法
wrapper.eq(User::getName, "张三")
.between(User::getAge, 10, 100)
.or().likeRight(User::getTel, "123");
//2. 执行查询
List<User> userList = userMapper.selectList(wrapper);
for (User user : userList) {
System.out.println(user);
}
}
11.::是啥来着?
12.wrapper为空时会查询出数据吗?
没有条件,会查出全部数据。
多写链式编程写法。
13.注意: .默认是and() , 写成.or(),逻辑关系就变成or()了。
14.查询所有,必须要使用条件查询,wrapper
15.投影(指定列):select * from aaa,的*叫做投影。
就是指要查询后显示的字段,指定列可以提高查询效率。
.select(实体类::字段名)
16.分组统计(用的很少):
过滤(必须和分组配合使用):例如过滤不为null的
注意:分组统计:还是自己写注解的sql语句比较方便。
17.书写格式:推荐lamada,设置条件的用链式编程,分组几乎不用。
18.mybatis-plus内置了分页插件,但不是pagehelper,原理基本相同都是拦截器。
19.使用分页时:要先注册mybatis-plus拦截器,mybatis-plus拦截器要包含分页拦截器。(大的套小的)
mybatis-plus拦截器的配置,每个版本配置可能不同,需要面向百度配置拦截器。
20.注解:@TableField
@TableField标注在属性上,它有两个特殊用法:
- exist:当实体类中属性在数据库中不存在时,使用@TableField(exist = false)标识
- select:当数据表中某个字段不想被查询映射到实体类中的某个指定字段上时,使用@TableField(select = false)标识
1)@tabeldField(exist = false)的作用:
比如再次输入密码,确认两次密码一致,的password2字段,数据库的表中,并不需要这个password2这个字段。
这时候password2属性需要加上@tabeldField(exist = false)
2)@TableField(select = false)的作用:
用户密码的这一项不需要查询出来,并返回到前端去。
21.注意:mybatis-plus要求,最好数据库的字段和实体的字段一一对应,实体类字段不能多但是可以少。
mybatis不要求一致。
22.为什么要用逻辑删除:
1)大数据:数据资源是很珍贵的,不能真的删除。
2)数据之间有约束,另一个表里可能会用到要删除的数据(保证数据的完整性)。
23:逻辑删除:
注解:@TableLgic(value = “1”,delval = “0”)声明该字段是逻辑删除,正常是1,删除是0。
注意:逻辑删除,想恢复就得自己去数据库改了。(实际逻辑上不允许恢复)
24.给别人复制项目:先clean一下,然后直接在父项目上复制,再粘贴到其他文件中,就可以了。
25.自动填充注解:@TableField(fill = FieldFill.Insert)
插入时进行填充。
26.MyMetaObjectHandle编写自动填充逻辑时,metaObject是employeeMapper吗?
不是,它包含被操作的实体类对象。
在进入xml之前,会先被填充上属性值。
27.ThreadLocal:
通俗理解:ThreadLocal包含一个map集合,key是线程,value是值。
threadlocal:线程1放进去的,只有线程1可以取出来。
线程内共享,线程间隔离。
ThreadLocal属于线程的工作空间中的局部变量,是线程私有的。
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。
线程局部变量(ThreadLocal)的功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的。在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。map的键就是每个线程对象,值就是每个线程所拥有的值
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
原文链接:https://blog.csdn.net/supermao1013/article/details/84947824
注意:分页查询的pagehelper也是用的threadlocal。
28.ConcurrentHashMap和ThreadLocal的区别:
ConcurrentHashMap是被多个线程共享的(,一个被多个线程共享使用静态的HashMap集合对象),ThreadLocal是被当前线程所私有的。
每个线程都有自己的一个堆栈空间,操作map集合时,把map复制到自己的内存空间
29.jwt:
JWT结构:
JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串
JWT认证的优势
对比传统的session认证方式,JWT的优势是:
简洁:JWT Token数据量小,传输速度也很快
因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端,特别适用于分布式微服务
单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题
适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端
因为这些优势,目前无论单体应用还是分布式应用,都更加推荐用JWT token的方式进行用户认证
原文链接:https://blog.csdn.net/weixin_45070175/article/details/118559272
30.多线程之间的内存是什么样的。
Java内存模型(Java Memory Model)描述了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这样的底层细节。
所有的共享变量都存储于主内存。这里所说的变量指的是实例变量(成员变量)和类变量(静态成员变量)。不包含局部变量,因为局部变量是线程私有的,因此不存在竞争问题。每一个线程还存在自己的工作内存,线程的工作内存,保留了被线程使用的变量的工作副本。线程对变量的所有的操作(读,取)都必须在工作内存中完成,而不能直接读写主内存中的变量,不同线程之间也不能直接访问对方工作内存中的变量,线程间变量的值的传递需要通过主内存完成。
31.写代码小技巧:可以直接.returen .if .for等。
为啥applicaton.yaml要放在web包下面?
之前的ssm整合的时候,spring启动配置文件要写在tomcat下面,webManageApplication,也写在web下,所以application.yaml也写在web下
mybatis和mybatis-plus的配置yaml文件,同时存在咋办?
32.在mapper接口打断点,项目会跑不起来,卡到断点上。所以不要在mapper接口上打方法断点。
32.IDEA的全局搜索的对勾是啥
搜索类,ctrl+N。如果想搜索Jar包里的类,那么需要在搜索类的筛选条件处点选Include non-project items选项,就可以查看Jar包里的类了
搜索文件,ctrl+shift+N
搜索函数,ctrl+art+shitf+N
搜索字符串,ctrl+shift+F,可以筛选搜索范围
原文链接:https://blog.csdn.net/u013364531/article/details/83505957
33.IDEA自动删除类中无用的import包:
Ctrl + Alt + O
34.怎么自动生成测试用例。
可以用一下框架:比如EvoSuite
35.一个接口可以继承多个接口.
interface C extends A, B {}是可以的.
36.interface接口是否有父类?
没有
37.mybatis起别名:
MyBatis中使用@Results注解来映射查询结果集到实体类属性。
/*
如果数据库中返回结果的字段跟实例类中的属性名有不对应的,自己定义映射规则
@Results:用于定义映射规则,相当于xml中的resultMap标签
id:表示当前映射的唯一标识,不可以重复
IllegalArgumentException: Result Maps collection already contains value for com.itheima.mapper.UserMapper.userMap
*/
@Results(
id="userMap",
value = {
@Result(column = "uid",property = "uid",id=true),
@Result(column = "username",property = "name"),
@Result(column = "password",property = "password"),
@Result(column = "email",property = "email"),
@Result(column = "birthday",property = "birthday"),
}
)
@Select("select uid,name as username,password,email,birthday from user;")
List<User> findAll();
//根据主键查询
//@ResultMap("userMap")用于引用定义好的映射规则
@ResultMap("userMap")
@Select("select uid,name as username,password,email,birthday from user where uid = #{uid}")
User findByUid(Integer uid);
38:mybatis-plus常用注解:
@TableName:对数据表名注解
@TableId:表主键标识
@TableId(value = “id”, type = IdType.AUTO):自增
@TableId(value = “id”, type = IdType.ID_WORKER):分布式全局唯一ID 长整型类型
@TableId(value = “id”, type = IdType.UUID):32位UUID字符串
@TableField:表字段标识
@TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的。
@TableField(exist = true):表示该属性为数据库表字段。
@TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
@TableLogic:表字段逻辑处理注解(逻辑删除)
原文链接:https://blog.csdn.net/weixin_44455452/article/details/93053590