[关闭]
@SendLin 2018-07-11T17:10:45.000000Z 字数 51639 阅读 1320

Spring boot 学习

Springboot 配置文件读取 properties jpa 自定义异常


Springboot 项目的Application.java文件是程序的入口所以其位置应与所有的Java文件的"包"同级,以防止bean未被扫描到@Autowired注入失败粗体文本

一、热部署

1、http://start.spring.io/ 下载自己想要的模板,注意各种jar版本问题
2、关于SpringBoot的热部署配置及依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-devtools</artifactId>
  4. <version>2.0.2.RELEASE</version>
  5. <optional>true</optional>
  6. <scope>true</scope>
  7. </dependency>
  8. <plugin>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-maven-plugin</artifactId>
  11. <configuration>
  12. <fork>true</fork>
  13. </configuration>
  14. </plugin>

二、读取Springboot核心配置文件application.properties

application.properties

  1. #tomcat port
  2. server.port=8080
  3. server.servlet.context-path=/spring-boot/

Java

  1. @Autowired
  2. private Environment environment;
  3. @RequestMapping("context")
  4. Object getContext(){
  5. return environment.getProperty("server.port");
  6. }

三、读取自定义配置文件config.properties(文件名随意)

config.properties

  1. config.ip=192.168.1.1
  2. config.port=8080

java代码domain

  1. @Component
  2. @PropertySource(value = "classpath:/config.properties")
  3. //由于@ConfigurationProperties的locations 属性被移除所以无法指定配置文件路径,由此藉由@PropertySource方法代替
  4. @ConfigurationProperties(prefix="config")
  5. public class config {
  6. @NotEmpty
  7. private String ip;
  8. private int port;
  9. public String getIp() {
  10. return ip;
  11. }
  12. public void setIp(String ip) {
  13. this.ip = ip;
  14. }
  15. public int getPort() {
  16. return port;
  17. }
  18. public void setPort(int port) {
  19. this.port = port;
  20. }
  21. }

Java代码Controller

  1. @Autowired
  2. private config config;
  3. @RequestMapping("/configPorperties")
  4. Object getport(){
  5. return config;
  6. }

四、导入XML配置

  1. import org.springframework.context.annotation.Configuration;
  2. import org.springframework.context.annotation.ImportResource;
  3. @Configuration
  4. //相当于<beans>标签可以与@bean(相当于<bean>)配合
  5. @ImportResource(locations = {"classpath:MyXml.xml"})
  6. //指定文件路径即可加载XML文件配置
  7. public class AllConfigs {
  8. }

五、输出XML或JSON格式的响应

pom依赖

  1. <!--返回xml格式的内容-->
  2. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-xml-provider -->
  3. <dependency>
  4. <groupId>com.fasterxml.jackson.jaxrs</groupId>
  5. <artifactId>jackson-jaxrs-xml-provider</artifactId>
  6. <version>2.9.5</version>
  7. </dependency>

在controller的类上加@RestController注解默认输出JSON格式的数据,导入以上jar包可输出xml格式

六、利用JPA对数据库的操作 转至该网站

  1. spring.datasource.url=jdbc:mysql://localhost:3306/test
  2. spring.datasource.username=root
  3. spring.datasource.password=root
  4. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  5. spring.jpa.properties.hibernate.hbm2ddl.auto=update
  6. spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
  7. spring.jpa.show-sql= true

其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构,有四个值:

  1. create 每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
  2. create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
  3. update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
  4. validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
  1. @Entity
  2. public class User implements Serializable {
  3. private static final long serialVersionUID = 1L;
  4. @Id
  5. @GeneratedValue
  6. private Long id;
  7. @Column(nullable = false, unique = true)
  8. private String userName;
  9. @Column(nullable = false)
  10. private String passWord;
  11. @Column(nullable = false, unique = true)
  12. private String email;
  13. @Column(nullable = true, unique = true)
  14. private String nickName;
  15. @Column(nullable = false)
  16. private String regTime;
  17. //省略getter settet方法、构造方法
  18. }

