SpringBoot入门基础

目录html

SpringBoot入门 (一) HelloWorld. 2前端

一 什么是springboot 1java

二 入门实例... 1mysql

SpringBoot入门 (二) 属性文件读取... 16web

一 自定义属性... 15正则表达式

二 自定义属性配置文件... 18redis

SpringBoot入门 (三) 日志配置... 21spring

日志格式及内容... 21sql

日志输出... 22数据库

输出文件... 22

集成log4j 23

SpringBoot入门 (四) 数据库访问之JdbcTemplate. 29

一 JDBC回顾... 28

二 JdbcTemplate使用示例... 29

三 测试,使用Junit Test 34

四 链接池配置... 36

SpringBoot入门 (五) 数据库访问之spring data jpa. 39

一 什么是Spring Data JPA.. 38

二 简单示例... 38

三 测试... 42

SpringBoot入门 (六) 数据库访问之Mybatis. 46

一 什么是Mybatis. 46

二 SpringBoot集成Mybatis. 47

三 测试... 51

SpringBoot入门 (七) Redis访问操做... 53

一 什么是Redis. 53

二 SpringBoot集成Redis. 54

三 测试... 55

SpringBoot入门 (八) Cache使用... 60

一 为何要使用缓存... 59

二 使用Cache. 60

1 @Cacheable. 61

2 @CachePut 62

3 CacheEvict 63

SpringBoot入门 (九) MQ使用... 65

一 什么是MQ.. 64

二 SpringBoot集成Active MQ.. 65

SpringBoot入门 (十) 发送邮件... 73

一 邮件发送过程... 72

二 发送邮件示例... 73

SpringBoot入门 (十一) 数据校验... 81

一 什么是数据校验... 80

二 使用示例... 82

SpringBoot入门 (十二) 定时任务... 88

一 SpringBoot 提供的定时任务... 87

二 SpringBoot集成Quartz. 90

 

返回目录

下一篇

SpringBoot入门 (一) HelloWorld

一 什么是springboot

  springboot是一个全新的框架,它设计的目的简化spring项目的初始环境的搭建和开发,主要有如下几个特色:

  一、简化初始配置 ,可与主流框架集成;

  二、内置Servlet容器,无需在打War包;

  三、使用了Starter(启动器)管理依赖并版本控制;

  四、大量的自动配置,简化开发,方便集成第三方;

  五、提供准生产环境运行时的监控,如指标,健康,外部配置等;

  六、无需XML配置,减小冗余代码 。

  未使用springboot时,若是咱们要搭建一个springweb项目环境,咱们须要配置web.xml及各类xml的配置文件来集成其余第三方的框架,而这些springboot已经帮咱们作了集成,咱们再也不须要去配置。

二 入门实例

  建立springboot项目有2中方式,1种是经过ide来建立,一种是官方网站建立(https://start.spring.io建立完成后会将工程下载到本地)而后导入ide便可,本文咱们经过idea建立项目。

  1 在idea的工具栏 file-->new project 以下图

 

会弹出选择工程类型的框,以下图

 

这个时候咱们有2种选择,一种是使用Spring Initializr建立,一种是使用Maven或者Gradle建立。这两种方式的不一样的地方是使用方法二建立的是空项目,咱们须要本身去修改添加所须要的依赖,方式一在建立的过程当中,咱们能够在ide中直接选择须要的依赖且会生成一个项目的根启动类。本文咱们使用Spring Initializr来建立项目。点击上图的Next

 

输入Group、Artifact、Package的对应的信息,再点击next

 

这是咱们能够选择咱们的项目要运行的springboot的版本和须要的依赖包(本文咱们只选择依赖web),而后点击Next

 

这是弹框会显示咱们项目的名称及项目的路径,点击Finish。初始时会下载springboot默认依赖的一些jar包,须要一会时间,咱们等待它下载完成。以后咱们能够看到项目的结构

 

pom.xml内容以下,2.0.8版本不是一个发布版本,在咱们的实际项目中,最好仍是要引用release版本的。

 

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

 

    <groupId>org.allen.demo</groupId>

    <artifactId>springboot-helloworld</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <packaging>jar</packaging>

 

    <name>springboot-helloworld</name>

    <description>Demo project for Spring Boot</description>

 

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.0.8</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

 

    <properties>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <java.version>1.8</java.version>

    </properties>

 

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

 

</project>

 

生成的启动类,一个可执行的main方法。

 

package org.wl.demo;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

 

@SpringBootApplication

public class HelloWorldApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(HelloWorldApplication.class, args);

    }

}

 

默认在类上边使用了@SpringBootApplication注解,这个注解是一个符合注解,至关于同时使用

@SpringBootConfiguration  指定类为配置类

@EnableAutoConfiguration  开启自动配置

@ComponentScan 指定扫描路径

下来建立一个能够访问的控制器,使用@RestController注解,它是一个复合注解,至关于同时使用了@Controller和@ResponseBody注解

 

package org.wl.demo.web;

 

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

 

@RestController

public class HelloController {

 

    @RequestMapping("/hello")

    public String hello(){

        return "hello world";

    }

 

}

 

执行main方法,启动项目,在控台可能够看到启动的日志信息

