博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring boot之旅
阅读量:3533 次
发布时间:2019-05-20

本文共 4306 字,大约阅读时间需要 14 分钟。

1. 初步认识

以往,我们用spring开发web应用时,需要:

  • ①Maven或Gradle,SpringMVC和Servlet API;
  • ②web.xml(声明了Spring的DispatcherServlet);
  • ③启用了Spring MVC的Spring配置;
  • ④控制器类;
  • ⑤Tomcat等。

其中只有控制器与我们的应用有关,剩下的都是Spring开发Web程序必需的通用样板。

boot的精要四个核心:

  • ①自动提供配置(在classpath里发现和自动配置JPA、Spring MVC、模板、安全等);
  • ②起步依赖,它能帮忙引库(利用传递依赖解析(maven+gradle)把常用库聚合在一起(版本都经过测试,不会不兼容));
  • ③命令行界面,无需构建(非必要组成,简化开发,检测要向classpath添加哪些起步依赖);
  • ④Actuator(运行时检视程序内部,eg.上下文配置bean、环境变量、配置属性和命令行参数、线程状态、最近的HTTP请求跟踪、内存用量,垃圾回收,web请求+数据源用量等)。

spring boot不是应用服务器(是内嵌的servlet容器提供),没有实现JPA或JMS规范(是配置了某JPA实现),没引入代码生成(用了spring4的条件化配置+传递依赖解析(maven+gradle))。本质上,spring boot就是spring。

2.实践

boot开发推荐使用.yml格式的配置文件+gradle,这里我们还是采用和原有项目兼容的properties文件+maven,以下为部分示例:

在配置文件中,需要注意spring.jpa.properties.hibernate.hbm2ddl.auto的配置,不符合该规范的命名会报错。

server.port=8997server.contextPath=/boot-server# 数据库访问配置spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.primary.driverClassName=com.mysql.jdbc.Driverspring.datasource.primary.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8spring.datasource.primary.username=testspring.datasource.primary.password=test## 显示Sqlhibernate.show_sql=true## 建表方式,must be spring.jpa.properties格式#出现Table 'test.user' doesn't existspring.jpa.properties.hibernate.hbm2ddl.auto=update# 方言spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

我们使用spring data JPA时,注意使用注解映射实体类时,要implements Serializable,同时我们会发现JPA进行表与表之间的关联时,会出现外键,即使可通过注解或其他方式,防止建表时创建外键,但查询的时候造样生成了,这时候可以通过@Transient注解巧妙地避开该问题。

生成外键示例:

类{    ...    @ManyToMany(cascade = CascadeType.DETACH, fetch = FetchType.EAGER)    @JoinTable(name = "user_authority", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))    private List
authorities;}

避开外键生成示例:

类{    ...    @Transient    private List
authorities;}

该种方法,把强依赖关系放到业务逻辑控制,这也是高性能mysql强烈推荐的基于单表开发。

同时hibernate5也为我们提供了很强大的校验功能,即使我们的项目不适用spring data JPA(即hibernate方案),也可以在使用mybatis的同时,兼用其校验功能。我们需要创建一个校验类。当实体类校验填入的数据,不符合规范的时候,抛给异常类,以便在前端返回数据。
实体类示例:

@NotEmpty(message = "姓名不能为空")    @Size(min=2, max=20)    @Column(nullable = false, length = 20)     // 映射为字段,值不能为空    private String name;    @NotEmpty(message = "邮箱不能为空")    @Size(max=50)    @Email(message= "邮箱格式不对" )    @Column(nullable = false, length = 50, unique = true)    private String email;    @NotEmpty(message = "账号不能为空")    @Size(min=3, max=20)    @Column(nullable = false, length = 20, unique = true)    // 用户账号,用户登录时的唯一标识    private String username;     @NotEmpty(message = "密码不能为空")    @Size(max=100)    @Column(length = 100)    // 登录时密码**    private String password;

抛出异常的类:

public class ConstraintViolationExceptionHandler {
/** * 获取批量异常信息 */ public static String getMessage(ConstraintViolationException e) { List
msgList = new ArrayList<>(); for (ConstraintViolation
constraintViolation : e.getConstraintViolations()) { msgList.add(constraintViolation.getMessage()); } String messages = StringUtils.join(msgList.toArray(), ";"); return messages; }}

除了该方法,当然也可以使用自定义异常类+@RestControllerAdvice注解&@ExceptionHandler注解来实现向前端抛出校验异常的信息,非常灵活。

异常的类:

/** * 自定义异常 */public class RRException extends RuntimeException {
private String msg; private int code = 500; public RRException(String msg) { super(msg); this.msg = msg; } ...}@RestControllerAdvicepublic class RRExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass()); /** * 处理自定义异常 */ @ExceptionHandler(RRException.class) public String handleRRException(RRException e){ return FastJsonUtil.error(e.getMsg()); } @ExceptionHandler(Exception.class) public String handleException(Exception e){ logger.error(e.getMessage(), e); return FastJsonUtil.error(e.getMessage()); } ...}

最后,需要熟悉JpaRepository查询方法名的规范,相比mybatis,开发效率确实提升不少(虽然mybatis也可自动生成代码)。

引自高性能mysql

很多高性能应用都会对关联查询进行分解——对每一张表进行单表查询,再将结果在应用程序关联。

优势有:

  • ①让缓存效率更高(eg.应用已缓存id为1、2、3,那下次在进行in查询,可少几个id,可复用缓存结果);
  • ②查询分解,可减少锁竞争;
  • ③应用层做关联,更容易对数据库进行拆分,更容易做到高性能、可扩展;
  • ④缓存的id将按照顺序进行查询,可能比随机关联更高效;
  • ⑤可减少冗余查询,在数据库中关联查询可能需重复访问一部分数据;
  • ⑥相当于应用中实现了哈希关联,而不是mysql的嵌套循环关联(某些场景哈希关联效率更高)。

参考:

《Spring Boot实战》

作者: @nanphonfy

转载出处 :

你可能感兴趣的文章
Spring框架中在并发访问时的线程安全性
查看>>
网站部署
查看>>
什么情况下会发生栈内存溢出。
查看>>
何为去中心化
查看>>
本地缓存的优缺点
查看>>
缓存一致性:写策略
查看>>
Cache一致性:MESI
查看>>
缓存一致性:写未命中
查看>>
为什么用中间位作为组索引
查看>>
缓存:局部性
查看>>
mysql原理:b+树索引
查看>>
mysql原理:最左原则
查看>>
mysql原理:join标到底是什么,为什么有军规不建议超过三个
查看>>
redis缓存穿透
查看>>
redis缓存雪崩
查看>>
mysql的事务隔离
查看>>
mvc架构
查看>>
ElasticSearch(0) ES的认识
查看>>
JPA入门
查看>>
JPA关系
查看>>