snjl

我大概率会编程。


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

springboot:mybatis多数据源

发表于 2018-12-03 | 分类于 springboot
字数统计: 805 字 | 阅读时长 ≈ 4 分钟

项目地址:https://github.com/snjl/springboot.mulidatasource.git

配置文件

数据库配置:

1
2
3
4
5
6
7
8
9
10
11
12
mybatis.config-locations=classpath:mybatis/mybatis-config.xml

spring.datasource.test1.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test1.url = jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true&zeroDateTimeBehavior=convertToNull
spring.datasource.test1.username = root
spring.datasource.test1.password = 123456


spring.datasource.test2.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test2.url = jdbc:mysql://localhost:3306/spring2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true&zeroDateTimeBehavior=convertToNull
spring.datasource.test2.username = root
spring.datasource.test2.password = 123456

一个test1库和一个test2库,其中test1位主库,在使用的过程中必须指定主库,不然会报错。

阅读全文 »

springboot:随机端口

发表于 2018-12-03 | 分类于 springboot
字数统计: 266 字 | 阅读时长 ≈ 1 分钟

为Spring Cloud的应用实用随机端口非常简单,主要有两种方法:

设置server.port=0,当应用启动的时候会自动的分配一个随机端口,但是该方式在注册到Eureka的时候会一个问题:所有实例都使用了同样的实例名(如:Lenovo-test:hello-service:0),这导致只出现了一个实例。所以,我们还需要修改实例ID的定义,让每个实例的ID不同,比如使用随机数来配置实例ID:

1
2
server.port=0
eureka.instance.instance-id=${spring.application.name}:${random.int}

除了上面的方法,实际上我们还可以直接使用random函数来配置server.port。这样就可以指定端口的取值范围,比如:

1
server.port=${random.int[10000,19999]}

由于默认的实例ID会由server.port拼接,而此时server.port设置的随机值会重新取一次随机数,所以使用这种方法的时候不需要重新定义实例ID的规则就能产生不同的实例ID了。

springboot:thymeleaf设置不校验html标签

发表于 2018-12-03 | 分类于 springboot
字数统计: 172 字 | 阅读时长 ≈ 1 分钟

默认配置下,thymeleaf对.html的内容要求很严格,比如,如果少封闭符号/,就会报错而转到错误页。也比如你在使用Vue.js这样的库,然后有

这样的html代码,也会被thymeleaf认为不符合要求而抛出错误。

通过设置thymeleaf模板可以解决这个问题,下面是具体的配置:

1
2
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5

LEGACYHTML5需要搭配一个额外的库NekoHTML才可用 项目中使用的构建工具是Maven添加如下的依赖即可完成:

1
2
3
4
5
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>

springboot:task定时任务(二)

发表于 2018-12-03 | 分类于 spring
字数统计: 333 字 | 阅读时长 ≈ 1 分钟

项目地址:https://github.com/snjl/springboot.springtask2.git

pom包配置

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

启动类启用定时

在启动类上面加上@EnableScheduling即可开启定时

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableScheduling
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

创建定时任务实现类

定时任务1:

1
2
3
4
5
6
7
8
9
10
11
@Component
public class SchedulerTask {

private int count=0;

@Scheduled(cron="*/6 * * * * ?")
private void process(){
System.out.println("this is scheduler task runing "+(count++));
}

}

定时任务2:

1
2
3
4
5
6
7
8
9
10
11
@Component
public class Scheduler2Task {

private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

@Scheduled(fixedRate = 6000)
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}

}

结果如下:

1
2
3
4
5
6
7
8
this is scheduler task runing  0
现在时间:09:44:17
this is scheduler task runing 1
现在时间:09:44:23
this is scheduler task runing 2
现在时间:09:44:29
this is scheduler task runing 3
现在时间:09:44:35

参数说明

@Scheduled 参数可以接受两种定时的设置,一种是我们常用的cron=”/6 * ?”,一种是 fixedRate = 6000,两种都表示每隔六秒打印一下内容。

fixeRate说明

  • @Scheduled(fixedRate = 6000) :上一次开始执行时间点之后6秒再执行
  • @Scheduled(fixedDelay = 6000) :上一次执行完毕时间点之后6秒再执行
  • @Scheduled(initialDelay=1000, fixedRate=6000) :第一次延迟1秒后执行,之后按fixedRate的规则每6秒执行一次

springboot:解决分页插件ClassNotFoundException

发表于 2018-12-02
字数统计: 834 字 | 阅读时长 ≈ 5 分钟

报错:

阅读全文 »

springboot:日期错误Zero date value prohibited 异常的解决方法

发表于 2018-12-02 | 分类于 springboot
字数统计: 104 字 | 阅读时长 ≈ 1 分钟

实际的错误还应该有:
java.sql.SQLException: Value ‘0000-00-00’ can not be represented as java.sql.Date