[           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''

[           main] org.wl.demo.HelloWorldApplication     : Started HelloWorldApplication in 3.591 seconds (JVM running for 4.784)

内嵌的tomcat服务器已经启动,启动端口是8080,更路径是'',咱们访问控制器的hello方法

 

这样一个web项目环境就搭建成功了,使用起来仍是很简单方便的。

在上边的日志信息中,默认启动端口是8080,访问根路径是‘’,若是咱们但愿修改的话也是能够的,只须要在application.properties中修改

修改端口,从默认的8080修改成8090

server.port=8090

修改根路径 修改前是‘’,修改后为‘/helloworld’

server.servlet.context-path=/helloWorld

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (二) 属性文件读取

  在上一篇中介绍了在idea中建立springboot工程及使用web工程输出“helloworld”到前端页面,本文学习在springboot工程中读取属性文件中的属性值。

一 自定义属性

  在application.properties文件中添加属性配置项

 myapp.name=helloworld 

  可使用@Value 注解来读取,在以前的helloworld工程的控制器中添加属性并读取,以下

 

@RestController

public class HelloController {

 

    @Value("${myapp.name}")

    private String name;

 

    @RequestMapping("/hello")

    public String hello(){

        System.out.println("myapp name :" + name);

        return "helloworld";

    }

 

}

 

@Value 注解会去application.properties文件中配置属性为myapp.name的属性,并将值赋值给name属性。访问hello方法,能够看到控制台上打印出来的信息

 

  自定义的属性比较少时使用@Value读取仍是比较方便的,若是咱们的属性比较多的时候,好比咱们要读取数据库链接池配置的不少的属性值,再这样读取的话,就显得不是很美观了。这种状况咱们通常定义一个对象,把属性字段做为对象的属性来接收,在属性文件中在增长一个属性

 myapp.age=2

  咱们定义一个对象MyAppProperties来接收属性值

 

@Component

@ConfigurationProperties(prefix = "myapp")

public class MyAppProperties {

 

    private String name;

    private int age;

 

    @Override

    public String toString() {

        return "MyAppProperties{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

 

    //省略getter和setter方法

}

 

@Component 表示指定当前类为实例,以即可以在spring中使用
@ConfigurationProperties(prefix = "myapp") 表示把application中的myapp开头的属性自动赋值给当前对象的属性,好比把myapp.name的值赋值给name属性,访问hello方法能够看到。

二 自定义属性配置文件

  有的时候,咱们须要把本身的属性配置信息写在本身的配置文件中,以便和系统的application.properties分开,咱们能够在resources目录下新建本身的属性文件my.properties,并添加属性
my.name=helloworld2

my.age=22            

 

定义读取属性的对象类,使用 @PropertySource("classpath:my.properties") 来指定咱们当前类要读取的属性文件

 

@Component

@PropertySource("classpath:my.properties")

@ConfigurationProperties(prefix = "my")

public class MyAppProperties2 {

 

    private String name;

    private int age;

 

    @Override

    public String toString() {

        return "MyAppProperties2{" +

                "name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

 

    // 省略getter和setter方法

}

 

  修改控制器hello方法测试

 

@RestController

public class HelloController {

 

    @Resource

    private MyAppProperties myAppProperties;

    @Resource

    private MyAppProperties2 myAppProperties2;

 

    @RequestMapping("/hello")

    public String hello(){

        System.out.println(myAppProperties.toString());

        System.out.println(myAppProperties2.toString());

        return "helloworld";

    }

 

}

 

  访问hello方法,能够看到控制台输出的打印信息

 

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (三) 日志配置

上一篇博文记录了再springboot项目中读取属性文件中配置的属性,本文学习在springboot项目中记录日志。

  日志记录在项目中是很常见的一个功能了,对排查问题有很大帮助,也能够作分类分析及统计。SpringBoot内部使用的是Commons Logging作日志的记录,可是对其余的日志框架也提供了默认的配置,如:Java util Logging,Log4j2,Logback,每一种状况下日志记录器都预先配置为使用控制台输出和可选的文件输出。

日志格式及内容

  若是咱们的SpringBoot项目使用的是Starters启动器,默认使用LogBack作日志记录。如咱们启动项目时在控制台上看到的

 

输出的信息有如下几点
日期和时间:精确到毫秒,如 2019-01-24 14:03:14.260

日志级别:日志级别有ERROR,WARN,INFO,DEBUG,TRACE,如上边的INFO

进程号:如上边的 10348

分割线:如上边的 ---

线程名:如上边用[]括起来的

日志名:通常使用的是代码的类名

日志信息:咱们在代码中要输出的内容

日志输出

  Spring Boot中默认配置了ERROR、WARN和INFO级别的日志输出到控制台,咱们也是能够修改的日志级别的,好比咱们修改成debug级别,有两种方式

1 使用命令 $ java -jar myapp.jar --debug 

2 在application.properties中添加配置debug=true 开启debug,此配置只会对核心Logger(如内嵌的tomcat容器、hibernate、spring)有效,可是咱们本身应用的日志并不会输出为DEBUG级别,须要本身配置,如 logger.level.root=debug

日志级别

  能够经过logger.level.*=LEVEL来改变对应日志级别,如

1

2

3

4

5

6

7

8

logging.level.root=warn

logging.level.org.springframework.web=info

logging.level.org.hibernate=error

 

######修改mubatis日志级别

logging.level.org.mybatis=info

#mapper接口为debug级别

logging.level.mybatis mapper接口所在包=debug

输出文件

  SpringBoot默认只在控制台输出日志信息,若是想把日志信息写入文件中记录,须要在application.properties中配置,如

1

2

3

4

5

6

7

8

##文件存放路径

logging.path=/usr/local/log

##写入的文件

logging.file=myapp.log

##日志文件大小,超过大小时会在新的文件中记录

logging.file.max-size=10Mb

##日志保存时间 天

logging.file.max-history=15

集成log4j

  SpringBoot在高版本中已经不支持log4j了,支持的是log4j2。在pom.xml中引入须要的log4j2的jar包

 

<dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

            <exclusions>

                <exclusion>

                    <groupId>org.springframework.boot</groupId>

                    <artifactId>spring-boot-starter-logging</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-log4j2</artifactId>

        </dependency>

 

因为web依赖包中已经有了log的依赖,因此咱们选去掉web中的log依赖,避免jar包冲突。

  而后配置log4j2的属性,在官方文档中能够看到集成的日志文件的命名以下

 

  在resources目录下建立一个log4j2-spring.xml文件

 

<?xml version="1.0" encoding="utf-8"?>

<configuration>

    <properties>

        <!-- 文件输出格式 -->

        <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} |-%-5level [%thread] %c [%L] -| %msg%n</property>

    </properties>

    <appenders>

        <!--添加一个控制台追加器-->

        <Console name="Console" target="system_out">

            <PatternLayout pattern="${PATTERN}" />

        </Console>

        <!--添加一个文本追加器,文件位于E:\\logs目录下,名为HelloWorld.log-->

        <File name="File" fileName="E:\\logs\\HelloWorld.log">

            <PatternLayout>

                <pattern>${PATTERN}</pattern>

            </PatternLayout>

            <Policies>

                <SizeBasedTriggeringPolicy size="10 MB" />

            </Policies>

        </File>

    </appenders>

    <loggers>

        <root level="info">

            <appenderref ref="File" />
       <!--为了直观,在控制天中也输出info级别的日志-->

            <appenderref ref="Console" />

        </root>

        <!--把org.springframework包下的全部日志输出到log文件,additivity="false"表示不输出到控制台-->

        <Logger name="org.springframework" level="debug" additivity="true">

            <appenderRef ref="File" />

        </Logger>

    </loggers>

</configuration>

 

  正式项目中,咱们须要对上述xml文件中的配置信息作些修改。写一个控制器访问,看看输出的信息

 

@RestController

public class HelloController {

 

    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

   

    @RequestMapping("/hello")

    public String hello(){

        logger.info("使用log4j输出日志!");

        return "helloworld";

    }

 

}

 

控制台和生成的log文件中输出的信息一致

 

 

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (四) 数据库访问之JdbcTemplate

JDBC回顾

  最先是在上学时接触的使用JDBC访问数据库,主要有如下几个步骤:

1 加载驱动 Class.forName(Driver)

2 获取数据库链接 conn = DriverManager.getConnection(url, user,password)

3 建立一个statement对象来访问操做数据库 statement = conn.createStatement();

4 执行SQL,访问操做数据库 rs = statement.execute(sql)

5 获得结果集,业务处理

6 关闭链接,释放资源 statement.close(); conn.close();

使用jdbc访问并操做数据库时比较麻烦,后来也作了必定的封装,主要是对statement的建立前和sql执行后进行的封装。

二 JdbcTemplate使用示例

  目前咱们使用的主流的开源的数据库访问框架主要有Hibernate,Mybatis,SpringJdbc。SpringJdbc时spring对JDBC封装后的一个ORM框架,JdbcTemplate就是SpringJdbc对外提供的一个访问数据库的接口类,咱们经过它能够很容易的实现数据库的访问操做。可是须要咱们本身根据业务手写相关的SQl,而后执行。

在spring boot项目中引入依赖,本文练习中使用的时MySql数据库

1

2

3

4

5

6

7

8

9

<dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

         

  <dependency>

     <groupId>mysql</groupId>

     <artifactId>mysql-connector-java</artifactId>

  </dependency>

 

 

在application.properties中配置数据库链接相关信息

1

2

3

4

5

6

7

8

9

#数据库配置

#链接

spring.datasource.url=jdbc:mysql://localhost:3306/test

#帐号

spring.datasource.username=root

#密码

spring.datasource.password=123456

#驱动

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

完成以上配后,在启动springboot项目时,会自动把数据源信息注入到JdbcTemplate中,咱们只须要在使用的地方注入JdbcTemplate就能够了

定义要操做数据库的相关方法接口

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

public interface UserDao {

 

    /**

     * 添加用户

     */

    int insert(UserInfo user);

 

    /**

     * 根据ID删除用户

     */

    int delete(Long id);

 

    /**

     * 修改用户

     */

    int update(UserInfo user);

 

    /**

     * 根据ID查询用户

     */

    UserInfo queryById(Long id);

 

    /**

     * 查询全部用户

     * @return

     */

    List<UserInfo> queryAll();

 

    /**

     * 分页查询用户

     * @param start 开始位置

     * @param size 要查询的数据条数

     * @return

     */

    List<UserInfo> pagedQuery(int start, int size);

 

}

1

<span style="font-size: 18px">接口的实现</span>

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

@Service

public class UserDaoImpl implements UserDao {

 

    @Autowired

    private JdbcTemplate jdbcTemplate;

 

    @Override

    public int insert(UserInfo user) {

      String insertSql = "insert into t_user(name, age) values(?, ?)";

      return jdbcTemplate.update(insertSql, user.getName(), user.getAge());

    }

 

    @Override

    public int delete(Long id) {

        String deleteSql = "delete from t_user where id = ?";

        return jdbcTemplate.update(deleteSql, id);

    }

 

    @Override

    public int update(UserInfo user) {

        String updateSql = "update t_user set name = ?, age = ? where id = ?";

        return jdbcTemplate.update(updateSql, user.getName(), user.getAge(), user.getId());

    }

 

    @Override

    public UserInfo queryById(Long id) {

        String sql = "select * from t_user where id = ?";

        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<UserInfo>(UserInfo.class));

    }

 

    @Override

    public List<UserInfo> queryAll() {

        String sql = "select * from t_user";

        return jdbcTemplate.query(sql, new BeanPropertyRowMapper(UserInfo.class));

    }

 

    @Override

    public List<UserInfo> pagedQuery(int start, int size) {

        String sql = "select * from t_user limit ?, ?";

        return jdbcTemplate.query(sql, new Object[]{start, size}, new BeanPropertyRowMapper(UserInfo.class));

    }

}

 

 

能够看到,使用JdbcTemplate时咱们彻底省去了使用JDBC时的建立链接,释放资源等操做。不一样数据库的分页查询不同,MySql中用的limit关键字,第一个参数表明获取数据的起点,第二个是要查询的数量,如:limit 5,5  咱们查询出来的是第6行到10行 共5条数据

测试,使用Junit Test

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringbootJdbctemplateApplicationTests {

 

    @Autowired

    private UserDaoImpl userDaoImpl;

 

    @Test

    public void testInsert(){

        UserInfo user = new UserInfo("kg", 21);

        userDaoImpl.insert(user);

    }

 

    @Test

    public void testDelete(){

        long id = 2;

        userDaoImpl.delete(id);

    }

 

    @Test

    public void testUpdate(){

        long id = 1;

        UserInfo user = new UserInfo();

        user.setId(id);

        user.setName("kobe");

        user.setAge(3);

        userDaoImpl.update(user);

    }

 

    @Test

    public void testQueryById(){

        long id = 1;

        UserInfo user = userDaoImpl.queryById(id);

    }

 

    @Test

    public void testQueryAll(){

        List<UserInfo> list = userDaoImpl.queryAll();

    }

 

    @Test

    public void testPagedQuery(){

        List<UserInfo> list = userDaoImpl.pagedQuery(1, 2);

    }

}

在启动项目时,能够看到在控制台上输出的日志信息中有如下内容

 

链接池配置

  在咱们没有配置数据库链接池时,springboot默认给咱们提供的Hikari链接池。若是咱们像使用其余的,咱们能够本身配置,好比咱们想使用阿里的Druid链接池,咱们须要引入依赖

1

2

3

4

5

<dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>druid</artifactId>

            <version>1.1.10</version>

        </dependency>

为了测试方便,我这里直接用@Value注解来获取配置信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

@SpringBootConfiguration

public class DataSourceConfig {

 

    @Value("${spring.datasource.driver-class-name}")

    private String DRIVER;

    @Value("${spring.datasource.url}")

    private String URL;

    @Value("${spring.datasource.username}")

    private String USER;

    @Value("${spring.datasource.password}")

    private String PASSWORD;

 

    @Bean

    public JdbcTemplate jdbcTemplate(){

        JdbcTemplate jdbcTemplate = new JdbcTemplate();

        jdbcTemplate.setDataSource(dataSource());

        return jdbcTemplate;

    }

 

    @Bean

    public DataSource dataSource(){

        System.out.println("初始化数据源start。。。");

        DruidDataSource dataSource = new DruidDataSource();

        dataSource.setDriverClassName(DRIVER);

        dataSource.setUrl(URL);

        dataSource.setUsername(USER);

        dataSource.setPassword(PASSWORD);

        //链接池的其余的属性。。。

        dataSource.setMaxActive(5);

        //...

        System.out.println("初始化数据源end。。。");

        return dataSource;

    }

 

}

 @SpringBootConfiguration 这个注解说明当前类是一个配置类,须要被特殊处理,在扫描时发现有@Bean 注解,会把当前方法返回的类Bean注入的容器中,方法名会别标记为注入的Bean的别名,如上JdbcTemplate使用的DataSource就从默认的Hikari修改成Druid了,启动项目能够看到控制台日志信息

 

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (五) 数据库访问之spring data jpa

本文记录学习使用spring data jpa访问数据库

什么是Spring Data JPA

  JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象、关联映射工具来管理Java应用中的关系数据。主要是为了简化现有的持久化开发工做和整合ORM技术,对不一样的ORM框架提供统一的规范标准。

  Spring Data JPA 是Spring基于Hibernate框架和JPA(Java Persistence API)规范的基础上封装的一套JPA应用框架,它提供了增、删、改、查等一些经常使用得方法供开发者调用,能够轻松实现实现对数据的访问和操做。

简单示例

  要使用spring data jpa,咱们首先须要在pom.xml中引入所须要的依赖jar包

1

2

3

4

5

6

7

8

9

<dependency>

  <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-data-jpa</artifactId>

    </dependency>

        <dependency>

          <groupId>mysql</groupId>

          <artifactId>mysql-connector-java</artifactId>

        </dependency>

  在application.properties文件配置数据源链接信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#驱动

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/test

#用户

spring.datasource.username=root

#密码

spring.datasource.password=123456

#ddl create:不论数据库表有没有都是建立,update:当表存在时更新,不存在是建立

spring.jpa.properties.hibernate.hbm2ddl.auto=update

#方言

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

#输出SQL

spring.jpa.show-sql=true

#对SQL格式化

spring.jpa.properties.hibernate.format_sql=true

   建立一个实体对象,完成与数据库表之间的映射

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

@Entity

@Table(name="t_user")

public class UserInfo {

 

    @Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    private Long id;

    @Column(name = "name", nullable = true, length = 30)

    private String name;

    @Column(name="age", nullable = true, length = 3)

    private Integer age;

 

    public UserInfo() {

    }

 

    public UserInfo(String name, Integer age) {

        this.name = name;

        this.age = age;

    }

 

    @Override

    public String toString() {

        return "UserInfo{" +

                "id=" + id +

                ", name='" + name + '\'' +

                ", age=" + age +

                '}';

    }

 

    //省略getter和setter

}

@Entity 说明当前类为一个实体类,默认属性name能够不输入,默认就是当前类名
@Table(name="t_user") 说明当前类映射的数据库表是t_user
@Id 说明该字段是表的主键
@GeneratedValue(strategy = GenerationType.AUTO) 说明主键的生成策略是 GenerationType.*,*有AUTO、INDENTITY、SEQUENCE 和 TABLE可供选择
@Column(name = "name", nullable = true, length = 30) 说明当前字段在数据库表中对应的列属性,name:表中的列名,nullable:容许为空,length:长度不超过30

  前边已经说过了,Spring Data JPA 已经给咱们提供了具体的接口供调用,因此只须要继承他的方法来使用就能够了,建立接口并继承JpaRepository

1

2

3

public interface UserRepository extends JpaRepository<UserInfo, Long> {

}

 

  在IDEA中打开类图(如上图),能够看到咱们继承的JpaRepository 经过继承关系已经有了增删该查(CrudRepository)和分页排序(PagingAndSortingRepository),因此咱们的UserRspository也就有了对应的方法

测试 

  使用Junit作个简单的测试

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

@RunWith(SpringRunner.class)

@SpringBootTest

public class JpaApplicationTests {

 

    @Resource

    private UserRepository userRepository;

 

    /**

     * 保存用户信息

     */

    @Test

    public void save() {

        UserInfo user = new UserInfo("卢俊义", 3);

        userRepository.save(user);

    }

 

    /**

     * 根据ID删除

     */

    @Test

    public void delete() {

        long id = 3;

        userRepository.deleteById(id);

    }

 

    /**

     * 修改

     */

    @Test

    public void update() {

        UserInfo user = new UserInfo();

        user.setId(Long.valueOf(3));

        user.setName("老卢");

        user.setAge(5);

        userRepository.saveAndFlush(user);

    }

 

    /**

     * 根据ID查询

     */

    @Test

    public void selectById() {

        long id = 3;

        UserInfo user = userRepository.findById(id).get();

        System.out.println(user);

    }

 

    /**

     * 查询全部

     */

    @Test

    public void selectAll() {

        List<UserInfo> userList = userRepository.findAll();

        System.out.println(userList);

    }

 

    /**

     * 根据Id倒序查询

     */

    @Test

    public void selectAllOrder() {

        Sort sort = new Sort(Sort.Direction.DESC, "id");

        List<UserInfo> userList = userRepository.findAll(sort);

        System.out.println(userList);

    }

 

    @Test

    public void pageSelect() {

        int currentPage = 1;

        int pageSize = 2;

        //分页查询

     Pageable page = PageRequest.of(currentPage, pageSize);

     Page<UserInfo> pageObject = userRepository.findAll(page);

      //分页 ID倒序

     Sort sort = new Sort(Sort.Direction.DESC, "id");

 Pageable pageOrder = PageRequest.of(currentPage, pageSize, sort);

 Page<UserInfo> pageObject2 = userRepository.findAll(pageOrder);

    }

}

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (六) 数据库访问之Mybatis

本文记录学习在SpringBoot中使用Mybatis。

什么是Mybatis

  MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎全部的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录(官方定义);

官方使用示例代码以下:

1

2

3

4

5

6

7

8

9

10

String resource = "org/mybatis/example/mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession session = sqlSessionFactory.openSession();

try {

  BlogMapper mapper = session.getMapper(BlogMapper.class);

  Blog blog = mapper.selectBlog(101);

} finally {

  session.close();

}

经过示例程序能够看到它的执行过程主要有如下几个步骤:

  1 应用程序启动时,根据配置文件生成一个SqlSessionFactory;

  2 经过SqlSessionFactory的到一个SqlSession;

  3 SqlSession内部经过Excutor执行对应的SQl;

  4 返回处理结果;

  5 释放资源;

SpringBoot集成Mybatis

  Mybatis使用有2中方式,一种是使用注解,即在接口定义的方法上经过注解写入要执行的SQL和要完成的数据映射;一种是使用xml配置文件即在xml文件中写相关SQL和完成表与实体的映射。本文咱们使用xml文件。

  首先须要引入SpringBoot集成Mybatis的依赖jar包,这里咱们只引入了Spring与Mybatis集成的包,springboot默认会自动帮咱们引入其余依赖的jar包。

1

2

3

4

5

<dependency>

            <groupId>org.mybatis.spring.boot</groupId>

            <artifactId>mybatis-spring-boot-starter</artifactId>

            <version>1.3.2</version>

        </dependency>

在application.properties文件中配置数据库链接信息和指定mybatis的接口对应的xml

1

2

3

4

5

6

7

#datasoure

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/test

spring.datasource.username=root

spring.datasource.password=123456

#mybatis

mybatis.mapper-locations=classpath:mybatis/*.xml

如上,咱们的mapper xml文件放在reources目录下的mybatis文件夹下

写一个接口,定义咱们要完成的功能

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@Mapper

public interface UserMapper {

 

    /**

     * 根据ID删除

     */

    int deleteByPrimaryKey(Long id);

 

    /**

     * 新增

     */

    int insert(UserInfo record);

 

    /**

     * 根据ID查询

     */

    UserInfo selectByPrimaryKey(Long id);

 

    /**

     * 修改

     */

    int updateByPrimaryKey(UserInfo record);

 

    /**

     * 查询全部

     */

    List<UserInfo> selectAll();

}

