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秒執行一次

 

 

 

 

 

返回目錄

 備註:此文檔借鑑其餘博客的,若有問題請及時聯繫,謝謝

相關文章
相關標籤/搜索