更改jdbc连接为:

1
jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull

即设置zeroDateTimeBehavior=convertToNull

设置zeroDateTimeBehavior 属性,当遇到DATETIME值完全由0组成时,最终的有效值可以设置为,异常(exception),一个近似值(round),或将这个值转换为null(convertToNull)。

使用convertToNull,返回null来替代0000-00-00这样的日期。

springboot:项目修改访问端口和访问路径

发表于 2018-12-02 | 分类于 springboot
字数统计: 175 字 | 阅读时长 ≈ 1 分钟

创建SpringBoot项目,启动后,默认的访问路径即主机IP+默认端口号8080。

修改端口号

使用properties文件方式:

在src/main/resoutces目录下创建:application.properties,添加如下配置即可修改端口号:

1
server.port=8088

使用yml文件方式:

在src/main/resoutces目录下创建:application.yml,添加如下配置即可修改端口号:

1
2
server:
port:8088

修改项目访问路径

使用properties文件方式:

在application.properties,添加如下配置即可修改项目访问路径:

1
server.servlet.context-path=/test

使用yml文件方式:

在src/main/resoutces目录下创建:application.yml,添加如下配置即可修改端口号:

1
2
3
4
server:
port:8088
servlet:
context-path:/test

springboot:报错Invalid CORS request, CORS 跨域请求设置

发表于 2018-12-02 | 分类于 springboot
字数统计: 426 字 | 阅读时长 ≈ 1 分钟

SpringBoot提供的跨域配置有两种,一种是全局的,一种是具体到方法的。如果同时配置了那么具体方法的优先。

全局跨域配置

提供一个自定义的WebMvcConfigurer bean,该bean的addCorsMappings方法中定义自己的跨域配置。
可以看到我的跨域配置是允许来自http://localhost:6677访问/user/users/*的方法。等程序运行后我们可以发现如果我们的前端使用http://127.0.0.1:6677 或者我们的前端运行在http://localhost:8080都无法通过rest访问对应的API(备注,示例程序提供了/user/users和/user/users/{userId}方法)

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
package com.yq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootApplication
public class CorsDemoApplication {

public static void main(String[] args) {
SpringApplication.run(CorsDemoApplication.class, args);
}

@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:6677");
}
};
}
}