@Mapper 该注解说名当前类是一个Mybatis的Mapper接口类,交给spring管理,令一种方式是使用注解 @MapperScan(basePackages="...") 说明basePackages及其子包下的接口都交给spring管理,咱们多数状况下都会使用@MapperScan这个注解,这样咱们就不用在每个Mapper接口上写注解了。
在xml文件中完成SQl,实现具体的方法,以下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="org.allen.demo.dao.UserMapper" >

  <resultMap id="BaseResultMap" type="org.allen.demo.domain.UserInfo" >

    <id column="id" property="id" jdbcType="BIGINT" />

    <result column="age" property="age" jdbcType="INTEGER" />

    <result column="name" property="name" jdbcType="VARCHAR" />

  </resultMap>

  <sql id="Base_Column_List" >

    id, age, name

  </sql>

  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >

    select

    <include refid="Base_Column_List" />

    from t_user

    where id = #{id,jdbcType=BIGINT}

  </select>

  <select id="selectAll" resultMap="BaseResultMap">

    select

    <include refid="Base_Column_List" />

    from t_user

  </select>

  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >

    delete from t_user

    where id = #{id,jdbcType=BIGINT}

  </delete>

  <insert id="insert" parameterType="org.allen.demo.domain.UserInfo" useGeneratedKeys="true" keyProperty="id">

    insert into t_user (id, age, name)

    values (#{id,jdbcType=BIGINT}, #{age,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})

  </insert>

  <update id="updateByPrimaryKey" parameterType="org.allen.demo.domain.UserInfo" >

    update t_user

    set age = #{age,jdbcType=INTEGER},

      name = #{name,jdbcType=VARCHAR}

    where id = #{id,jdbcType=BIGINT}

  </update>

</mapper>

 从这个xml文件,咱们能够看到如下几点:

1 namespace="org.allen.demo.dao.UserMapper" 经过namespace来指定将当前xml文件的SQL实现的对应的接口Mapper

2 经过 resultMap 完成实体类与数据库表字段的映射

3 xml中的SQL语句都必须写在<select> <insert> <update><delete>内部

4 每个标识的id都必须与接口中的方法名保持一直

5 insert 中使用的 useGeneratedKeys 设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。若是设置了true,咱们就能够在insert完成后直接经过当前操做的实体类获取数据库主键。

测试

  使用Junit作测试

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

@RunWith(SpringRunner.class)

@SpringBootTest

public class MybatisApplicationTests {

 

    @Resource

    private UserMapper userMapper;

 

    @Test

    public void save() {

        UserInfo user = new UserInfo();

        user.setName("world");

        user.setAge(2);

        userMapper.insert(user);

        System.out.println("保存后的ID:" + user.getId());

    }

 

    @Test

    public void delete() {

        long id = 5;

        userMapper.deleteByPrimaryKey(id);

    }

 

    @Test

    public void update() {

        UserInfo user = new UserInfo();

        user.setName("world");

        user.setAge(5);

        long id = 3;

        user.setId(id);

        userMapper.updateByPrimaryKey(user);

    }

 

    @Test

    public void selectById() {

        long id = 3;

        userMapper.selectByPrimaryKey(id);

    }

 

    @Test

    public void selectAll() {

        List<UserInfo> userList = userMapper.selectAll();

    }

     

}

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (七) Redis访问操做

本文记录学习在SpringBoot中使用Redis。

什么是Redis

  Redis 是一个速度很是快的非关系数据库(Non-Relational Database),它能够存储键(Key)与 多种不一样类型的值(Value)之间的映射(Mapping),能够将存储在内存的键值对数据持久化到硬盘,可使用复制特性来扩展读性能,还可使用客户端分片来扩展写性能。Redis主要有如下几个优势:

  1 性能极高,它每秒可执行约 100,000 个 Set 以及约 100,000 个 Get 操做;

  2 丰富的数据类型,Redis 对大多数开发人员已知的大多数数据类型提供了原生支持,这使得各类问题得以轻松解决;

  3 原子性,由于全部 Redis 操做都是原子性的,因此多个客户端会并发地访问一个 Redis 服务器,获取相同的更新值;

  4 丰富的特性,Redis 是一个多效用工具,有很是多的应用场景,包括缓存、消息队列(Redis 原生支持发布/订阅)、短时间应用程序数据(好比 Web 会话、Web 页面命中计数)等。

  目前咱们经常使用的Value的数据类型有String(字符串),Hash(哈希),List(列表),Set(集合),Zset(有序集合)。

SpringBoot集成Redis

  SpringBoot提供了对Redis的集成的模块,包是spring-boot-starter-data-redis,它依赖于 spring-data-redis 和 lettuce,lettuce是一个线程安全的redis客户端。

  在pom.xml中引入依赖

1

2

3

4

<dependency>

   <groupId>org.springframework.boot</groupId>

     <artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>  

  在application.properties中配置Redis的链接信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

# redis 配置

## redis数据库索引(默认0)

spring.redis.database=0

## redis 服务器地址

spring.redis.host=localhost

## redis 服务器端口

spring.redis.port=6379

## redis数据库密码(默认为空)

spring.redis.password=

## redis链接池最大链接数(使用负数表示没有显示,默认8)

spring.redis.lettuce.pool.max-active=8

## 链接池最大阻塞等待时间(使用负值表示没有限制,默认-1)

spring.redis.lettuce.pool.max-wait=-1

## 链接池中的最大空闲链接 默认 8

spring.redis.lettuce.pool.max-idle=8

## 链接池中的最小空闲链接 默认 0

spring.redis.lettuce.pool.min-idle=0

  有了上边这两个步骤以后,咱们启动服务后,SpringBoot就会帮咱们链接到Redis服务器,并给咱们提供了一个RedisTemplate类供咱们使用操做Redis。咱们在须要用的地方注入RedisTemplate就能够轻松完成操做。

测试

  使用Junit作测试,在咱们的单元测试类中注入RedisTemplate

1

2

3

4

5

6

7

8

@RunWith(SpringRunner.class)

@SpringBootTest

public class RedisApplicationTests {

 

    @Autowired

    private RedisTemplate redisTemplate;

 

}

  String字符串操做,value是一个字符串,经过delete(key)删除

1

2

3

4

5

6

7

8

9

@Test

    public void testString() throws InterruptedException {

        //字符串

    ValueOperations strOps = redisTemplate.opsForValue();

    strOps.set("name", "梓&艺");

    System.out.println("字符串结果name:"+strOps.get("name"));

    //删除key

    redisTemplate.delete("name");

}

  对象操做,value是一个对象

1

2

3

4

5

6

7

8

@Test

  public void testObject() throws InterruptedException {

     ValueOperations objOps = redisTemplate.opsForValue();

     City city = new City(1, "X`A", "西安");

     objOps.set("city", city);

     System.out.println(objOps.get("city").toString());

        redisTemplate.delete("city");

}

  设置key的过时时间,在set时加上过时时间,经过hasKey(key)来判断key是否还存在

1

2

3

4

5

6

7

8

9

10

@Test

public void testExpire(){

  //过时

   ValueOperations objOps1 = redisTemplate.opsForValue();

    City city1 = new City(1, "BJ", "北京");

    objOps1.set("expire", city1, 2000, TimeUnit.MILLISECONDS);

 System.out.println(objOps1.get("expire").toString());

   Thread.sleep(2000);

     System.out.println(redisTemplate.hasKey("expire")); 

}

  hash哈希操做

1

2

3

4

5

6

@Test

  public void testHash() {

     HashOperations hashOps = redisTemplate.opsForHash();

     hashOps.put("hash","hashKey","hashValue");

     System.out.println(hashOps.get("hash", "hashKey"));

   }

  在上边的代码中能够看出,Hash Set的时候就是在哈希表 Key 中的域(Field)的值设为 value。若是 Key 不存在,一个新的哈希表被建立并进行 Hash set 操做;若是域(Field)已经存在于哈希表中,旧值将被覆盖。

  List列表操做

1

2

3

4

5

6

7

8

@Test

public void testList() {

ListOperations<String, String> listOps = redisTemplate.opsForList();

listOps.leftPush("list","梓");

listOps.leftPush("list","&");

listOps.leftPush("list","艺");

System.out.println(listOps.leftPop("list"));

    }

  列表操做时咱们经过 leftPush 或者 rightPush 来将数据存入列表中,经过 leftPop 或者rightPop将数据取出来,咱们能够利用它来实现一个队列。

  Set集合操做

1

2

3

4

5

6

7

8

9

@Test

public void testSet() {

 SetOperations<String, String> setOps = redisTemplate.opsForSet();

 setOps.add("set","梓");

 setOps.add("set","&");

 setOps.add("set","&");

 setOps.add("set","艺");

 System.out.println(setOps.members("set"));

    }

  Set是一个没有顺序的集合,key相同时,若是value已经存在了,后边进入的会把前边的覆盖掉

  ZSet有序集合操做

1

2

3

4

5

6

7

8

9

10

@Test

  public void testZSet() {

   ZSetOperations zSetOps = redisTemplate.opsForZSet();

   zSetOps.add("zSet", "梓", 1);

   zSetOps.add("zSet", "&", 2);

   zSetOps.add("zSet", "艺", 3);

   zSetOps.add("zSet", "zi", 1);

   zSetOps.add("zSet", "yi", 3);

   System.out.println(zSetOps.rangeByScore("zSet", 1, 3));

    }

  add 方法的3个参数分别是key,value,数据插入位置。ZSet中存储的数据都是有顺序的,输出时顺序按照存储时设置的从小到大,若是遇到key相同,Value和顺序同样的,后边的会把前边的覆盖掉,range方法后边的2个参数时插入的位置。如上的输出

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (八) Cache使用

本文记录学习在SpringBoot中使用Cache。

为何要使用缓存

  缓存是一个数据交换的缓冲区,在一些条件下能够替代数据库。举个例子:咱们有一个查询的业务,访问数据的频率特别高,且每次访问时的查询条件都同样,数据库的数据一直保存不变,这样咱们每次查询出来的结果都是同样的。为了下降高频率访问数据库给数据库带来的压力,咱们能够在第一次访问后把数据缓存起来,之后再作相同查询时只去缓存中取数据,而不用取数据库再作查询。

使用Cache

  SpringBoot对缓存作了支持以供咱们方便快速的使用,咱们只须要引入相关依赖就能够了。在项目启动时会自动根据配置进行识别和初始化操做。

  在pom.xml文件中引入对Cache支持的依赖

1

2

3

4

<dependency>

 <groupId>org.springframework.boot</groupId>

 <artifactId>spring-boot-starter-cache</artifactId>

</dependency>

要使用Cache,咱们必须在启动时开启Cache,

@EnableCaching 说明开启缓存

1

2

3

4

5

6

7

8

9

@SpringBootApplication

@EnableCaching

public class CacheApplication {

  public static void main(String[] args) {

     SpringApplication.run(CacheApplication.class, args);

    }

}

  Spring Cache有3个比较重要的注解@Cacheable,@CachePut,@CacheEvict,咱们一个一个说明:

1 @Cacheable

  这个注解代表对操做进行缓存,它能够放在类上,代表对当前类中全部的方法的结果进行缓存;也能够放在方法上,代表对当前方法的结果进行缓存。它有3个参数:

  Value 缓存的名称

  Key 缓存的键,能够为空,若是指定要按照 SpEL 表达式编写;若是不指定,则缺省按照方法的全部参数进行组合

  Condition 缓存触发的条件,返回值是true和false,只有知足条件的状况(true)才会加入缓存,默认为空,既表示所有都加入缓存,支持 SpEL表达式。

  实现代码

@RestController

public class CacheController {

@RequestMapping("/hello")

@Cacheable(value="helloCache", key = "#name", condition = "#name.length()>2")

public String hello(@RequestParam(value="name", required = true) String name){

     System.out.println("没有走缓存,去数据库查询数据");

     return "hello,"+name;

    }

}

  咱们的方法中有一个参数,模拟数据库查询时的条件,如上,当咱们的参数name的长度大于2时,参数加入的缓存中。若是咱们请求http://localhost:8080/hello?name=ch,无论咱们请求多少次控制台中都会打印出‘没有走缓存,去数据库查询数据’,说明缓存没有触发,若是咱们请求http://localhost:8080/hello?name=cache,第一次请求时控制台会打印出‘没有走缓存,去数据库查询数据’,以后不会再有,说明在方法执行前会先去缓存中看是否有结果,有则返回结果,没则执行请求方法,如第一次请求时执行后已经对结果进行了缓存,咱们再请求时会直接去缓存中取结果,不会再去执行方法请求数据库了。

2 @CachePut

  它与@Cacheable相似,都是说明要作缓存,并且属性Key,Value,Condition的用法都同样,也可使用在类或者方法上,区别是它每次都会执行实际方法(如查询数据库)

  代码实现

1

2

3

4

5

6

@RequestMapping("/hello1")

    @CachePut(value="helloCache", key = "#name", condition = "#name.length()>2")

    public String hello1(@RequestParam(value="name", required = true) String name){

        System.out.println("没有走缓存,去数据库查询数据");

        return "hello,"+name;

    }

  当咱们请求http://localhost:8080/hello1?name=cache时,无论咱们请求第几回,都会在控制台输出‘没有走缓存,去数据库查询数据’。若是数据库数据发生了变化,则会用新的数据替换以前的同value同Key缓存的数据。

3 CacheEvict

  它是用来清除缓存的,一样是能够标记在类和方法上,标记在类上时说明全部方法都会清除缓存。Key,Value,Condition属性用法与Cacheable同样,还有2个属性allEntries和beforeInvocation。

  allEntries表示是否删除缓存中的全部属性,默认是false,表示不,true表示是。当被指定为true时,会忽略掉指定的Key而删除全部。

  beforeInvocation表示删除缓存的时机,默认是false,表示在方法执行完后才删除缓存,true表示在方法执行前就先删除缓存。在方法执行过程当中若是发生了异常,默认设置下(false)将不能删除掉缓存。

  代码实现

@RequestMapping("/hello2")

@CacheEvict(value="helloCache", key="#name", condition="#name.length()>2", allEntries = true, beforeInvocation = true)

public String hello2(@RequestParam(value="name", required = true) String name){

 System.out.println("CacheEvict 清除缓存");

 return "hello,"+name;

    }

  使用一样的参数如cache,先请求执行hello方法进行数据缓存,在执行hello2进行删除缓存操做,而后再执行hello1方法会发如今控制台上又输出了‘没有走缓存,去数据库查询数据’,说明执行hello2方法时已经将缓存删除掉了。

注:SpELSpring Expression Language)是一个支持运行时查询和操做对象图的强大的表达式语言,其语法相似于统一 EL,但提供了额外特性,显式方法调用和基本字符串模板函数。

 

