当前位置: 代码迷 >> 综合 >> mysql 添加索引+Springboot+shiro导致session污染+PowerMock+@InjectMocks,@Mock+其他= 202001
  详细解决方案

mysql 添加索引+Springboot+shiro导致session污染+PowerMock+@InjectMocks,@Mock+其他= 202001

热度:119   发布时间:2023-11-07 14:45:00.0

一、mysql 添加索引

我使用了多列索引来提高查询速度,如图第二条,某个查询语句的条件同时包含这个三个字段,比如select 1 from xxx where type = 1 and tag_set_id = 12 and tag_id = 888 limit 1,但是这个表记录又特别多,查询起来特别慢,所以加多列索引:
(因为该sql是判断是否被使用,加一个limit 1 就是为了查到一个就返回,不用继续下去了)
在这里插入图片描述

优点
1、大大加快数据的检索速度;
2、创建唯一性索引,保证数据库表中每一行数据的唯一性;
3、加速表和表之间的连接;
4、在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。

缺点
1、索引需要占物理空间。
2、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。

基本语法是:

ALTER TABLE <表名> ADD INDEX (<字段>);

另:

1.添加PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
2.添加UNIQUE(唯一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE (`column`)
3.添加INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
4.添加FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
5.添加多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
6. 删除索引
alter table 表名 drop index 索引名;

参考:索引的作用及优缺点,
mysql 添加索引 mysql 如何创建索引,
mysql创建脚本索引范例

二、Springboot+shiro导致session污染

前提:同一个服务器,一套系统,部署两次(做测试环境A和开发环境B),仅仅端口不同。

问题:A登录了,B再登录,回过头来点A的界面,发现需要重新登录。

原因:因为shiro是基于session会话的权限管理,那么浏览器打开一次就会产生一个session,在session活跃期间,只要你浏览器不关闭,session信息是一直有效的。其session信息是写在cookie里的。如果你是两个域的话,session信息不回互相干扰。但如果你是一个域问题就来了,a登录后session信息会写入浏览器cookie里,当b登录时session信息更新此域的信息。a原始登录的session信息就会失效。因此b登录后,会挤占a的session信息。

解决:
在shiro配置文件的sessionManager()方法里修改session的key值:

@Beanpublic DefaultWebSessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();Cookie cookie=sessionManager.getSessionIdCookie();cookie.setName("newsessid");return sessionManager;}

主要是保证两份代码的session的key值不同就可以了,因为我们过段时间会合开发代码到测试,所以我把key值写到了配置文件里。

参考:springboot集成shiro的session污染问题,
Springboot+shiro解决session污染的问题

另:springboot + shiro之登录人数限制、登录判断重定向、session时间设置

三、PowerMock

这个测试框架比较强大,可以mock私有方法,静态方法,测试私有方法,final类等。我主要用来mock私有方法。但是项目已经引入mockito了,所以我引入powermock可能是和mockito冲突了,导致没有生效。并且 合理的单元测试不对私有方法进行测试,只会对共有方法测试,私有方法会被共有方法调用,所以也就测试到了。所以这里记录一下:
Mockito 中文文档 ( 2.0.26 beta ),
有了它(powerMocker)再也不怕单元测试不达标了!,
PowerMock 精萃,
无所不能的PowerMock,mock私有方法,静态方法,测试私有方法,final类,
使用Powermock对私有方法进行mock,
PowerMock使用详解,
PowerMock Mock 私有方法,

四、@InjectMocks,@Mock

Mockito里面使用:

如果所有的 Mock 对象全部通过手工来创建,那就不容易体现出 Mockito 的优越性出来。因此对于被测试对象的创建,Mock 属性的注入应该让 @Mock 和 @InjectMocks这两个注解大显身手了。

@InjectMocks:创建一个实例,简单的说是这个Mock可以调用真实代码的方法,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中。

@Mock:对函数的调用均执行mock(即虚假函数),不执行真正部分。

@Spy:对函数的调用均执行真正部分。

@Autowird 等方式完成自动注入。在单元测试中,没有启动 spring 框架,此时就需要通过 @ InjectMocks完成依赖注入。
@InjectMocks会将带有@Spy 和@Mock 注解的对象尝试注入到被 测试的目标类中。记住下面这两句话即可:

Usually when you are unit testing, you shouldn’t initialize Spring context. So remove Autowiring.
Usually when you do integration testing, you should use real dependencies. So remove mocking.

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
    @Mockprivate MyMapper myMapper;@InjectMocksprivate MyService myService;@Testpublic void testInjectMocks() {
    System.out.println(myService.MyMapper().getClass());}

MyService 被标记了 @InjectMocks,在 setUp方法中 执行 MockitoAnnotations.initMocks(this); 的时候,会将标记了 @Mock 或 @Spy 的属性注入到 service 中。MyService 里面的 MyRepository 完全被Mock实例替换,所有的调用都是针对Mock生成类的。

参考:@InjectMocks,
Mockito的使用(二)——@InjectMocks、@Spy、@Mock,

五、其他

  1. springboot干货——(八)springboot引入外部xml配置文件
  2. 8080端口被占用:

windows:
netstat -ano | findstr 8080 指令的意思是找出占用8080端口的进程pid
taskkill -pid 7244 -f,回车

Linux:
netstat -anp |grep 8080
kill -9 PID 17413

  相关解决方案