此处,设置addMapping是设置访问路径(pathPattern—),设置了可以被跨域访问的路径和可以被哪些主机跨域访问,而不是设置包的路径。即包名为app.api.controller,但是controller里面的地址设置为/user/paper/,/user/user/,则这里应该写为/user/**。

具体方法的跨域配置@CrossOrigin

我们可以使用@CrossOrigin在具体的API上配置跨域设置。@CrossOrigin(origins = “http://localhost:9000”)表明该方法允许来自http://localhost:9000访问,也就是前端可以是localhost:9000。

1
2
3
4
5
6
7
@ApiOperation(value = "查询所有用户")
@CrossOrigin(origins = "http://localhost:9000")
@GetMapping(value = "/users", produces = "application/json;charset=UTF-8")
public Iterable<User> findAllUsers() {
Collection<User> users = userMap.values();
return users;
}

Spring Data JPA 与 MyBatis对比

发表于 2018-12-02 | 分类于 springboot
字数统计: 1.9k 字 | 阅读时长 ≈ 6 分钟

Spring Data JPA是Spring Data的子模块。使用Spring Data,使得基于“repositories”概念的JPA实现更简单和容易。Spring Data JPA的目标是大大简化数据访问层代码的编码。作为使用者,我们只需要编写自己的repository接口,接口中包含一些个性化的查询方法,Spring Data JPA将自动实现查询方法。
JPA默认使用hibernate作为ORM实现,所以,一般使用Spring Data JPA即会使用hibernate。我们再看看hibernate的官方概念,Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

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

这样看,Spring Data JPA与MyBatis对比,起始也就是hibernate与MyBatis对比。所以,我们直接来比较后两者。

从基本概念和框架目标上看,两个框架差别还是很大的。hibernate是一个自动化更强、更高级的框架,毕竟在java代码层面上,省去了绝大部分sql编写,取而代之的是用面向对象的方式操作关系型数据库的数据。而MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。所以,从表面上看,hibernate能方便、自动化更强,而MyBatis 在Sql语句编写方面则更灵活自由。

但这只是从使用层面上看两者的区别,并未涉及的本质。但如果看问题,值看浅层次、表象问题的话,就不能理解技术本质,也不能发挥技术的最多效用。所以,如果更上一个抽象层次去看,
对于数据的操作,hibernate是面向对象的,而MyBatis是面向关系的。
当然,用hibernate也可以写出面向关系代码和系统,但却得不到面向关系的各种好处,最大的便是编写sql的灵活性,同时也失去面向对象意义和好处——一句话,不伦不类。那么,面向对象和关系型模型有什么不同,体现在哪里呢?实际上两者要面对的领域和要解决的问题是根本不同的:面向对象致力于解决计算机逻辑问题,而关系模型致力于解决数据的高效存取问题。我们不妨对比一下面向对象的概念原则和关系型数据库的不同之处:

  1. 面向对象考虑的是对象的整个生命周期包括在对象的创建、持久化、状态的改变和行为等,对象的持久化只是对象的一种状态,而面向关系型数据库的概念则更关注数据的高效存储和读取;
  2. 面向对象更强调对象状态的封装性,对象封装自己的状态(或数据)不允许外部对象随意修改,只暴露一些合法的行为方法供外部对象调用;而关系型数据库则是开放的,可以供用户随意读取和修改关系,并可以和其他表任意的关联(只要sql正确允许的情况下);
  3. 面向对象试图为动态的世界建模,他要描述的是世界的过程和规律,进而适应发展和变化,面向对象总是在变化中处理各种各样的变化。而关系型模型为静态世界建模,它通过数据快照记录了世界在某一时候的状态,它是静态的。

从上面两者基本概念和思想的对比来看,可以得出结论hibernate和MyBatis两个框架的侧重点完全不同。所以我们就两个框架选择上,就需要根据不同的项目需求选择不同的框架。在框架的使用中,也要考虑考虑框架的优势和劣势,扬长避短,发挥出框架的最大效用,才能真正的提高项目研发效率、完成项目的目标。但相反,如果使用Spring Data JPA和hibernate等ORM的框架而没有以面向对象思想和方法去分析和设计系统,而是抱怨框架不能灵活操作sql查询数据,那就是想让狗去帮你拿耗子了。

那么,话题再说回来,使用两个框架时候的时候,也要注意最佳的步骤和流程。下面我们来分别讨论一下,hibernate的一般使用步骤如下:

  1. 分析、抽象和归纳出系统中的业务概念,并梳理出各个业务概念之间的关系——创建概念模型
  2. 根据概念模型,进一步细化设计系统中的对象类以及类的依赖关系——创建设计模型
  3. 将设计好的类映射到数据库的表和字段配置好
  4. hibernate可以根据配置信息自动生成数据库表,这个时候也可以集中精力去梳理一下表关系,看看表结构是否合理,并适当调整一下类和表的映射关系,重新生成表结构

完成以上步骤,基本上完成了体统中主要的业务概念类和表结构的设计工作,只是完成表结构设计的出发点事如何持久化系统的对象,同时兼顾数据库表、字段、字段类型、表的关联关系的合理性和合规性,而不是单纯表设计。这两者思考和关注点还是有很大差别的。另外,需要说明一点,这只是使用hibernate的最通用步骤,实际操作过程中还是需要根据具体项目情况来安排。

而MyBatis对于面向对象的概念强调比较少,更适用于灵活的对数据进行增、删、改、查,所以在系统分析和设计过程中,要最大的发挥MyBatis的效用的话,一般使用步骤则与hibernate有所区别:

  1. 综合整个系统分析出系统需要存储的数据项目,并画出E-R关系图,设计表结构
  2. 根据上一步设计的表结构,创建数据库、表
  3. 编写MyBatis的SQL 映射文件、Pojos以及数据库操作对应的接口方法

这样看来MyBatis更适合于面向关系(或面向数据、或面向过程)的系统设计方法,这样的系统一般称为“事务脚步”系统(事务脚步(Transaction Script) 出自Martin Fowler 2004年所著的企业应用架构模式(Patterns of Enterprise Application Architecture))。而hibernate(也可以说Spring Data JPA)更适合于构建领域模型类的系统。当然,我们也不能说MyBatis无法构建领域模型驱动的系统,而hibernate无法构建事务脚步系统。只是用MyBatis构建领域模型要做更多、跟脏、更累的工作;而用hibernate构建一个事务脚本系统有些大材小用,数据的查询反而没那么灵活。

参考:https://www.jianshu.com/p/3927c2b6acc0

java web项目中的dao,service层的接口的必要性

发表于 2018-12-01 | 分类于 理论
字数统计: 2.3k 字 | 阅读时长 ≈ 8 分钟

参考:https://www.jianshu.com/p/64abdd29bdf6

https://www.zhihu.com/question/36021012

DAO接口
为每个DAO声明接口的好处在于:

可以在尚未实现具体DAO的时候编写上层代码,如Service里对DAO的调用
可以为DAO进行多实现,例如有JDBCDAO实现,MyBatisDAO实现,而不需要更改上层代码,只需要简单的在Spring的IoC配置里修改一下注入的DAO实现

阅读全文 »
1…151617…21
snjl

snjl

越过山丘,才发现无人等候。

203 日志
44 分类
107 标签
RSS
GitHub E-Mail Weibo
© 2019 snjl
总访问量次 | 总访客人 |
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4