dao只要继承JpaRepository类就可以,几乎可以不用写方法,还有一个特别有尿性的功能非常赞,就是可以根据方法名来自动的生产SQL,比如findByUserName 会自动生产一个以 userName 为参数的查询方法,比如 findAlll 自动会查询表里面的所有数据,比如自动分页等等。。
Entity中不映射成列的字段得加@Transient 注解,不加注解也会映射成列

  1. public interface UserRepository extends JpaRepository<User, Long> {
  2. User findByUserName(String userName);
  3. User findByUserNameOrEmail(String username, String email);
  4. List<User> findAllByUserName(String userName);
  5. List<User> findByUserNameAndRegTime(String name,String time);
  6. List<User> findByUserNameOrRegTime(String name,String time);
  7. @Transactional//不加Transactional会报错
  8. @Modifying
  9. @Query("update User u set u.userName = ?1 where u.userName = ?2")
  10. //sql语句拼写的方式是以对象名.属性的方式进行查询
  11. int modifyByUserName(String userName,String userName1);

Controller代码

  1. @RequestMapping(value = "getUserList/{zz}/{size}", method = RequestMethod.GET)
  2. public List<User> getUserList(@PathVariable(name = "zz") Integer zz, @PathVariable(name = "size") Integer size) {
  3. List lst = new ArrayList<>();
  4. Pageable pageable = new PageRequest(zz, size);
  5. Page<User> page = userRepository.findAll(pageable);
  6. Iterator<User> iterator = page.iterator();
  7. while (iterator.hasNext()) {
  8. lst.add(iterator.next());
  9. }
  10. lst.add(String.format("=========第 %s 页===========", pageable.getPageNumber()));
  11. lst.add(String.format("=========有 %s 条数据===========", pageable.getPageSize()));
  12. return lst;
  13. }
  14. @RequestMapping(value = "Delete/{id}", method = RequestMethod.GET)
  15. public Object DeleteUser(@PathVariable(name = "id") Long id) {
  16. userRepository.deleteById(id);
  17. return "SUCCESS";
  18. }
  19. @RequestMapping(value = "Count",method = RequestMethod.GET)
  20. public Object contUser(){
  21. return userRepository.count();
  22. }
  23. @RequestMapping(value = "findAnd/{name}/{time}",method = RequestMethod.GET)
  24. public Object findAnd(@PathVariable(name = "name")String name,@PathVariable(name = "time") String time){
  25. return userRepository.findByUserNameAndRegTime(name, time);
  26. }
  27. @RequestMapping(value = "findOr/{name}/{time}",method = RequestMethod.GET)
  28. public Object findOr(@PathVariable(name = "name")String name,@PathVariable(name = "time") String time){
  29. return userRepository.findByUserNameOrRegTime(name, time);
  30. }
  31. @RequestMapping(value = "updateUser/{name}/{name1}",method = RequestMethod.GET)
  32. public Object updateUser(@PathVariable(name = "name")String name,@PathVariable(name = "name1") String name1){
  33. int num = userRepository.modifyByUserName(name,name1);
  34. return num > 0 ? "SUCCESS" : "FAILURE";
  35. }
  36. //利用该对象进行
  37. @PersistenceUnit
  38. private EntityManagerFactory entityManagerFactory;
  39. @RequestMapping("/leftJoin")
  40. public Object LeftJoin() {
  41. String sql = "select u.id,u.userName,u.passWord,u.email,u.nickName,u.regTime,i.id,i.message,i.user from User u left join Interest i on u.id = i.user";
  42. //sql是以对象.属性的方法进行语句拼写
  43. return entityManagerFactory.createEntityManager().createQuery(sql).getResultList();
  44. }

使用注解的方法生成外键约束

  1. package com.example.demo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import javax.persistence.*;
  6. import java.io.Serializable;
  7. @Entity
  8. @AllArgsConstructor//生成全参构造器
  9. @Data//生成get set toString equal 方法
  10. @NoArgsConstructor //生成无参构造器
  11. public class User implements Serializable{
  12. @Transient
  13. private static final long serialVersionUID = 1L;
  14. @Id
  15. @GeneratedValue
  16. private Long id;
  17. @Column(nullable = false, unique = true)
  18. private String userName;
  19. @Column(nullable = false)
  20. private String passWord;
  21. @Column(nullable = false, unique = true)
  22. private String email;
  23. @Column(nullable = true, unique = true)
  24. private String nickName;
  25. @Column(nullable = false)
  26. private String regTime;
  27. }
  28. -----------------------------------------------------------------
  29. package com.example.demo;
  30. import lombok.AllArgsConstructor;
  31. import lombok.Data;
  32. import lombok.NoArgsConstructor;
  33. import javax.persistence.*;
  34. import java.io.Serializable;
  35. @Data
  36. @NoArgsConstructor
  37. @AllArgsConstructor
  38. @Entity
  39. public class Interest implements Serializable{
  40. @Id
  41. @GeneratedValue
  42. @Column(name = "Interest_id")
  43. private Long id;
  44. @OneToOne//声明表与表的关系
  45. @JoinColumn(name = "user_id")//声明外键约束额字段名
  46. private User user;//声明外键约束的对应实体类
  47. @Column()
  48. private String message;
  49. }

controller类的方法

  1. @RequestMapping("/saveIn")
  2. public Object saveInterest() {
  3. User user = new User(17L, "211", "211", "121", "211", "121");
  4. interestRepository.save(new Interest(11111L, user, "this is messagie"));
  5. return "SUCCESS";
  6. }

实体类声明@Entity 关系型数据库支持类型、声明@Document为mongodb支持类型,不同的数据源使用不同的实体就可以了,但如果一个类同时是两个数据库类型的映射类,那么两个注解也能同时混用,也可以通过对不同的包路径进行声明,比如A包路径下使用mysql,B包路径下使用mongoDB

  1. @EnableJpaRepositories(basePackages = "com.neo.repositories.jpa")
  2. @EnableMongoRepositories(basePackages = "com.neo.repositories.mongo")
  3. interface Configuration { }

七、自定义异常

  1. package com.example.util;
  2. public class GlobalException extends Exception {
  3. private int code;
  4. public int getCode() {
  5. return code;
  6. }
  7. public void setCode(int code) {
  8. this.code = code;
  9. }
  10. public GlobalException(String message) {
  11. super(message);
  12. }
  13. public GlobalException(String message,int code){
  14. super(message);
  15. this.code = code;
  16. }
  17. }
  18. //自定义枚举异常代码
  19. package com.example.util;
  20. public enum ResponseCode {
  21. PARAM_ERROR_CODE(400),
  22. SERVER_ERROR_CODE(500);
  23. private int code;
  24. public int getCode() {
  25. return code;
  26. }
  27. public void setCode(int code) {
  28. this.code = code;
  29. }
  30. private ResponseCode(int code) {
  31. this.code = code;
  32. }
  33. }
  34. //自定义异常
  35. package com.example.util;
  36. public class ResponseDate {
  37. private Boolean status = true;
  38. private int code = 200;
  39. private String message;
  40. private Object data;
  41. public ResponseDate(Object data){
  42. this.data = data;
  43. }
  44. public static ResponseDate ok(Object data){
  45. return new ResponseDate(data);
  46. }
  47. public ResponseDate(){
  48. }
  49. public Boolean getStatus() {
  50. return status;
  51. }
  52. public void setStatus(Boolean status) {
  53. this.status = status;
  54. }
  55. public int getCode() {
  56. return code;
  57. }
  58. public void setCode(int code) {
  59. this.code = code;
  60. }
  61. public String getMessage() {
  62. return message;
  63. }
  64. public void setMessage(String message) {
  65. this.message = message;
  66. }
  67. public Object getData() {
  68. return data;
  69. }
  70. public void setData(Object data) {
  71. this.data = data;
  72. }
  73. }
  74. //自定义异常
  75. package com.example.util;
  76. public enum ResponseCode {
  77. PARAM_ERROR_CODE(400),
  78. SERVER_ERROR_CODE(500);
  79. private int code;
  80. public int getCode() {
  81. return code;
  82. }
  83. public void setCode(int code) {
  84. this.code = code;
  85. }
  86. private ResponseCode(int code) {
  87. this.code = code;
  88. }
  89. }
  90. //自定义异常
  91. package com.example.util;
  92. public class ResponseDate {
  93. private Boolean status = true;
  94. private int code = 200;
  95. private String message;
  96. private Object data;
  97. public ResponseDate(Object data){
  98. this.data = data;
  99. }
  100. public static ResponseDate ok(Object data){
  101. return new ResponseDate(data);
  102. }
  103. public ResponseDate(){
  104. }
  105. public Boolean getStatus() {
  106. return status;
  107. }
  108. public void setStatus(Boolean status) {
  109. this.status = status;
  110. }
  111. public int getCode() {
  112. return code;
  113. }
  114. public void setCode(int code) {
  115. this.code = code;
  116. }
  117. public String getMessage() {
  118. return message;
  119. }
  120. public void setMessage(String message) {
  121. this.message = message;
  122. }
  123. public Object getData() {
  124. return data;
  125. }
  126. public void setData(Object data) {
  127. this.data = data;
  128. }
  129. }
  130. //自定义异常适配器
  131. package com.example.util;
  132. import org.springframework.web.bind.annotation.ControllerAdvice;
  133. import org.springframework.web.bind.annotation.ExceptionHandler;
  134. import org.springframework.web.bind.annotation.ResponseBody;
  135. import javax.servlet.http.HttpServletRequest;
  136. @ControllerAdvice
  137. public class GlobalExceptionHandler {
  138. @ExceptionHandler(GlobalException.class)
  139. @ResponseBody
  140. public ResponseDate jsonErrorHandler(HttpServletRequest request ,GlobalException e) throws Exception{
  141. ResponseDate r = new ResponseDate();
  142. r.setMessage(e.getMessage());
  143. r.setCode(e.getCode());
  144. r.setData(null);
  145. r.setStatus(false);
  146. return r;
  147. }
  148. }

八、Listener

spring boot提供了四种事件类型:

  1. 1ApplicationEnvironmentPreparedEventspring boot 对应Enviroment已经准备完毕。
  2. 2ApplicationPreparedEventspring boot上下文context创建完成。
  3. 3ApplicationStartedEvent spring boot启动开始时执行的事件。
  4. 4ApplicationFailedEventspring boot启动异常时执行事件。

以上顺序是按照起订Springboot启动时各方法的打印顺序顺序,但是ApplicationStartedEvent应该是第一位启动啊...
以下是Java代码

  1. package com.example.listener;
  2. import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
  3. import org.springframework.context.ApplicationListener;
  4. public class ApplicationListenerEnvironmentPrepared implements ApplicationListener<ApplicationEnvironmentPreparedEvent>{
  5. /**
  6. * Handle an application event.
  7. *
  8. * @param event the event to respond to
  9. */
  10. @Override
  11. public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
  12. //可以通过ApplicationEnvironmentPreparedEvent获取到SpringApplication、ConfigurableEnvironment等等信息, 可以通过ConfigurableEnvironment实例对象来修改以及获取默认的环境信息。
  13. SpringApplication springApplication = event.getSpringApplication();
  14. ConfigurableEnvironment environment = event.getEnvironment();
  15. long timestamp = event.getTimestamp();
  16. Object source = event.getSource();
  17. System.out.println(
  18. String.format("自定义标识 2 :----%s----",getClass().getSimpleName())
  19. );
  20. }
  21. }
  22. package com.example.listener;
  23. import org.springframework.boot.context.event.ApplicationPreparedEvent;
  24. import org.springframework.context.ApplicationListener;
  25. public class ApplicationListenerPrepared implements ApplicationListener<ApplicationPreparedEvent> {
  26. /**
  27. * Handle an application event.
  28. *
  29. * @param event the event to respond to
  30. */
  31. @Override
  32. public void onApplicationEvent(ApplicationPreparedEvent event) {
  33. System.out.println(
  34. String.format("自定义标识 3 :----%s----",getClass().getSimpleName())
  35. );
  36. }
  37. }
  38. package com.example.listener;
  39. import org.springframework.boot.context.event.ApplicationStartedEvent;
  40. import org.springframework.context.ApplicationListener;
  41. public class ApplicationListenerStarted implements ApplicationListener<ApplicationStartedEvent> {
  42. /**
  43. * Handle an application event.
  44. *
  45. * @param event the event to respond to
  46. */
  47. @Override
  48. public void onApplicationEvent(ApplicationStartedEvent event) {
  49. //可以在SpringApplication启动之前做一些手脚,比如修改SpringApplication实例对象中的属性值
  50. SpringApplication springApplication = event.getSpringApplication();
  51. //springApplication.setShowBanner(false);
  52. System.out.println(
  53. String.format("自定义标识 1 :----%s----",getClass().getSimpleName())
  54. );
  55. }
  56. }
  57. package com.example.listener;
  58. import org.springframework.boot.context.event.ApplicationFailedEvent;
  59. import org.springframework.context.ApplicationListener;
  60. public class ApplicationListenerFailed implements ApplicationListener<ApplicationFailedEvent> {
  61. @Override
  62. public void onApplicationEvent(ApplicationFailedEvent event) {
  63. //可以通过ApplicationFailedEvent 获取Throwable实例对象获取异常信息并处理。
  64. Throwable exception = event.getException();
  65. System.out.println(
  66. String.format("自定义标识 4 :----%s----",getClass().getSimpleName())
  67. );
  68. }
  69. }

