spring杂七杂八
SpringBoot接口开发的常用注解有哪些
-
@Controller 标记此类是一个控制器,可以返回视图解析器指定的html页面,通过@ResponseBody可以将结果返回json、xml数据。
-
@RestController 相当于@ResponseBody加 @Controller,实现rest接口开发,返回json数据,不能返回html页面。
-
@RequestMapping 定义接口地址,可以标记在类上也可以标记在方法上,支持http的post、put、get等方法。
-
@PostMapping 定义post接口,只能标记在方法上,用于添加记录,复杂条件的查询接口
-
@GetMapping 定义get接口,只能标记在方法上,用于查询接口的定义。
-
@PutMapping 定义put接口,只能标记在方法上,用于修改接口的定义。
-
@DeleteMapping 定义delete接口,只能标记在方法上,用于删除接口的定义。
-
@RequestBody 定义在方法上,用于将json串转成java对象。
-
@PathVarible 接收请求路径中占位符的值。
-
@ApiOperation swagger注解,对接口方法进行说明。
-
@Api wagger注解,对接口类进行说明。
-
@Autowired 基于类型注入。
-
@Resource 基于名称注入,如果基于名称注入失败转为基于类型注入。
项目的开发流程是什么?
1、产品人员设计产品原型。
2、讨论需求。
3、分模块设计接口。
4、出接口文档。
5、将接口文档给到前端人员,前后端分离开发。
6、开发完毕进行测试。
7、测试完毕发布项目,由运维人员进行部署安装。
MySQL常见的存储引擎及区别?
InnoDB
1、支持事务。
2、使用的锁粒度默认为行级锁,可以支持更高的并发;也支持表锁。
3、支持外键约束;外键约束其实降低了表的查询速度,增加了表之间的耦合度。
MyISAM
1、不提供事务支持
2、只支持表级锁
3、不支持外键
memory
数据存储在内存中
总结:
• MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果在应用中执行大量select操作,应该选择MyISAM
• InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB
MySQL建表时注意什么?
1、注意选择存储引擎,如果要支持事务需要选择InnoDB。
2、注意字段类型的选择,对于日期类型如果要记录时分秒建议使用datetime,只记录年月日使用date类型,对于字符类型的选择,固定长度字段选择char,不固定长度的字段选择varchar,varchar比char节省空间但速度没有char快;对于内容介绍类的长广文本字段使用text或longtext类型;如果存储图片等二进制数据使用blob或longblob类型;对金额字段建议使用DECIMAL;对于数值类型的字段在确保取值范围足够的前提下尽量使用占用空间较小的类型,
3、主键字段建议使用自然主键,不要有业务意义,建议使用int unsigned类型,特殊场景使用bigint类型。
4、如果要存储text、blob字段建议单独建一张表,使用外键关联。
5、尽量不要定义外键,保证表的独立性,可以存在外键意义的字段。
6、设置字段默认值,比如:状态、创建时间等。
7、每个字段写清楚注释。
8、注意字段的约束,比如:非空、唯一、主键等
解决跨域问题
1、JSONP
通过script标签的src属性进行跨域请求,如果服务端要响应内容则首先读取请求参数callback的值,callback是一个回调函数的名称,服务端读取callback的值后将响应内容通过调用callback函数的方式告诉请求方
2、添加响应头
服务端在响应头添加 Access-Control-Allow-Origin:*
3、通过nginx代理跨域
由于服务端之间没有跨域,浏览器通过nginx去访问跨域地址。
-
浏览器先访问http://192.168.101.10:8601 nginx提供的地址,进入页面
-
此页面要跨域访问http://192.168.101.11:8601 ,不能直接跨域访问http://www.baidu.com:8601 ,而是访问nginx的一个同源地址,比如:http://192.168.101.11:8601/api ,通过http://192.168.101.11:8601/api 的代理去访问http://www.baidu.com:8601。
这样就实现了跨域访问。
浏览器到http://192.168.101.11:8601/api 没有跨域
nginx到http://www.baidu.com:8601通过服务端通信,没有跨域。
Mybatis分页插件的原理?
首先分页参数放到ThreadLocal中,拦截执行的sql,根据数据库类型添加对应的分页语句重写sql,例如:(select * from table where a) 转换为 (select count(*) from table where a)和(select * from table where a limit ,)
计算出了total总条数、pageNum当前第几页、pageSize每页大小和当前页的数据,是否为首页,是否为尾页,总页数等。
树型表的标记字段是什么?如何查询MySQL树型表?
树型表的标记字段是parentid即父结点的id。
查询一个树型表的方法:
-
当层级固定时可以用表的自链接进行查询。
-
如果想灵活查询每个层级可以使用mysql递归方法,使用with RECURSIVE 实现。
MyBatis的ResultType和ResultMap的区别?
ResultType:指定映射类型,只要查询的字段名和类型的属性名匹配可以自动映射。
ResultMap:自定义映射规则,当查询的字段名和映射类型的属性不匹配时可以通过ResultMap自定义映射规则,也可以实现一对多、一对一映射。
#{} 和 ${} 有什么区别?
#{}是标记一个占位符,可以防止sql注入。
${} 用于在动态 sql中拼接字符串,可能导致sql注入。
系统如何处理异常?
我们自定义一个统一的异常处理器去捕获并处理异常。
使用控制器增加注解@ControllerAdvice和异常处理注解@ExceptionHandler来实现。
-
处理自定义异常
程序在编写代码时根据校验结果主动抛出自定义异常类对象,抛出异常时指定详细的异常信息,异常处理器捕获异常信息记录异常日志并响应给用户。 -
处理未知异常
接口执行过程中的一些运行时异常也会由异常处理器统一捕获,记录异常日志,统一响应给用户500错误。
在异常处理器中还可以针对某个异常类型进行单独处理。
请求参数的合法性校验如何做?
使用基于JSR303的校验框架实现,SpringBoot提供了JSR-303的支持,它就是spring-boot-starter-validation,它包括了很多校验规则,只需要在模型类中通过注解指定校验规则,在controller方法上开启校验。
什么情况Spring事务会失效
- 在方法中捕获异常没有抛出去
- 非事务方法调用事务方法
- 事务方法内部调用事务方法
- @Transactional标记的方法不是public
- 抛出的异常与rollbackFor指定的异常不匹配,默认rollbackFor指定的异常为RuntimeException
- 数据库表不支持事务,比如MySQL的MyISAM
- Spring的传播行为导致事务失效,比如:
PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED
PROPAGATION_REQUIRED- 支持当前事务如果当前没有事务,就新建一个事务。这是最常见的选择
PROPAGATION_SUPPORTS-- 支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。PROPAGATION_REQUIRES_NEW-- 新建事务如果当前存在事务,把当前事务挂起PROPAGATION_NOT_SUPPORTED-- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
PROPAGATION_NEVER-- 以非事务方式执行,如果当前存在事务,则抛出异常。PROPAGATION_NESTED-- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则与PROPAGATION_REQUIRED类似的操作