一、Lombok
我们编写pojo时,经常需要编写构造函数和getter、setter方法,属性多的时候,就非常浪费时间,使用lombok插件可以解决这个问题:
在IDEA中安装lombok插件;不安装插件在IDEA中使用lombok的注解虽然编译能通过,但是源码会报错。所以为了让IDEA更好的辨别lombok注解则才安装插件。
需在pom.xml文件中引入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
然后可以在Bean上使用:
@Data :自动提供getter和setter、hashCode、equals、toString等方法
@Getter:自动提供getter方法
@Setter:自动提供setter方法
@Slf4j:自动在bean中提供log变量,其实用的是slf4j的日志功能
//在编译时自动生成get,set,hashcode,equals,toString等方法
@Data
public class User {
private Long id;
private String name;
private Integer age;
}
二、整合SpringMVC
虽然默认配置已经可以使用SpringMVC了,不过我们有时候需要进行自定义配置。
1、修改日志级别
可以在 application.yml 文件中配置日志级别控制:
#日志记录级别
logging:
level:
cn.rewind: debug
org.springframework: info
2、修改端口
#修改tomcat的端口
server:
port: 80
3、访问静态资源
现在,我们的项目是一个jar工程,那么就没有webapp,我们的静态资源该放哪里呢?
有一个叫做ResourceProperties的类,里面就定义了静态资源的默认查找路径:
默认的静态资源路径为:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public
只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。
习惯会把静态资源放在 classpath:/static/ 目录下。
可通过路径直接访问静态资源:js文件、图片等。
注意:如果访问图片时候没有显示;可以先将项目先clean再启动,或者创建 public、resources 文件夹,然后图片放置到public或resources中。
4、添加拦截器
拦截器不是一个普通属性,而是一个类,所以就要用到java配置方式了。
以下为官方文档说明翻译:
如果你想要保持Spring Boot 的一些默认MVC特征,同时又想自定义一些MVC配置(包括:拦截器,格式化器,视图控制器、消息转换器 等等),你应该让一个类实现 WebMvcConfigurer ,并且添加 @Configuration 注解,但是千万不要加 @EnableWebMvc 注解。
如果你想要自定义 HandlerMapping 、 HandlerAdapter 、ExceptionResolver 等组件,你可以创建一个 ebMvcRegistrationsAdapter 实例 来提供以上组件。
如果你想要完全自定义SpringMVC,不保留SpringBoot提供的一切特征,你可以自己定义类并且添加@Configuration 注解和 @EnableWebMvc 注解。
总结:通过实现 WebMvcConfigurer 并添加 @Configuration 注解来实现自定义部分SpringMvc配置。
(1)创建拦截器com\rewind\interceptor\MyInterceptor.java
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
//在目标方法执行之前 执行
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
log.debug("MyInterceptor的preHandle方法");
return true;
}
//在目标方法执行之后 视图对象返回之前执行
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
log.debug("MyInterceptor的postHandle方法");
}
//在流程都执行完毕后 执行
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
log.debug("MyInterceptor的afterCompletion方法");
}
}
(2)定义配置类com\rewind\config\MvcConfig.java,用于注册拦截器
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* 将拦截器注册到spring ioc容器
* @return myInterceptor
*/
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
/**
* 重写该方法;往拦截器链添加自定义拦截器
* @param registry 拦截器链
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//通过registry添加myInterceptor拦截器,并设置拦截器路径为 /*
registry.addInterceptor(myInterceptor()).addPathPatterns("/*");
}
}
三、整合jdbc和事务
1、事务
spring中的jdbc连接和事务是配置中的重要一环,在SpringBoot中该如何处理呢?
答案是不需要处理,我们只要找到SpringBoot提供的启动器即可,在 pom.xml 文件中添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
当然,不要忘了数据库驱动,SpringBoot并不知道我们用的什么数据库,这里我们选择MySQL;同样的在 pom.xml文件中添加如下依赖:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
至于事务,SpringBoot中通过注解来控制。就是我们熟知的 @Transactional 使用的时候设置在对应的类或方法上即可。
值得注意的是:如果需要使用 synchronized
进行并发控制的话,synchronized
作用范围一定要比 @Transactional
大,否则仍会出现超卖问题。synchronized
代码块可以加在 Controller
层
@Service
public class UserService {
public User queryById(Long id){
//根据id查询
return new User();
}
@Transactional
public void saveUser(User user){
System.out.println("新增用户...");
}
}
2、连接池
才引入jdbc启动器的时候,SpringBoot已经自动帮我们引入了一个连接池:
HikariCP应该是目前速度最快的连接池了
因此,我们只需要指定连接池参数即可;打开 application.yml 添加修改配置如下:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
url后面的参数?useSSL=false&serverTimezone=GMT%2B8
(1)useSSL=false:
MySQL在高版本需要指明是否进行SSL连接。
使用该参数可禁用SSL
SSL协议提供服务主要:
1)认证用户服务器,确保数据发送到正确的服务器; .
2)加密数据,防止数据传输途中被窃取使用;
3)维护数据完整性,验证数据在传输过程中是否丢失;
当前支持SSL协议两层:
SSL记录协议(SSL Record Protocol):建立靠传输协议(TCP)高层协议提供数据封装、压缩、加密等基本功能支持
SSL握手协议(SSL Handshake Protocol):建立SSL记录协议用于实际数据传输始前通讯双进行身份认证、协商加密
算法、 交换加密密钥等。
(2)serverTimezone=GMT%2B8 指定时区
这个时区要设置好,不然会出现时差,如果你设置serverTimezone=UTC,连接不报错,但是我们在用java代码插入到数据库时间的时候却出现了问题。
比如在java代码里面插入的时间为:2018-06-24 17:29:56
但是在数据库里面显示的时间却为:2018-06-24 09:29:56
有了8个小时的时差UTC代表的是全球标准时间 ,但是我们使用的时间是北京时区也就是东八区,领先UTC八个小时。
//北京时间东八区
serverTimezone=GMT%2B8
//或者使用上海时间
serverTimezone=Asia/Shanghai
四、整合Mybatis
1、依赖
<!--springboot整合mybatis依赖-->
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
<!--将配置文件放在 resource 文件夹中
对于 Maven 项目,可指定 POM 文件的 resource
注意!Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)-->
<build>
<resources>
<resource>
<!-- xml放在java目录下-->
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--指定资源的位置(xml放在resources下,可以不用指定)-->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
2、配置application.yml
# mybatis配置
mybatis:
# 实体类别名包路径
type-aliases-package: com.rewind.pojo
# 映射文件路径
# mapper-locations: classpath:mappers/*.xml
configuration:
# 控制台输出执行sql
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3、配置mapper扫描
需要注意,这里没有配置mapper接口扫描包,因此我们需要给每一个Mapper接口添加 @Mapper 注解,才能被识别。
@Mapper
public interface UserMapper {
}
或者,我们也可以不加注解,而是在启动类上添加扫描包注解(推荐):
@SpringBootApplication
@MapperScan("com.rewind.mapper")
public class Application {
public static void main(String[] args) {
// 启动代码
SpringApplication.run(Application.class, args);
}
}
五、整合MyBatisPlus
1、依赖
<!-- mybatis - plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
2、配置xml路径
#配置mapper xml文件的路径
mybatis-plus:
mapper-locations: classpath:com/rewind/test01/mapper/xml/*.xml
3、启动类
@MapperScan("com.rewind.test01.mapper")
六、通用mapper方式整合Mybatis
1、引入依赖坐标
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
注意:一旦引入了通用Mapper的启动器,会覆盖Mybatis官方启动器的功能,因此需要移除对官方Mybatis启动器的依赖。
2、编写UserMapper
编写UserMapper
无需任何配置就可以使用了。如果有特殊需要,可以到通用mapper官网查看
https://github.com/abel533/Mapper/wiki/3.config
import cn.rewind.pojo.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper<User> {
}
包别导错了
3、修改启动类上的注解
把启动类上的@MapperScan注解修改为通用mapper中自带的:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
//Springboot项目启动器
@SpringBootApplication
//通用mapper
@MapperScan("cn.rewind.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
4、在User实体类上加JPA注解
//在编译时自动生成get,set,hashcode,equals,toString等方法
@Data
@Table(name = "tb_user")
public class User {
//主键
@Id
//主键回填,即新增数据时,对象中主键是没有值的,新增后在数据库中生成主键,然后回填到对象中
@KeySql(useGeneratedKeys = true)
private Long id;
//当对象属性和数据库字段名称相同,或符合驼峰命名法,或符合user_name --> userName时,此注解可不加
//否则应在注解内的name属性中指定相应的数据库字段名称
//@Column(name = "user_name")
private String userName;
``private String name;
private Integer age;
}
通用mapper不认识int类型,尽量都用包装类。
5、编写UserService
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
//根据id查询user
public User findUserById(long id){
User user = userMapper.selectByPrimaryKey(id);
return user;
}
//新增保存用户
@Transactional
public void saveUser(User user){
//选择性新增,如果属性为空,则不出现在insert语句上
userMapper.insertSelective(user);
}
}
6、编写Controller
@RestController
public class HelloController {
@Autowired
private UserService userService;
/**
* 根据id获取用户
*/
@GetMapping("/user/{id}")
public User queryById(@PathVariable Long id){
return userService.queryById(id);
}
}
7、测试
启动项目,当访问localhost/user/1时,即会把id为1的用户信息 打印到网页上
七、Junit测试
1、依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
2、编写测试类
com\rewind\service\UserServiceTest
在测试类上面必须要添加 @SpringBootTest 注解
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void queryById() {
User user = userService.queryById(1L);
System.out.println("user = " + user);
}
@Test
public void saveUser() {
User user = new User();
user.setUserName("test");
}
}
八、整合Redis
1、依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置application.yml
spring:
redis:
host: localhost
port: 6379
3、测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
//string 字符串
//redisTemplate.opsForValue().set("str", "rewind");
redisTemplate.boundValueOps("str").set("rewind");
System.out.println("str = " + redisTemplate.opsForValue().get("str"));
//hash 散列
redisTemplate.boundHashOps("h_key").put("name", "rewind");
redisTemplate.boundHashOps("h_key").put("age", 13);
//获取所有域
Set set = redisTemplate.boundHashOps("h_key").keys();
System.out.println(" hash散列的所有域:" + set);
//获取所有值
List list = redisTemplate.boundHashOps("h_key").values();
System.out.println(" hash散列的所有域的值:" + list);
//list 列表
redisTemplate.boundListOps("l_key").leftPush("c");
redisTemplate.boundListOps("l_key").leftPush("b");
redisTemplate.boundListOps("l_key").leftPush("a");
//获取全部元素
list = redisTemplate.boundListOps("l_key").range(0, -1);
System.out.println(" list列表中的所有元素:" + list);
// set 集合
redisTemplate.boundSetOps("s_key").add("a", "b", "c");
set = redisTemplate.boundSetOps("s_key").members();
System.out.println(" set集合中的所有元素:" + set);
// sorted set 有序集合
redisTemplate.boundZSetOps("z_key").add("a", 30);
redisTemplate.boundZSetOps("z_key").add("b", 20);
redisTemplate.boundZSetOps("z_key").add("c", 10);
set = redisTemplate.boundZSetOps("z_key").range(0, -1);
System.out.println(" zset有序集合中的所有元素:" + set);
}
}
结果
九、热部署
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
项目或者页面修改以后:Ctrl+F9
十、项目部署
1、项目打包
(1) 添加项目的pom.xml插件;
在pom.xml要显式的加入插件spring-boot-maven-plugin,否则无法产生 jar 清单文件,导致打出来的 jar 无法使用命令运行;
注意:是插件,不是依赖
<build>
<plugins>
<!-- 打jar包时如果不配置该插件,打出来的jar包没有清单文件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
(2)使用maven的命令package打包;
打包路径
(3)运行
运行打出来的包;使用命令: java –jar 包全名 或者写一个 bat 文件,里面包含 java –jar 包全名;这样就可以双击启动应用。
如执行上述打出来的jar的命令为:
java -jar myspringboot-1.0-SNAPSHOT.jar
测试则可使用浏览器访问:http://localhost/user/8