返回目录

上一篇

下一篇

SpringBoot入门 (九) MQ使用

本文记录学习在Spring Boot中使用MQ。

什么是MQ

  MQ全称(Message Queue)又名消息队列,是一种异步通信的中间件。它的做用相似于邮局,发信人(生产者)只须要将信(消息)交给邮局,而后由邮局再将信(消息)发送给具体的接收者(消费者),具体发送过程与时间发信人能够不关注,也不会影响发信人作其它事情。目前常见的MQ有activemq、kafka、rabbitmq、zeromq、rocketmq等。

  使用MQ的优势主要有:

  1 方法的异步执行 使用MQ能够将耗时的同步操做经过以发送消息的方式进行了异步化处理,减小了因为同步而等待的时间;

  2 程序之间松耦合 使用MQ能够减小了服务之间的耦合性,不一样的服务能够经过消息队列进行通讯,只要约定好消息的内容格式就行;

  JMS(Java Message Service)即java消息服务,是一个Java平台中关于面向消息中间件(MOM)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通讯。JMS的消息机制有2种模型,一种是1对1(Point to Point)的队列的消息,这种消息,只能被一个消费者消费;另外一种是一对多的发布/订阅(Topic)消息,一条消息能够被多个消费者消费。ActiveMq是对JMS的一个实现。

