spring boot之旅

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=8997
server.contextPath=/boot-server
# 数据库访问配置
spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.primary.driverClassName=com.mysql.jdbc.Driver
spring.datasource.primary.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
spring.datasource.primary.username=test
spring.datasource.primary.password=test

## 显示Sql
hibernate.show_sql=true
## 建表方式,must be spring.jpa.properties格式
#出现Table 'test.user' doesn't exist
spring.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<Authority> authorities;
}

避开外键生成示例:

类{
    ...
    @Transient
    private List<Authority> 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<String> 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;
    }
    ...
}

@RestControllerAdvice
public 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实战》
https://www.zhihu.com/question/21657443
http://www.cnblogs.com/lanxuezaipiao/p/3369962.html
http://blog.csdn.net/ming070423/article/details/22086169
https://www.zhihu.com/question/53729800
http://blog.csdn.net/webzhuce/article/details/53319468

作者: @nanphonfy
转载出处 : http://blog.csdn.net/nanphonfy

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值