Application.properties中使监听器生效的代码

  1. context.listener.classes=com.example.listener.ApplicationListenerStarted,com.example.listener.ApplicationListenerEnvironmentPrepared,com.example.listener.ApplicationListenerFailed,com.example.listener.ApplicationListenerPrepared

复制类路径,以逗号分割,需要注意的是采用配置的方式ApplicationStartedEvent起不了作用的,当框架加载到配置文件的时候其实项目已经启动了,所以这个事件是无效的。
所以在Application.java中配置如下

  1. package com.example;
  2. import com.example.listener.ApplicationListenerEnvironmentPrepared;
  3. import com.example.listener.ApplicationListenerFailed;
  4. import com.example.listener.ApplicationListenerPrepared;
  5. import com.example.listener.ApplicationListenerStarted;
  6. import org.springframework.boot.SpringApplication;
  7. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  8. import org.springframework.context.annotation.ComponentScan;
  9. import org.springframework.context.annotation.Configuration;
  10. @Configuration
  11. @EnableAutoConfiguration
  12. @ComponentScan(basePackages = {"com.example"})
  13. public class Application {
  14. public static void main(String[] args) {
  15. /**
  16. * 采用代码方式注册监听器<br>
  17. * 或者通过增加配置context.listener.classes=com.cxytiandi.listener.ApplicationListenerStarted
  18. * 多个用逗号隔开
  19. */
  20. SpringApplication application = new SpringApplication(Application.class);
  21. application.addListeners(new ApplicationListenerStarted());
  22. application.addListeners(new ApplicationListenerEnvironmentPrepared());
  23. application.addListeners(new ApplicationListenerPrepared());
  24. application.addListeners(new ApplicationListenerFailed());
  25. application.run(args);
  26. //SpringApplication.run(Application.class, args);
  27. }
  28. }

九、过滤器

1、方式一

  1. package com.example.Filter;
  2. import org.apache.catalina.filters.RemoteIpFilter;
  3. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import javax.servlet.*;
  7. import javax.servlet.http.HttpServletRequest;
  8. import java.io.IOException;
  9. @Configuration
  10. public class WebConfiguration {
  11. //这个好像无用
  12. @Bean
  13. public RemoteIpFilter remoteIpFilter(){
  14. return new RemoteIpFilter();
  15. }
  16. //在这里进行过滤器的配置
  17. @Bean
  18. public FilterRegistrationBean testRegistrationBean(){
  19. FilterRegistrationBean registrationBean = new FilterRegistrationBean();
  20. registrationBean.setFilter(new MyFilter());
  21. registrationBean.addUrlPatterns("/*");
  22. registrationBean.addInitParameter("paramName","paramValue");
  23. registrationBean.setName("MyFFFFFFF");
  24. registrationBean.setOrder(1);
  25. return registrationBean;
  26. }
  27. public class MyFilter implements Filter{
  28. @Override
  29. public void init(FilterConfig filterConfig) throws ServletException {
  30. System.out.println("------------init----------");
  31. }
  32. @Override
  33. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  34. System.out.println("this is my filter ,url = " + ((HttpServletRequest) request).getRequestURI());
  35. chain.doFilter(request,response);
  36. }
  37. @Override
  38. public void destroy() {
  39. System.out.println("---------destory---------");
  40. }
  41. }
  42. }

当有多个过滤器是需要设置执行顺序,只需要在FilterRegistrationBean类的setOrder()加入int类型的数字,服务器会根据其大小,按照 从小到大的顺序进行加载

2、过滤器 方式二

  1. package com.example.Filter;
  2. import org.springframework.core.annotation.Order;
  3. import javax.servlet.*;
  4. import javax.servlet.annotation.WebFilter;
  5. import java.io.IOException;
  6. @WebFilter(filterName="LoginFilter",urlPatterns="*")
  7. @Order(3)//在这里设置filter的加载级别
  8. //注意使用注解方式设置Filter过滤器需要在启动类Application.Java添加`@ServletComponentScan`注解
  9. public class LoginFilter1 implements Filter{
  10. @Override
  11. public void init(FilterConfig filterConfig) throws ServletException {
  12. }
  13. @Override
  14. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  15. System.out.println("我是后来后来来的过滤器");
  16. chain.doFilter(request,response);
  17. }
  18. @Override
  19. public void destroy() {
  20. }
  21. }