二 SpringBoot集成Active MQ

  官网下载一个服务程序,解压后直接启动服务就能够了,下载地址:http://activemq.apache.org/activemq-5158-release.html

  SpringBoot也对Active MQ提供了支持,咱们使用时引入具体的依赖便可,修改pom.xml文件,添加依赖

1

2

3

4

<dependency>

 <groupId>org.springframework.boot</groupId>

 <artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

  在application.properties文件中配置Active MQ服务器的链接信息

1

2

3

4

5

spring.activemq.broker-url=tcp://localhost:61616

spring.activemq.user=admin

spring.activemq.password=admin

#消息模式 true:广播(Topic),false:队列(Queue),默认时false

#spring.jms.pub-sub-domain=true

完成以上配置信息后,当咱们在启动SpringBoot项目时,会自动帮咱们完成初始化操做,并提供一个JmsMessagingTemplate,提提供了咱们经常使用发送消息的各类方法供咱们使用。咱们只须要在使用的地方注入JmsMessagingTemplate便可使用。

发送队列消息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@RunWith(SpringRunner.class)

@SpringBootTest

public class ActivemqApplicationTests {

@Autowired

private JmsMessagingTemplate jmsMessagingTemplate;

 

@Test

public void testQueueMsg(){

 //建立名称为zyQueue的队列

 Queue queue = new ActiveMQQueue("zyQueue");

 //向队列发送消息

 jmsMessagingTemplate.convertAndSend(queue,"这是一个队列消息!");

    }

}

  消息的接收方,监听消息队列,当队列中有消息时就能够获取到消息