十、文件的批量上传下载 程序转自

  1. package com.example.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestMethod;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import org.springframework.web.multipart.MultipartFile;
  11. import org.springframework.web.multipart.MultipartHttpServletRequest;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. import java.io.*;
  15. import java.util.List;
  16. @Controller
  17. public class FileController {
  18. @RequestMapping("/greeting")
  19. public String greeting(@RequestParam(value = "name", required = false, defaultValue = "World") String name, Model model) {
  20. model.addAttribute("name", name);
  21. return "greeting";
  22. }
  23. private static final Logger logger = LoggerFactory.getLogger(FileController.class);
  24. //文件上传相关代码
  25. @RequestMapping(value = "upload")
  26. @ResponseBody
  27. public String upload(@RequestParam("test") MultipartFile file) {
  28. if (file.isEmpty()) {
  29. return "文件为空";
  30. }
  31. // 获取文件名
  32. String fileName = file.getOriginalFilename();
  33. logger.info("上传的文件名为:" + fileName);
  34. // 获取文件的后缀名
  35. String suffixName = fileName.substring(fileName.lastIndexOf("."));
  36. logger.info("上传的后缀名为:" + suffixName);
  37. // 文件上传后的路径
  38. String filePath = "E://test//";
  39. // 解决中文问题,liunx下中文路径,图片显示问题
  40. // fileName = UUID.randomUUID() + suffixName;
  41. File dest = new File(filePath + fileName);
  42. // 检测是否存在目录
  43. if (!dest.getParentFile().exists()) {
  44. dest.getParentFile().mkdirs();
  45. }
  46. try {
  47. file.transferTo(dest);
  48. return "上传成功";
  49. } catch (IllegalStateException e) {
  50. e.printStackTrace();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. return "上传失败";
  55. }
  56. //文件下载相关代码
  57. @RequestMapping("/download")
  58. public String downloadFile(org.apache.catalina.servlet4preview.http.HttpServletRequest request, HttpServletResponse response) {
  59. String fileName = "FileUploadTests.java";
  60. if (fileName != null) {
  61. //当前是从该工程的WEB-INF//File//下获取文件(该目录可以在下面一行代码配置)然后下载到C:\\users\\downloads即本机的默认下载的目录
  62. String realPath = request.getServletContext().getRealPath(
  63. "//WEB-INF//");
  64. File file = new File(realPath, fileName);
  65. if (file.exists()) {
  66. response.setContentType("application/force-download");// 设置强制下载不打开
  67. response.addHeader("Content-Disposition",
  68. "attachment;fileName=" + fileName);// 设置文件名
  69. byte[] buffer = new byte[1024];
  70. FileInputStream fis = null;
  71. BufferedInputStream bis = null;
  72. try {
  73. fis = new FileInputStream(file);
  74. bis = new BufferedInputStream(fis);
  75. OutputStream os = response.getOutputStream();
  76. int i = bis.read(buffer);
  77. while (i != -1) {
  78. os.write(buffer, 0, i);
  79. i = bis.read(buffer);
  80. }
  81. System.out.println("success");
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. } finally {
  85. if (bis != null) {
  86. try {
  87. bis.close();
  88. } catch (IOException e) {
  89. e.printStackTrace();
  90. }
  91. }
  92. if (fis != null) {
  93. try {
  94. fis.close();
  95. } catch (IOException e) {
  96. e.printStackTrace();
  97. }
  98. }
  99. }
  100. }
  101. }
  102. return null;
  103. }
  104. //多文件上传
  105. @RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
  106. @ResponseBody
  107. public String handleFileUpload(HttpServletRequest request) {
  108. List<MultipartFile> files = ((MultipartHttpServletRequest) request)
  109. .getFiles("file");
  110. MultipartFile file = null;
  111. String fielPath = "C:/Users/Administrator/Desktop/";
  112. BufferedOutputStream stream = null;
  113. for (int i = 0; i < files.size(); ++i) {
  114. file = files.get(i);
  115. if (!file.isEmpty()) {
  116. try {
  117. byte[] bytes = file.getBytes();
  118. stream = new BufferedOutputStream(new FileOutputStream(
  119. new File(fielPath+file.getOriginalFilename())));
  120. stream.write(bytes);
  121. stream.close();
  122. } catch (Exception e) {
  123. stream = null;
  124. return "You failed to upload " + i + " => "
  125. + e.getMessage();
  126. }
  127. } else {
  128. return "You failed to upload " + i
  129. + " because the file was empty.";
  130. }
  131. }
  132. return "upload successful";
  133. }
  134. }

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>Getting Started: Serving Web Content</title>
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  6. </head>
  7. <body>
  8. <p>Get your greeting <a href="/greeting">here</a></p>
  9. <form action="/upload" method="POST" enctype="multipart/form-data">
  10. 文件:<input type="file" name="test"/>
  11. <input type="submit" />
  12. </form>
  13. <a href="/download">下载test</a>
  14. <p>多文件上传</p>
  15. <form method="POST" enctype="multipart/form-data" action="/batch/upload">
  16. <p>文件1:<input type="file" name="file" /></p>
  17. <p>文件2:<input type="file" name="file" /></p>
  18. <p><input type="submit" value="上传" /></p>
  19. </form>
  20. </html>

框架对文件上传的大小做了限制,可以通过在application.properties文件添加自定义的大小

  1. spring.servlet.multipart.max-file-size=20000MB
  2. spring.servlet.multipart.max-request-size=20000MB

十一、SpringbootRedisCache缓存

1、启动类Application.java需要加上注解@EnableCaching开启缓存

2、Cache的几个注解的含义:

  1. @Cacheable(value = "value",key="#user.id",condition="#user.id%2==0")当该注解在一个方法上使用时,会将该方法的返回值存储到起来,当下次再次调用的时候,不会再执行方法,而是将方法的返回值从缓存中取出使用,因为Spring储存缓存都是以键值对的方式进行储存的value相当于储存时的keykey属性是用来指定Spring缓存方法的返回结果时对应的key的。condition对缓存的对象进行限制,满足条件为true时,才进行缓存。
  2. @CachePut注解无论如何都会始终执行方法,然后将返回的数据进行缓存,其属性与@Cacheable注解方法属性一致。
  3. @CacheEvict是用来清除缓存的,与@Cacheable属性一致,另外有allEntriesbeforeInvocation两个属性allEntries是Boolean属性,默认为false当为true时会将所有的缓存清空。由于allEntries是方法执行成功时才会执行,相对的当方法报错时不会执行,所以beforeInvocationtrue时清空缓存的操作会在方法执行之前执行。
  4. @Caching(cacheable = @Cacheable("users"), evict={@CacheEvict("cache2"), @CacheEvict(value = "cache3", allEntries = true) })@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

3、在application.properties配置redis链接

  1. # REDIS (RedisProperties)
  2. # Redis数据库索引(默认为0
  3. spring.redis.database=0
  4. # Redis服务器地址
  5. spring.redis.host=192.168.133.111
  6. # Redis服务器连接端口
  7. spring.redis.port=6379
  8. # Redis服务器连接密码(默认为空)
  9. spring.redis.password=
  10. # 连接池最大连接数(使用负值表示没有限制)
  11. #多线程情况下是非线程安全的
  12. #spring.redis.jedis.pool.max-active=
  13. #多线程情况下是线程安全的
  14. spring.redis.lettuce.pool.max-active=8
  15. # 连接池最大阻塞等待时间(使用负值表示没有限制)
  16. spring.redis.lettuce.pool.max-wait=-1ms
  17. # 连接池中的最大空闲连接
  18. spring.redis.lettuce.pool.max-idle=8
  19. # 连接池中的最小空闲连接
  20. spring.redis.lettuce.pool.min-idle=0
  21. # 连接超时时间(毫秒)
  22. spring.redis.timeout=5000ms

4、pom依赖

  1. <!--Springboot Redis-->
  2. <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-data-redis</artifactId>
  6. <version>2.0.2.RELEASE</version>
  7. </dependency>

5、示例代码

  1. package com.example.controller;
  2. import com.example.dao.UserRepository;
  3. import com.example.demo.User;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  6. import org.springframework.cache.annotation.CachePut;
  7. import org.springframework.cache.annotation.Cacheable;
  8. import org.springframework.cache.annotation.EnableCaching;
  9. import org.springframework.data.redis.core.RedisTemplate;
  10. import org.springframework.data.redis.core.ValueOperations;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RestController;
  13. @RestController
  14. @EnableAutoConfiguration
  15. //@EnableCaching
  16. public class RedisController {
  17. @Autowired
  18. private UserRepository userRepository;
  19. @Autowired
  20. private RedisTemplate redisTemplate;
  21. public ValueOperations<String, User> getValueOperations() {
  22. return redisTemplate.opsForValue();
  23. }
  24. @RequestMapping("User")
  25. @Cacheable(value = "getUser")
  26. public Object getUser(User aa){
  27. User user = getValueOperations().get("aa");
  28. System.out.println("out --------------------------");
  29. System.out.println(user);
  30. return user;
  31. }
  32. @RequestMapping("SaveAA")
  33. public Object save(){
  34. getValueOperations().set("aa",new User("aa","bb","cc","dd","ee"));
  35. System.out.println("SUCCESS");
  36. return "SUCCESS";
  37. }
  38. }

十二、SpringRedisSession 的Session共享

1、pom依赖

  1. <dependency>
  2. <groupId>org.springframework.session</groupId>
  3. <artifactId>spring-session-data-redis</artifactId>
  4. </dependency>

2、注解配置

  1. @Configuration
  2. @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
  3. public class SessionConfig {
  4. }
  1. maxInactiveIntervalInSeconds: 设置Session失效时间,使用Redis Session之后,原Bootserver.session.timeout属性不再生效

3、测试代码

  1. @RequestMapping("/uid")
  2. String uid(HttpSession session){
  3. UUID uid = (UUID) session.getAttribute("uid");
  4. if(uid == null){
  5. uid = UUID.randomUUID();
  6. }
  7. session.setAttribute("uid",uid);
  8. return session.getId();
  9. }

当该接口被访问时会在redis数据库储存如下数据

  1. 127.0.0.1:6379> keys *session*
  2. 1) "spring:session:expirations:1529562420000"//session失效时间
  3. 2) "spring:session:sessions:a7b08ae6-667c-4b9d-bd10-456b203da2b8"//是sessionID
  4. 3) "spring:session:sessions:expires:a7b08ae6-667c-4b9d-bd10-456b203da2b8"