@Component

public class Consumer {

private static DateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss

,sss");

    /**

     * destination 目标地址即队列

     */

     @JmsListener(destination = "zyQueue")

    public void receiveMessage(String text){

 System.out.println("接收队列消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

}

  执行测试方法发送消息能够看到,控制台输出的消费者接受到消息

 

队列消息只能有一个消费者,若是有多个消费者同时监听一个队列时,只能有一个拿到消息,咱们测试,修改发送方法,循环发送10调消息

@Test

    public void testQueueMsg(){

        //建立名称为zyQueue的队列

        Queue queue = new ActiveMQQueue("zyQueue");

        //向队列发送消息

        for (int i=0;i<10;i++) {

jmsMessagingTemplate.convertAndSend(queue,"这是第"+i+"个队列消息!");

        }

    }

  在Consumer 类中再添加一个消费者,监听队列zyQueue

@JmsListener(destination = "zyQueue")

public void receiveMessage(String text){

System.out.println("接收队列消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

 

    @JmsListener(destination = "zyQueue")

    public void receiveMessage1(String text){

System.out.println("1接收队列消息时间:"+ df.format(new Date())

+",接收到消息内容:"+text);

    }

执行发送消息,看到控制台输出的结果,2个消费者平分了这10条消息

 

  若是但愿监听同一个队列的多个消费者都能接收到全部消息,咱们就只能发送Topic消息了,咱们修改application.properties中的

#消息模式 true:广播(Topic),false:队列(Queue),默认时false

spring.jms.pub-sub-domain=true

  咱们在Consumer 类中添加两个消费者来监听zyTopic队列,接受消息

@JmsListener(destination = "zyTopic")

public void receiveTopicMessage1(String text){

System.out.println("消费者1接收消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

 

@JmsListener(destination = "zyTopic")

public void receiveTopicMessage2(String text){

System.out.println("消费者2接收消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

  执行发消息方法,能够看到控制台输出的内容,2个消费者都完整的接收到了5条消息

 咱们在测试发送消息时修改了属性文件中的配置信息,才能够发送对应的类型的消息,这是因为SpringBoot中默认的是队列消息(查看源码能够知道,监听器默认使用的DefaultJmsListenerContainerFactory),若是咱们想在不修改配置信息的状况下能够同时发送Queue和Topic消息怎么办呢,咱们须要手动的更改初始的配置类,分别针对Queue和Topic消息提供JmsListenerContainerFactory

  新建一个配置类,以下

@SpringBootConfiguration

public class ActiveMqConfig {

 

    @Bean("queueListenerFactory")

    public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory connectionFactory){

        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

        factory.setConnectionFactory(connectionFactory);

        //设置消息模型为队列

        factory.setPubSubDomain(false);

        return factory;

    }

     

    @Bean("topicListenerFactory")

    public JmsListenerContainerFactory topicListenerFactory(ConnectionFactory connectionFactory){

        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

        factory.setConnectionFactory(connectionFactory);

        //设置消息模型为队列

        factory.setPubSubDomain(true);

        return factory;

    }

}

  在容器启动时会针对两种消息类型,初始化获得两个不一样的JmsListenerContainerFactory。下来再修改消费者类,在 @JmsListener 注解中指定 containerFactory,如

@JmsListener(destination = "zyQueue", containerFactory = "queueListenerFactory")

    public void receiveMessage(String text){

        System.out.println("接收队列消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

 

@JmsListener(destination = "zyTopic", containerFactory = "topicListenerFactory")

    public void receiveTopicMessage1(String text){

        System.out.println("消费者1接收消息时间:"+ df.format(new Date()) +", 接收到消息内容:"+text);

    }

  Queue消息使用 queueListenerFactory,Topic消息使用 topicListenerFactory,而后注释掉属性文件中的消息模式配置就能够了。

 

 

返回目录

上一篇

下一篇

SpringBoot入门 (十) 发送邮件

本文记录学习在SpringBoot中发送邮件。

一 邮件发送过程

  发送邮件是一个咱们在项目中常常会用到的功能,如在用户注册时发送验证码,帐户激活等都会用到。完整的一个邮件发送过程主要包含如下几个步骤:

  1 发件人在用户邮件代理上写邮件内容及收件人的邮箱地址;

  2 用户邮件代理根据发件人填写的邮件信息,生成一封符合邮件格式的邮件;

  3 用户邮件代理把邮件发送到发信人的邮件服务器上;

  4 发件人的邮件服务器使用 SMTP 协议把这封邮件发送到收件人的邮件服务器上;

  5 收件人的邮件服务器收到邮件后,把这封邮件放到收件人在这个服务器上的信箱中;

  6 收件人使用用户邮件代理来收取邮件。

二 发送邮件示例

  之前发送邮件时,调用 JavaMail 的相关 API 来开发实现,须要咱们本身去组装消息体,代码量比较大,实现起来也不是很容易;Spring 提供的JavaMailSender 对JavaMail的Api作了必定的封装,简化了发邮件的过程。JavaMailSender 提供了强大的邮件发送功能,可支持各类类型的邮件发送。Spring Boot在JavaMailSender 的基础上又作了进一步的封装,让咱们的使用更加的简单。

  在pom.xml文件中引入须要得依赖

<dependency>

 <groupId>org.springframework.boot</groupId>

 <artifactId>spring-boot-starter-mail</artifactId>

</dependency>

  在application.properties中配置邮件服务相关信息(测试使用得是QQ邮件服务)

# Email

#邮件默认字符集

spring.mail.default-encoding=UTF-8

#邮件服务地址

spring.mail.host=smtp.qq.com

#邮件服务协议,能够不写(查看源码可知,没有时默认值是smtp )

#spring.mail.protocol=smtp

#端口

spring.mail.port=25

#帐号

spring.mail.username=********@qq.com

#密码 使用第三方发送邮件时,须要开通受权,因此此处要写邮箱受权码

spring.mail.password=****************

完成了上边得配置后,在启动服务得时候,SpringBoot会根据咱们得配置,为咱们初始化好一个JavaMailSender类供咱们调用,咱们只须要在要使用得地方注入就能够了。

定义一个邮件服务接口,提供咱们得邮件服务方法,其余业务中用到发邮件功能时,调用这个接口就能够了

public interface EmailSenderService {

    /**

     * 发送文本消息

     * @param subject 邮件主题

     * @param content 邮件内容

     * @param to 收件人(可变参数,多个时用逗号隔开)

     */

    void sendTextMail(String subject, String content, String... to);

 

}

@Service

public class EmailSenderServiceImpl implements EmailSenderService {

 

    @Autowired

    private JavaMailSender javaMailSender;

 

    //发件人邮箱

    @Value("${spring.mail.username}")

    private String from;

 

    @Override

    public void sendTextMail(String subject, String content, String... to) {

        SimpleMailMessage mailMessage = new SimpleMailMessage();

        mailMessage.setFrom(from);

        mailMessage.setTo(to);

        mailMessage.setSubject(subject);

        mailMessage.setText(content);

        mailMessage.setSentDate(new Date());

        javaMailSender.send(mailMessage);

    }

}

  如上,咱们在实现类中注入JavaMailSender后直接调用它send方法就能够完成发邮件。其余业务中用到发邮件业务了,直接调用EmailSenderService 接口得方法便可。咱们彻底也能够把JavaMailSender直接注入到咱们得各个业务模块中去,在发邮件时直接调用JavaMailSender得send方法发邮件。可是仍是推荐将邮件发送相关功能独立起来,便于维护。

  上边咱们实现了发送一个文本邮件,有时候咱们还须要在发送邮件时附带发送附件,这种也是支持的,咱们添加接口及实现方法

/**

     * 发送带附件邮件

     * @param subject 主题

     * @param content 内容

     * @param filePath 附件得本地路径

     * @param fileName 附件名

     * @param to 收件人

     */

    void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to);

@Override

public void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to) {

MimeMessage mimeMessage =javaMailSender.createMimeMessage();

        try {

MimeMessageHelper helper =new MimeMessageHelper(mimeMessage, true);

         helper.setFrom(from);

         helper.setTo(to);

         helper.setSubject(subject);

            helper.setText(content);

            //附件

            FileSystemResource file = new FileSystemResource(new File(filePath));

            helper.addAttachment(fileName, file);

 

            javaMailSender.send(mimeMessage);

        } catch (MessagingException e) {

            e.printStackTrace();

        }

    }

  若是咱们发送邮件时,除了收件人以外,还想让某些人知道即抄送某些人,这种也是支持得,接口及实现方法以下:

1

2

3

4

5

6

7

8

/**

     * 发送一个邮件并抄送

     * @param subject 主题

     * @param content 内容

     * @param ccList 抄送人(能够有多个)

     * @param to 收件人(能够有多个)

     */

    void sendTextMail(String subject, String content, List<String> ccList, String... to);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

@Override

    public void sendTextMail(String subject, String content, List<String> ccList, String... to) {

        //收件人地址

        InternetAddress[] addressesTo = new InternetAddress[to.length];

        if(to != null && to.length>0){

            for(int i=0;i<to.length;i++){

                InternetAddress addressTo = null;

                try {

                    addressTo = new InternetAddress(to[i]);

                    addressesTo[i] = addressTo;

                } catch (AddressException e) {

                    e.printStackTrace();

                }

            }

        }

        //抄送人地址

        InternetAddress[] addressesCc = new InternetAddress[ccList.size()];

        if(ccList != null && ccList.size() > 0){

            for(int i=0;i<ccList.size();i++){

                String ccAdd = ccList.get(i);

                InternetAddress address = null;

                try {

                    address = new InternetAddress(ccAdd);

                    addressesCc[i] = address;

                } catch (AddressException e) {

                    e.printStackTrace();

                }

            }

        }

 

        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            @Override

            public void prepare(MimeMessage mimeMessage) throws Exception {

                mimeMessage.setFrom(from);

                mimeMessage.setSubject(subject);

                mimeMessage.setText(content);

                mimeMessage.setRecipients(Message.RecipientType.TO, addressesTo);

                mimeMessage.setRecipients(Message.RecipientType.CC, addressesCc);

            }

        };

        javaMailSender.send(preparator);

    }

  如上方法就实现了向多人发送邮件而且抄送多人

 

返回目录

上一篇

下一篇

SpringBoot入门 (十一) 数据校验

本文记录学习在SpringBoot中作数据校验。

一 什么是数据校验

  数据校验就是在应用程序中,对输入进来得数据作语义分析判断,阻挡不符合规则得数据,放行符合规则得数据,以确保被保存得数据符合咱们得数据存储规则。

  在SpringMvc中作数据校验有2中方式:一种是 Spring 自带的验证框架,另一种是利用 JSR 实现。JSR 是一个规范,提供了完整得一套 API,经过标注给对象属性添加约束。Hibernate Validator 就是 对JSR 规范全部注解的具体实现,以及一些附加的约束注解。用户还能够自定义约束注解。Hibernate Validator提供得注解以下:

  注解

   做用目标

   检查规则

 @Length(min=, max=)

 属性(String)

 检查字符串长度是否符合范围

 @Max(value=)

 属性(以 numeric 或者 string 类型来表示一个数字)

 检查值是否小于或等于最大值

 @Min(value=)

 属性(以 numeric 或者 string 类型来表示一个数字)

 检查值是否大于或等于最小值

 @NotNull

 属性

 检查值是否非空(not null)

 @Future

 属性(date 或 calendar)

 检查日期是不是将来

 @Pattern(regex="regexp", flag=)

 属性(string)

 检查属性是否与给定匹配标志的正则表达式相匹配

 @Range(min=, max=)

 属性(以 numeric 或者 string 类型来表示一个数字)

 检查值是否在最小和最大值之间(包括临界值)

 

 

 

 

 

 

 

 

 

 @Size(min=, max=)

 属性(array,collection,map)

 检查元素大小是否在最小和最大值之间(包括临界值)

 @AssertFalse

 属性

 检查方法的演算结果是否为 false(对以代码方式而不是注解表示的约束颇有用)

 @AssertTrue

 属性

 检查方法的演算结果是否为 true(对以代码方式而不是注解表示的约束颇有用)

 @Valid

 属性(object)

 对关联对象递归进行验证。若是对象是集合或数组,就递归地验证其元素;若是对象是 Map,则递归验证其值元素

 @Email

 属性(String)

 检查字符串是否符合有效的 email 地址规范

 @Past

 属性(date 或 calendar)

 检查日期是不是过去

 

二 使用示例

  SpringBoot对数据校验也作了支持,默认提供的参数校验依赖于 hibernate-validator来实现。使用 Hibernate Validator校验数据,须要定义一个接收的数据模型,使用注解的形式描述字段校验的规则。经过前台页面提交form表单保存数据,后台作校验。

   在pom.xml文件中引入依赖

1

2

3

4

5

6

7

8

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

<dependency>

  <groupId>org.hibernate.validator</groupId>

  <artifactId>hibernate-validator</artifactId>

</dependency>

  写一个实体类,对相关属性字段经过注解添加校验规则

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class Person {

    @NotBlank(message = "不能为空")

    @Length(min = 2, max = 20, message = "长度要在2到20之间")

    private String name;

 

    @NotNull

    @Min(value = 17, message = "最小值为17")

    private Integer age;

 

    @NotEmpty

    @Email(message="邮件格式不正确")

    private String email;

     

  // 此处省略getter和setter 

 

}

  每一个注解中得属性message是数据校验不经过时咱们要给出得提示信息,如 @Email(message="邮件格式不正确") 当邮件格式校验不经过时,提示邮件格式不正确。

  控制器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@Controller

public class TestController {

 

    @GetMapping("/info")

    public String info(Model model){

        Person person = new Person();

        model.addAttribute("person", person);

        return "person_info.html";

    }

 

    @PostMapping("/save")

    public String save(@Valid Person person, BindingResult result, Model model){

        if (result.hasErrors()) {

            model.addAttribute("person", person);

            return "person_info.html";

        }    //数据保存。。。

        model.addAttribute("success","校验经过,数据已保存");

        return "success.html";

    }

 

}

  咱们经过访问info方法,跳转到信息输入页面,提交数据时访问save方法,Person前得注解@Valid 说明当前对象要作数据校验,BindingResult 中会存储数据校验得结果,@Valid和BindingResult必须成对出现。若是校验不经过时即有错误信息,会进入if略记判断中,返回信息输入页面,展现错误提示信息。

  信息输入页面

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

    <form th:action="@{/save}" th:method="post" th:object="${person}">

        <table>

            <tr>

                <td>name:</td>

                <td><input type="text" th:field="*{name}" th:value="${person.name}"/></td>

                <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}" th:style="'color:red'">Name Error</td>

            </tr>

            <tr>

                <td>age:</td>

                <td><input type="text" th:field="*{age}" th:value="${person.age}"/></td>

                <td th:if="${#fields.hasErrors('age')}" th:errors="*{age}" th:style="'color:red'">Age Error</td>

            </tr>

            <tr>

                <td>email:</td>

                <td><input type="text" th:field="*{email}" th:value="${person.email}"/></td>

                <td th:if="${#fields.hasErrors('email')}" th:errors="*{email}" th:style="'color:red'">Email Error</td>

            </tr>

            <tr>

                <td th:colspan="2"><button th:type="submit">Submit</button></td>

            </tr>

        </table>

    </form>

</body>

</html>

  th:object 要与后台接收校验得对象保持一致。访问info方法在页面随便输入一些信息,在提交数据,会看到校验结果

 

  若是各项数据都符合规则,则校验经过,跳转至success页面

 

 

返回目录

上一篇

返回第一篇

SpringBoot入门 (十二) 定时任务

本文记录在SpringBoot中使用定时任务。

  在咱们的项目中,常常须要用到定时任务去帮咱们作一些事情,好比服务状态监控,业务数据状态的更改等,SpringBoot中实现定时任务有2中方案,一种是自带的,咱们只须要加上注解便可;另外一种是集成Quartz来实现定时任务。

一 SpringBoot 提供的定时任务

  在SpringBoot的starter包中已经提供了对定时任务的支持,咱们很容易实现定时任务。修改pom.xml文件,加入以下内容,引入依赖:

<dependency>

   <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter</artifactId>

</dependency>

  在启动类上加注@EnableScheduling 注解,开启定时任务

@SpringBootApplication

@EnableScheduling

public class TimingTaskApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(TimingTaskApplication.class, args);

    }

 

}

  建立定时任务类及要定时执行的方法

1

2

3

4

5

6

7

8

9

10

11

12

@Component

public class ScheduleTaskDemo {

 

    private int num1 = 0;

    private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

    @Scheduled(cron = "*/5 * * * * ?")

    public void test1(){

        System.out.println("这是test1方法第"+ (++num1) + "次执行,执行时间:"+df.format(new Date()));

    }

 

}

  @Component 注解 将当前类交给Spring容器管理

  @Scheduled 注解标明方法是一个定时执行的方法

  启动项目后能够看到控制台打印出的信息

 

  @Scheduled 注解有几个参数可使用,每一个参数的意义不同,参数及执行规则说明以下:

  fixedRate @Scheduled(fixedRate = 5000) 上一次开始执行时间点以后每5秒执行一次;

  fixedDelay @Scheduled(fixedDelay = 5) 上一次执行完毕时间点以后每5秒执行一次;

  initialDelay @Scheduled(initialDelay = 1, fixedDelay = 6) 第一次延迟1秒后执行,以后按照fixedRate的规则执行;

  cron @Scheduled(cron = "*/5 * * * * ?") 一个表达式,一共有7位,通常只须要设置6为就能够了

  第一位:秒,取值范围是0-59;

  第二位:分,取值范围是0-59;

  第三位:时,取值范围0-23

  第四位:日,取值范围1-31

  第五位:月,取值范围1-12

  第六位:星期,取值范围1-71表明星期日,2表明星期一,7表明星期六;

  第七位:年,取值范围1970-099,能够不设置。

  cron表达式也能够在http://cron.qqe2.com进行在线生成。

 二 SpringBoot集成Quartz

     Quartz是用Java编写的一个开源的任务调度框架。提供了丰富的Api供调用,支持集群环境和持久化,支持多种配置,与SpringBoot能够无缝集成。

  Quartz几个关键元素:

  Job  表明要执行的任务,是个接口,提供了一个方法 execute(JobExecutionContext context);

  JobDetail  表明具体的要执行的任务;

  Trigger  表明调度任务的触发器,配置调度任务的执行规则;

  Scheduler  表明调度容器,一个调度容器中能够注册多个JobDetail和Trigger。

  元素关系以下图:

 

  SpringBoot对Quartz已经提供了支持,咱们能够很容易的使用,在pom.xml文件中引入依赖

1

2

3

4

<dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-quartz</artifactId>

        </dependency>

  在启动类上加注解 @EnableScheduling ,开启定时执行。

  建立一个要执行的任务继承QuartzJobBean,输出任务执行时间

1

2

3

4

5

6

7

8

9

10

public class MyTask1 extends QuartzJobBean {

 

    private DateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");

 

    @Override

    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println("MyTask1 执行时间:" + df.format(new Date()));

    }

 

}

  建立一个配置类,初始化MyTask1任务所须要的JobDetail和Trigger

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@SpringBootConfiguration

public class QuartzConfig {

 

    @Bean

    public JobDetail myTask1JobDetail(){

        return JobBuilder.newJob(MyTask1.class).withIdentity("myTask1").storeDurably().build();

    }

 

    @Bean

    public Trigger myTask1Trigger(){

        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()

                //5秒执行一次

                .withIntervalInSeconds(5)

                .repeatForever();

        SimpleTrigger trigger = TriggerBuilder.newTrigger()

                //指定触发器对应的JobDetail

                .forJob(myTask1JobDetail())

                .withIdentity("myTask1")

                .withSchedule(scheduleBuilder).build();

        return trigger;

    }

 

}

  启动项目,能够看到控制台输出的内容

 

    在上边的方法,咱们使用的定时执行方法是在代码中写的固定值,这种局限性比较大,难以知足一些复杂的定制任务执行时间。咱们使用Cron表达式来完成定时任务执行时间配置。

  建立任务类,继承QuartzJobBean

1

2

3

4

5

6

7

8

9

10

public class MyTask2 extends QuartzJobBean {

 

    private DateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");

 

    @Override

    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        System.out.println("MyTask2 执行时间:" + df.format(new Date()));

    }

 

}

  在配置类QuartzConfig中建立任务所需的JobDetail和Trigger

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@Bean

    public JobDetail myTask2JobDetail(){

        return JobBuilder.newJob(MyTask2.class).withIdentity("myTask2").storeDurably().build();

    }

 

    @Bean

    public Trigger myTask2Trigger(){

        //cron 表达式

        String cronStr = "*/10 * * * * ?";

        //根据表达式设置ScheduleBuilder

        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronStr);

        CronTrigger trigger = TriggerBuilder.newTrigger()

                //指定JobDetail

                .forJob(myTask2JobDetail())

                .withIdentity("myTask2")

                //指定ScheduleBuilder

                .withSchedule(cronScheduleBuilder)

                .build();

        return trigger;

    }

  重启项目,看到控制台输出内容,任务1每5秒执行一次,任务2每10秒执行一次

 

 

 

 

 

返回目录

 备注:此文档借鉴其余博客的,若有问题请及时联系,谢谢

相关文章
相关标签/搜索