实现共享的方法就是在另一个项目中链接同一个redis服务器进行相同的配置即可实现Session共享。

十三、SpringbootMybatis使用@注解实现 转载自纯洁的微笑

1、pom依赖

  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>1.3.1</version>
  5. </dependency>

2、application.properties配置

  1. mybatis.type-aliases-package=com.neo.entity
  2. spring.datasource.driverClassName = com.mysql.jdbc.Driver
  3. spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
  4. spring.datasource.username = root
  5. spring.datasource.password = root

3、@MapperScan @Mapper

如果未在启动类(Application.java)配置@MapperScan("com.example.Mapper"),就需要在每一个Mepper类上加@Mapper注解

4、DAO的示例

  1. package com.example.Mapper;
  2. import com.example.demo.User;
  3. import org.apache.ibatis.annotations.*;
  4. import java.util.List;
  5. public interface UserMapper {
  6. @Select("Select * from user")
  7. @Results({//peoperty代表实体类的属性名,column代表字段名
  8. //当实体类的属性与对应的字段名不同时需要使用该注解@Results
  9. @Result(property = "nickName",column = "nick_name"),
  10. @Result(property = "passWord",column = "pass_word"),
  11. @Result(property = "regTime",column = "reg_time"),
  12. @Result(property = "userName",column = "user_name")
  13. })
  14. List<User> getAll();
  15. @Results({
  16. @Result(property = "nickName",column = "nick_name"),
  17. @Result(property = "passWord",column = "pass_word"),
  18. @Result(property = "regTime",column = "reg_time"),
  19. @Result(property = "userName",column = "user_name")
  20. })
  21. @Select("Select * from user where id = #{id}")
  22. User getUser(int id );
  23. @Insert("insert into user(email,nick_name,pass_word,reg_time,user_name) values(" +
  24. "#{email},#{nickName},#{passWord},#{regTime},#{userName})")
  25. int saveUser(User user);
  26. @Update("update user set email=#{email},nick_name=#{nickName},pass_word=#{passWord},reg_time=#{regTime}," +
  27. "user_name=#{userName} where id = #{id}")
  28. int updateUser(User user);
  29. @Delete("DELETE from user where id = #{id}")
  30. void DeleteUser(Long id);
  31. }
  1. @Select 是查询类的注解,所有的查询均使用这个
  2. @Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
  3. @Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
  4. @Update 负责修改,也可以直接传入对象
  5. @delete 负责删除

5、controller对应的示例

  1. package com.example.controller;
  2. import com.example.Mapper.UserMapper;
  3. import com.example.demo.User;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import java.util.List;
  8. @RestController
  9. @RequestMapping("/user")
  10. public class UserMapperController {
  11. @Autowired
  12. private UserMapper userMapper;
  13. @RequestMapping("/selectAll")
  14. public List<User> selectAll() {
  15. return userMapper.getAll();
  16. }
  17. @RequestMapping("/selectOne")
  18. public User selectOne(int id) {
  19. return userMapper.getUser(id);
  20. }
  21. @RequestMapping("/saveUser")
  22. public String saveUser(User user) {
  23. return userMapper.saveUser(user) > 0 ? "SUCCESS" : "FFFFFFF";
  24. }
  25. @RequestMapping("/updateUser")
  26. public String updateUser(User user) {
  27. return userMapper.updateUser(user) > 0 ? "SUCCESS" : "FFFFFFF";
  28. }
  29. @RequestMapping("/deleteUser")
  30. public String deleteUser(Long id){
  31. userMapper.DeleteUser(id);
  32. return "SUCCESS";
  33. }
  34. }

十四、SpringbootMybatis使用XML配置实现跳转该处————》纯洁的微笑

1、pom文件和上个版本一样,只是application.properties新增以下配置

  1. mybatis.config-locations=classpath:mybatis/mybatis-config.xml
  2. mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

mybatis-config.xml 配置

  1. <configuration>
  2. <typeAliases>
  3. <typeAlias alias="Integer" type="java.lang.Integer" />
  4. <typeAlias alias="Long" type="java.lang.Long" />
  5. <typeAlias alias="HashMap" type="java.util.HashMap" />
  6. <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
  7. <typeAlias alias="ArrayList" type="java.util.ArrayList" />
  8. <typeAlias alias="LinkedList" type="java.util.LinkedList" />
  9. </typeAliases>
  10. </configuration>

添加User的映射文件

  1. <mapper namespace="com.neo.mapper.UserMapper" >
  2. <resultMap id="BaseResultMap" type="com.neo.entity.UserEntity" >
  3. <id column="id" property="id" jdbcType="BIGINT" />
  4. <result column="userName" property="userName" jdbcType="VARCHAR" />
  5. <result column="passWord" property="passWord" jdbcType="VARCHAR" />
  6. <result column="user_sex" property="userSex" javaType="com.neo.enums.UserSexEnum"/>
  7. <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
  8. </resultMap>
  9. <sql id="Base_Column_List" >
  10. id, userName, passWord, user_sex, nick_name
  11. </sql>
  12. <select id="getAll" resultMap="BaseResultMap" >
  13. SELECT
  14. <include refid="Base_Column_List" />
  15. FROM users
  16. </select>
  17. <select id="getOne" parameterType="java.lang.Long" resultMap="BaseResultMap" >
  18. SELECT
  19. <include refid="Base_Column_List" />
  20. FROM users
  21. WHERE id = #{id}
  22. </select>
  23. <insert id="insert" parameterType="com.neo.entity.UserEntity" >
  24. INSERT INTO
  25. users
  26. (userName,passWord,user_sex)
  27. VALUES
  28. (#{userName}, #{passWord}, #{userSex})
  29. </insert>
  30. <update id="update" parameterType="com.neo.entity.UserEntity" >
  31. UPDATE
  32. users
  33. SET
  34. <if test="userName != null">userName = #{userName},</if>
  35. <if test="passWord != null">passWord = #{passWord},</if>
  36. nick_name = #{nickName}
  37. WHERE
  38. id = #{id}
  39. </update>
  40. <delete id="delete" parameterType="java.lang.Long" >
  41. DELETE FROM
  42. users
  43. WHERE
  44. id =#{id}
  45. </delete>
  46. </mapper>

DAO层

  1. public interface UserMapper {
  2. List<UserEntity> getAll();
  3. UserEntity getOne(Long id);
  4. void insert(UserEntity user);
  5. void update(UserEntity user);
  6. void delete(Long id);
  7. }

定时任务

一、定时任务

1、配置

在启动类加注解@EnableScheduling
pom依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-test</artifactId>
  8. <scope>test</scope>
  9. </dependency>

十五、Actuator运行状态监控

  1. management:
  2. server:
  3. port: 9001 #配置端口号
  4. endpoints:
  5. web:
  6. exposure:
  7. include: '*' #开放API,可以获取到信息

2、代码示例

  1. package com.example.exe;
  2. import org.springframework.scheduling.annotation.Scheduled;
  3. import org.springframework.stereotype.Component;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. @Component
  7. public class Scheduler2TaskTime {
  8. private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
  9. @Scheduled(fixedRate = 6000)
  10. public void reportCurrentTime() {
  11. System.out.println("现在时间:" + dateFormat.format(new Date()));
  12. }
  13. }
  14. package com.example.exe;
  15. import org.springframework.scheduling.annotation.Scheduled;
  16. import org.springframework.stereotype.Component;
  17. @Component
  18. public class SchedulerTaskTime {
  19. private int count=0;
  20. @Scheduled(cron="*/6 * * * * ?")
  21. private void process(){
  22. System.out.println("this is scheduler task runing "+(count++));
  23. }
  24. }

3、输出

  1. this is scheduler task runing 0
  2. 现在时间:15:06:44
  3. this is scheduler task runing 1
  4. 现在时间:15:06:50
  5. this is scheduler task runing 2
  6. 现在时间:15:06:56
  7. this is scheduler task runing 3
  8. 现在时间:15:07:02
  9. this is scheduler task runing 4
  10. 现在时间:15:07:08
  11. this is scheduler task runing 5
  12. 现在时间:15:07:14

4、参数说明

  1. @Scheduled 参数可以接受两种定时的设置,一种是我们常用的cron="*/6 * * * * ?",一种是 fixedRate = 6000,两种都表示每隔六秒打印一下内容。
  2. fixedRate 说明
  3. @Scheduled(fixedRate = 6000) :上一次开始执行时间点之后6秒再执行
  4. @Scheduled(fixedDelay = 6000) :上一次执行完毕时间点之后6秒再执行
  5. @Scheduled(initialDelay=1000, fixedRate=6000) :第一次延迟1秒后执行,之后按fixedRate的规则每6秒执行一次

5、问题

该方法默认使用单线程,多个微服务时需要加配置ThreadPoolTaskScheduler??quartz??分布式锁了解下??

6、cron表达式转化网站

二、MongoDB+Springboot的配置使用

1、pom依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-mongodb</artifactId>
  5. </dependency>
  6. </dependencies>

2、application.properties的配置

  1. #MongoDB配置
  2. spring.data.mongodb.uri=mongodb://renwb:123456@192.168.133.111:27017/test
  3. #renwb:代表链接的账户
  4. #123456:代表密码

3、测试实体类

  1. package com.example.demo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import java.io.Serializable;
  6. @Data
  7. @NoArgsConstructor
  8. @AllArgsConstructor
  9. public class MongoDBUser implements Serializable {
  10. private Long id;
  11. private String userName;
  12. private String passWord;
  13. }

4、DAO层

  1. package com.example.dao;
  2. import com.example.demo.MongoDBUser;
  3. import com.mongodb.client.result.DeleteResult;
  4. import org.junit.jupiter.api.Test;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.data.mongodb.MongoDbFactory;
  7. import org.springframework.data.mongodb.core.MongoTemplate;
  8. import org.springframework.data.mongodb.core.query.Criteria;
  9. import org.springframework.data.mongodb.core.query.Query;
  10. import org.springframework.data.mongodb.core.query.Update;
  11. import org.springframework.stereotype.Component;
  12. @Component
  13. public class MongoDBUserDAO {
  14. @Autowired
  15. private MongoTemplate mongoTemplate;
  16. public void testSaveUser(MongoDBUser mongoDBUser){
  17. mongoTemplate.save(mongoDBUser);
  18. }
  19. public MongoDBUser findUser(String userName){
  20. Query query = new Query(Criteria.where("userName").is(userName));
  21. MongoDBUser mongoDBUser = mongoTemplate.findOne(query,MongoDBUser.class);
  22. return mongoDBUser;
  23. }
  24. public void updateUser(MongoDBUser mongoDBUser){
  25. Query query = new Query(Criteria.where("id").is(mongoDBUser.getId()));
  26. Update update = new Update().set("userName",mongoDBUser.getUserName()).set("password",mongoDBUser.getPassWord());
  27. mongoTemplate.updateFirst(query,update,MongoDBUser.class);
  28. }
  29. public void deleteUserById(Long id){
  30. Query query = new Query(Criteria.where("id").is(id));
  31. //mongoTemplate.remove(query); 这个方法不可用会报错
  32. DeleteResult deleteResult = mongoTemplate.remove(query,MongoDBUser.class,"mongoDBUser");
  33. //System.out.println("这是什么 ? " + DeleteResult.unacknowledged().getDeletedCount());
  34. }
  35. }

5、测试类

  1. package test.MongoDBTest;
  2. import com.example.Application;
  3. import com.example.dao.MongoDBUserDAO;
  4. import com.example.demo.MongoDBUser;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.boot.test.context.SpringBootTest;
  9. import org.springframework.test.context.junit4.SpringRunner;
  10. @RunWith(SpringRunner.class)
  11. @SpringBootTest(classes = Application.class)
  12. public class MongoDBTest {
  13. @Autowired
  14. private MongoDBUserDAO mongoDBUserDAO;
  15. @Test
  16. public void TestMongoDB(){
  17. MongoDBUser user = new MongoDBUser(233L,"老明","123456");
  18. mongoDBUserDAO.testSaveUser(user);
  19. System.out.println("第一次查询 :" + mongoDBUserDAO.findUser("老明"));
  20. MongoDBUser user1 = new MongoDBUser(233L,"老红","654321");;
  21. mongoDBUserDAO.updateUser(user1);
  22. System.out.println("第二次查询 :" + mongoDBUserDAO.findUser("老红"));
  23. mongoDBUserDAO.deleteUserById(233L);
  24. System.out.println("第三次查询 :" + mongoDBUserDAO.findUser("老红"));
  25. }
  26. }

6、结果

  1. 2018-06-08 16:59:32.773 INFO 6692 --- [ main] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:125}] to 192.168.133.111:27017
  2. 第一次查询 MongoDBUser(id=233, userName=老明, passWord=123456)
  3. 第二次查询 MongoDBUser(id=233, userName=老红, passWord=123456)
  4. 第三次查询 null

三、yml文件的使用

1、application.yml的内容

  1. mongodb:
  2. primary:
  3. host: 192.168.133.111
  4. port: 27017
  5. database: test
  6. secondary:
  7. host: 192.168.133.111
  8. port: 27017
  9. database: test1

2、对应的实体类

  1. package com.example.config;
  2. import lombok.Data;
  3. import org.springframework.boot.autoconfigure.mongo.MongoProperties;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.stereotype.Component;
  6. @Data
  7. @Component
  8. @ConfigurationProperties(prefix = "mongodb")
  9. public class MultipleMongoProperties {
  10. private MongoProperties primary = new MongoProperties();
  11. private MongoProperties secondary = new MongoProperties();
  12. }

Mybatis 多数据源配置参考至纯洁的微笑

1、application.properties的配置

  1. #主数据库
  2. spring.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
  3. spring.datasource.ds1.username=root
  4. spring.datasource.ds1.password=root
  5. spring.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
  6. #从数据库
  7. #由于Spring Boot2.0 使用 HikariCP 作为默认的连接池 它使用的是jdbc-url,所以不是spring.datasource.ds2.url
  8. spring.datasource.ds2.jdbc-url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
  9. spring.datasource.ds2.username=root
  10. spring.datasource.ds2.password=root
  11. spring.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver

2、注解实现配置

主数据配置

  1. package com.example.config;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring.SqlSessionTemplate;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.boot.context.properties.ConfigurationProperties;
  8. import org.springframework.boot.jdbc.DataSourceBuilder;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.context.annotation.Primary;
  12. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  13. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  14. import javax.sql.DataSource;
  15. import java.io.IOException;
  16. //主数据配置
  17. @Configuration
  18. @MapperScan(basePackages = "com.example.Mapper.Test1",sqlSessionTemplateRef = "test1SqlSessionTemplate")
  19. public class DataSourceConfig {
  20. @Bean(name = "test1DataSource")
  21. @ConfigurationProperties(prefix = "spring.datasource.ds1")
  22. @Primary//该注解表示这个是主数据库,是默认的数据库
  23. public DataSource testDataSource(){
  24. return DataSourceBuilder.create().build();
  25. }
  26. @Bean(name = "test1SqlSessionFactory")
  27. @Primary
  28. public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource")DataSource dataSource) throws Exception {
  29. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  30. bean.setDataSource(dataSource);//注意配置文件应在resource包下,否则IDEA是不会将Java包下的配置文件编译到项目里去!!!!!
  31. bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:Hibernate/Test1/*.xml"));
  32. return bean.getObject();
  33. }
  34. @Bean("transactionManager")//这个名字是好像是固定的 如果不是这个编译时会报错
  35. @Primary
  36. public DataSourceTransactionManager testDataSourceTranscationManage(@Qualifier("test1DataSource")DataSource dataSource){
  37. return new DataSourceTransactionManager(dataSource);
  38. }
  39. //这个name应与该类上@MapperScan(sqlSessionTemplateRef = "test1SqlSessionTemplate")一样
  40. @Bean(name = "test1SqlSessionTemplate")
  41. @Primary
  42. public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
  43. return new SqlSessionTemplate(sqlSessionFactory);
  44. }
  45. }

从数据库配置

  1. package com.example.config;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring.SqlSessionTemplate;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.boot.context.properties.ConfigurationProperties;
  8. import org.springframework.boot.jdbc.DataSourceBuilder;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.context.annotation.Primary;
  12. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  13. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  14. import javax.sql.DataSource;
  15. import java.io.IOException;
  16. @Configuration//这个相当于xml里的<beans>标签
  17. @MapperScan(basePackages = "com.example.Mapper.Test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
  18. public class DataSourceConfig2 {
  19. @Bean(name = "test2DataSource")
  20. @ConfigurationProperties(prefix = "spring.datasource.ds2")
  21. public DataSource testDataSource() {
  22. return DataSourceBuilder.create().build();
  23. }
  24. @Bean(name = "test2SqlSessionFactory")//这个注解是<bean>标签
  25. public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
  26. SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
  27. bean.setDataSource(dataSource);
  28. bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:Hibernate/Test2/*.xml"));
  29. return bean.getObject();
  30. }
  31. @Bean("test2TransactionManager")
  32. public DataSourceTransactionManager testDataSourceTranscationManage(@Qualifier("test2DataSource") DataSource dataSource) {
  33. return new DataSourceTransactionManager(dataSource);
  34. }
  35. @Bean(name = "test2SqlSessionTemplate")
  36. public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  37. return new SqlSessionTemplate(sqlSessionFactory);
  38. }
  39. }

3、主数据库的查询map.xml配置

  1. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  2. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.example.Mapper.Test1.Test1Mapper">
  4. <resultMap id="BaseResultMap" type="com.example.demo.User">
  5. <id column="id" property="id" jdbcType="BIGINT"/>
  6. <result column="user_name" property="userName"/>
  7. <result property="passWord" column="pass_word"/>
  8. <result property="email" column="email"/>
  9. <result property="nickName" column="nick_name"/>
  10. <result property="regTime" column="reg_time"/>
  11. </resultMap>
  12. <sql id="allSql">
  13. id,user_name,pass_word,email,nick_name,reg_time
  14. </sql>
  15. <select id="getAll" resultMap="BaseResultMap">
  16. SELECT
  17. <include refid="allSql"/>
  18. FROM USER
  19. </select>
  20. </mapper>

3、从数据库的查询map.xml配置

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.example.Mapper.Test2.Test2Mapper">
  4. <resultMap id="BaseResultMap" type="com.example.demo.User">
  5. <id column="id" property="id" jdbcType="BIGINT"/>
  6. <result column="user_name" property="userName"/>
  7. <result property="passWord" column="pass_word"/>
  8. <result property="email" column="email"/>
  9. <result property="nickName" column="nick_name"/>
  10. <result property="regTime" column="reg_time"/>
  11. </resultMap>
  12. <sql id="allSql">
  13. user_name,pass_word,email,nick_name,reg_time
  14. </sql>
  15. <select id="saveUser" parameterType="com.example.demo.User">
  16. INSERT
  17. INTO
  18. USER
  19. (<include refid="allSql"/>)
  20. VALUES
  21. (#{userName},#{passWord},#{email},#{nickName},#{regTime})
  22. </select>
  23. </mapper>

4、主数据库的map.java代码示例

  1. package com.example.Mapper.Test1;
  2. import com.example.demo.User;
  3. import org.springframework.stereotype.Service;
  4. import java.util.List;
  5. @Service
  6. public interface Test1Mapper {
  7. List<User> getAll();
  8. }

4、从数据库的map.java代码示例

  1. package com.example.Mapper.Test2;
  2. import com.example.demo.User;
  3. import org.springframework.stereotype.Service;
  4. import java.util.List;
  5. @Service
  6. public interface Test2Mapper {
  7. void saveUser(User user);
  8. }

5、对IDEA不编译src下的配置文件解决的方法

pom文件添加如下代码

  1. <build>
  2. <resources>
  3. <resource>
  4. <directory>src/main/java</directory>
  5. <includes>
  6. <include>**/*.xml</include>
  7. </includes>
  8. </resource>
  9. </resources>
  10. </build>

RabbitMQ

一、pom依赖

  1. <!--消息队列RabbitMQ-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-amqp</artifactId>
  5. </dependency>

二、application.properties配置

  1. #RabbitMQ配置
  2. spring.application.name=spirng-boot-rabbitmq
  3. spring.rabbitmq.host=192.168.133.111
  4. #注意端口号web端访问MQ时端口号为 15672 程序访问时为 5672
  5. spring.rabbitmq.port=5672
  6. spring.rabbitmq.username=admin
  7. spring.rabbitmq.password=123456
  8. spring.rabbitmq.connection-timeout=10000ms

三、Java代码示例

1、config信息

  1. package com.example.config;
  2. import org.springframework.amqp.core.Queue;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. @Configuration
  6. public class RabbitMQConfig {
  7. @Bean
  8. public Queue queue(){
  9. return new Queue("hello");
  10. }
  11. @Bean
  12. public Queue queue1(){
  13. return new Queue("hello1");
  14. }
  15. @Bean
  16. public Queue queue2(){
  17. return new Queue("hello2");
  18. }
  19. }

2、生产者示例代码

  1. package com.example.exe;
  2. import com.example.demo.Student;
  3. import com.example.demo.config;
  4. import org.springframework.amqp.core.AmqpTemplate;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Component;
  7. import java.util.Date;
  8. @Component
  9. public class HelloSender {
  10. @Autowired
  11. private AmqpTemplate amqpTemplate;
  12. public void send(Student student){
  13. String conetxt = "hello" + new Date();
  14. System.out.println("Sender : " + conetxt);
  15. this.amqpTemplate.convertAndSend("hello",student);
  16. }
  17. public void oneToMany(){
  18. config config1 = new config();
  19. config1.setIp("10.10.1.1");
  20. config1.setPort(255);
  21. for (int i = 0; i < 100 ; i++){
  22. this.amqpTemplate.convertAndSend("hello",config1);
  23. this.amqpTemplate.convertAndSend("hello1","message ------ " + i);
  24. }
  25. }
  26. }

3、消费者示例代码

  1. package com.example.exe;
  2. import com.example.demo.Student;
  3. import com.example.demo.config;
  4. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  5. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  6. import org.springframework.stereotype.Component;
  7. @Component
  8. @RabbitListener(queues = "hello")//单个信道声明的格式
  9. public class HelloReceiver {
  10. public int count;
  11. @RabbitHandler//如果生产者发送的是对象的换,消费者形参要是同类型
  12. public void process(Student hello){
  13. count++;
  14. System.out.println(this.getClass().getName()+" hello接收到的消息 " + hello);
  15. System.out.println(this.getClass().getName()+" hello接收到了"+ hello+"条消息的消息 " );
  16. System.out.println();
  17. }
  18. }
  19. package com.example.exe;
  20. import com.example.demo.Student;
  21. import com.example.demo.config;
  22. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  23. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  24. import org.springframework.stereotype.Component;
  25. @Component
  26. @RabbitListener(queues = {"hello","hello1"})//多个信道的声明方式
  27. public class HelloReceiver2 {
  28. public int count;
  29. @RabbitHandler
  30. public void process(Student hello){
  31. count++;
  32. System.out.println(this.getClass().getName()+" 接收到的消息 " + hello);
  33. System.out.println(this.getClass().getName()+" 接收到了"+ hello+"条消息的消息 " );
  34. System.out.println();
  35. }
  36. }

4、Topic Exchange

topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列*
1)、TopicConfigBean

  1. package com.example.config;
  2. import org.springframework.amqp.core.*;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. @Configuration
  6. public class TopicRabbitConfig {
  7. final static String MESSAGE = "topic.message";
  8. final static String MESSAGES = "topic.messages";
  9. @Bean
  10. public Queue queueMessage() {
  11. return new Queue(TopicRabbitConfig.MESSAGE);
  12. }
  13. @Bean
  14. public Queue queueMessages() {
  15. return new Queue(TopicRabbitConfig.MESSAGES);
  16. }
  17. @Bean
  18. public Exchange exchange() {
  19. return new TopicExchange("exchange");
  20. }
  21. @Bean
  22. public Exchange exchange1() {
  23. return new TopicExchange("exchange1");
  24. }
  25. @Bean
  26. Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
  27. return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
  28. }
  29. @Bean
  30. Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange1) {
  31. return BindingBuilder.bind(queueMessages).to(exchange1).with("topic.messages");
  32. }
  33. }

2)、Topic生产者

  1. public void send1() {
  2. String context = "hi, i am message 1";
  3. System.out.println("Sender : " + context);
  4. this.amqpTemplate.convertAndSend("exchange", "topic.message", context);
  5. }
  6. public void send2() {
  7. String context = "hi, i am messages 2";
  8. System.out.println("Sender : " + context);
  9. this.amqpTemplate.convertAndSend("exchange1", "topic.messages", context);
  10. }

3)、消费者

  1. package com.example.exe;
  2. import com.example.demo.Student;
  3. import com.example.demo.config;
  4. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  5. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  6. import org.springframework.stereotype.Component;
  7. @Component
  8. @RabbitListener(queues = {"topic.message"})
  9. public class HelloReceiver {
  10. public int count;
  11. @RabbitHandler
  12. public void process(String hello){
  13. count++;
  14. System.out.println(this.getClass().getName()+" hello接收到的消息 " + hello);
  15. System.out.println(this.getClass().getName()+" hello接收到了"+ hello+"条消息的消息 " );
  16. System.out.println();
  17. }
  18. }
  19. ----
  20. package com.example.exe;
  21. import com.example.demo.Student;
  22. import com.example.demo.config;
  23. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  24. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  25. import org.springframework.stereotype.Component;
  26. @Component
  27. @RabbitListener(queues = "topic.messages")
  28. public class HelloReceiver1 {
  29. public int count;
  30. @RabbitHandler
  31. public void process(String hello){
  32. count++;
  33. System.out.println(this.getClass().getName()+" helloOne接收到的消息 " + hello);
  34. System.out.println(this.getClass().getName()+" helloOne接收到了"+ hello+"条消息的消息 " );
  35. System.out.println();
  36. }
  37. }

4)、测试代码

  1. package test.RabbitMQTest;
  2. import com.example.Application;
  3. import com.example.demo.Student;
  4. import com.example.exe.HelloReceiver;
  5. import com.example.exe.HelloReceiver1;
  6. import com.example.exe.HelloReceiver2;
  7. import com.example.exe.HelloSender;
  8. import org.junit.Test;
  9. import org.junit.runner.RunWith;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.boot.test.context.SpringBootTest;
  12. import org.springframework.test.context.junit4.SpringRunner;
  13. @RunWith(SpringRunner.class)
  14. @SpringBootTest(classes = Application.class)
  15. public class RabbitMQTest {
  16. @Autowired
  17. private HelloSender helloSender;
  18. @Test
  19. public void hello() throws Exception{
  20. Student student = new Student("student","name");
  21. helloSender.send1();
  22. helloSender.send2();
  23. }
  24. }

5)、输出结果

  1. Sender : hi, i am message 1
  2. Sender : hi, i am messages 2
  3. com.example.exe.HelloReceiver1 helloOne接收到的消息 hi, i am messages 2
  4. com.example.exe.HelloReceiver1 helloOne接收到了hi, i am messages 2条消息的消息
  5. com.example.exe.HelloReceiver hello接收到的消息 hi, i am message 1
  6. com.example.exe.HelloReceiver hello接收到了hi, i am message 1条消息的消息

5、Fanout Exchange

Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。
1)、配置

  1. package com.example.config;
  2. import org.springframework.amqp.core.Binding;
  3. import org.springframework.amqp.core.BindingBuilder;
  4. import org.springframework.amqp.core.FanoutExchange;
  5. import org.springframework.amqp.core.Queue;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. @Configuration
  9. public class FanoutRabbitMQConfig {
  10. @Bean
  11. public Queue AMessage(){
  12. return new Queue("fanout.A");
  13. }
  14. @Bean
  15. public Queue BMessage(){
  16. return new Queue("fanout.B");
  17. }
  18. @Bean
  19. public Queue CMessage(){
  20. return new Queue("fanout.C");
  21. }
  22. @Bean
  23. FanoutExchange fanoutExchange(){
  24. return new FanoutExchange("fanoutExchange");
  25. }
  26. @Bean
  27. Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange){
  28. return BindingBuilder.bind(AMessage).to(fanoutExchange);
  29. }
  30. @Bean
  31. Binding bindingExchangeB(Queue BMessage,FanoutExchange fanoutExchange){
  32. return BindingBuilder.bind(BMessage).to(fanoutExchange);
  33. }
  34. @Bean
  35. Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange){
  36. return BindingBuilder.bind(CMessage).to(fanoutExchange);
  37. }
  38. }

2)、生产者

  1. public void sendFanout(){
  2. String context = "hi, fanout msg ";
  3. System.out.println("Sender : " + context);
  4. //订阅模式routing_key无需声明队列名,因为会被忽略
  5. this.amqpTemplate.convertAndSend("fanoutExchange","", context);
  6. }

3)、消费者

  1. package com.example.exe;
  2. import com.example.demo.Student;
  3. import com.example.demo.config;
  4. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  5. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  6. import org.springframework.stereotype.Component;
  7. @Component
  8. @RabbitListener(queues = "fanout.A")
  9. public class HelloReceiver {
  10. public int count;
  11. @RabbitHandler
  12. public void process(String hello){
  13. count++;
  14. System.out.println(this.getClass().getName()+" hello接收到的消息 " + hello);
  15. System.out.println(this.getClass().getName()+" hello接收到了"+ hello+"条消息的消息 " );
  16. System.out.println();
  17. }
  18. }
  19. package com.example.exe;
  20. import com.example.demo.Student;
  21. import com.example.demo.config;
  22. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  23. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  24. import org.springframework.stereotype.Component;
  25. @Component
  26. @RabbitListener(queues = "fanout.B")
  27. public class HelloReceiver1 {
  28. public int count;
  29. @RabbitHandler
  30. public void process(String hello){
  31. count++;
  32. System.out.println(this.getClass().getName()+" helloOne接收到的消息 " + hello);
  33. System.out.println(this.getClass().getName()+" helloOne接收到了"+ hello+"条消息的消息 " );
  34. System.out.println();
  35. }
  36. }
  37. package com.example.exe;
  38. import com.example.demo.Student;
  39. import com.example.demo.config;
  40. import org.springframework.amqp.rabbit.annotation.RabbitHandler;
  41. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  42. import org.springframework.stereotype.Component;
  43. @Component
  44. @RabbitListener(queues = {"fanout.C"})
  45. public class HelloReceiver2 {
  46. public int count;
  47. @RabbitHandler
  48. public void process(String hello){
  49. count++;
  50. System.out.println(this.getClass().getName()+" 接收到的消息 " + hello);
  51. System.out.println(this.getClass().getName()+" 接收到了"+ hello+"条消息的消息 " );
  52. System.out.println();
  53. }
  54. }

4)、输出

  1. com.example.exe.HelloReceiver1 helloOne接收到的消息 hi, fanout msg
  2. com.example.exe.HelloReceiver1 helloOne接收到了hi, fanout msg 条消息的消息
  3. com.example.exe.HelloReceiver hello接收到的消息 hi, fanout msg
  4. com.example.exe.HelloReceiver hello接收到了hi, fanout msg 条消息的消息
  5. com.example.exe.HelloReceiver2 接收到的消息 hi, fanout msg
  6. com.example.exe.HelloReceiver2 接收到了hi, fanout msg 条消息的消息

四、订阅模式更多注解配置可参考

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注