Springboot整合mybatis和Springcloud
一、Springcloud简介
1、Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
2、Spring cloud组成
Spring cloud的子项目大致分为两类,一类是对现有成熟框架Spring boot的封装和抽象,也是数量最多的项目;第二类是开发了一部分分布式系统的基础设施的实现,但是这种用的比较少,第一类对于我们想要实践微框架的开发者来说,第一种完全够了,如:
Spring Cloud Netflix
是对Netflix开发的一套分布式服务框架的封装,包括服务的发现和注册,负载均衡、断路器、REST客户端、请求路由等。
Spring Cloud Config
将配置信息中央化保存, 配置Spring Cloud Bus可以实现动态修改配置文件
Spring Cloud Bus
分布式消息队列,是对Kafka, MQ的封装
Spring Cloud Security
对Spring Security的封装,并能配合Netflix使用
Spring Cloud Zookeeper
对Zookeeper的封装,使之能配置其它Spring Cloud的子项目使用
Spring Cloud Eureka
Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件中的一部分,它基于Netflix Eureka 做了二次分装,主要负责完成微服务架构中的服务治理功能。
由于Spring cloud这个微框架是基于Spring boot框架的,我们先要了解Spring boot,下面我们介绍怎么搭建Spring boot这个框架。
二、Spring boot框架搭建
先建一个maven项目,在新建的maven项目的pom文件中添加如下的内容:
4.0.0
com.slinsoft
spring-mybatis
0.0.1-SNAPSHOT
war
org.springframework.boot
spring-boot-starter-parent
1.5.6.RELEASE
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
5.1.21
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-surefire-plugin
true
上面就是Spring boot的pom文件内容,完成pom文件之后,我们就来写一个小测试例子,看看我们的Spring boot是怎么工作的。
我们在新建工程的resource目录下新建一个application.properties配置文件,配置文件里面配置连接数据库的内容,如下:
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
既然有数据库的连接了,那么我们需要在数据库建立一张表,并且添加几条数据,为我们一会的测试用。
在main/Java目录下新建package,包名自己命名,在包下面创建一个entity,entity的属性自己根据数据库的内容定义,下面是我的entity以及一些属性,
public class User {
private int id;
private String name;
private int age;
get和set以及tostring方法自己生成
}
接下来我们创建一个接口类,也就是我们平时的dao:
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper {
User findUserByName(@Param(“name”)String name);
void update(@Param(“age”)int age,@Param(“name”)String name);
void insert(@Param(“id”)int id,@Param(“name”)Stringname,@Param(“age”)int age);
void delete(@Param(“name”)String name);
}
我这里命名为UserMapper,也可以是UserDao。在这里需要注意一下,看方法上面的@Mapper,在这里因为我使用了mapper文件来写SQL语句,所以在方法上添加了这个注解,还有一个办法是在启动类也就是application这个类上添加注解@MapperScan,作用是一样的,如果你有多个接口dao的话,后面一种会比较省事,因为只需要添加一次,但是注意,这两个注解只能使用一个,不能两个一起使用。在这里添加这个注解时需要我们需要在resource目录下创建mybatis-config.xml文件,文件内容如下:
update user set age = #{age} where name = #{name}
insert into user (
id,
name,
age
)values(
#{id},
#{name},
#{age}
)
delete from user where name = #{name}
这是把SQL语句写到mapper文件中的一种方式,还有一种方式是在每一个接口上添加注解,像下面的方法:
@Mapper
public interface UserMapper {
@Select(“select * from user where name = #{name}”)
User findUserByName(@Param(“name”)String name);
@Update("update user set age = #{age},name = #{name} where id = 1")
void update(@Param("age")int age,@Param("name")String name);
}
就是添加注解,然后把SQL语句写在注解后面,这种方法不用配置mybatis-config.xml文件,application配置文件中也不需要添加mapper文件的路径和mybatis-config的路径,只需要连接数据库的配置即可,但是这种方法适用于业务比较简单的程序,当业务比较复杂时,我建议还是使用mapper文件的形式。
和其他web程序一样,在接口完成之后就该写service和它的实现类了,但是我现在只是测试,业务比较简单,所以我把业务写在了controller,业务多的话要用service,这个和SpringMVC的service是一样的,没什么区别,我的controller类:
@RestController
@RequestMapping("/home")
public class UserController {
@Autowired
UserMapper userMapper;
@RequestMapping("/find")
@ResponseBody
public String User(){
User user = userMapper.findUserByName(“zhangsi”);
if(user != null){
return user.getName()+"—"+user.getAge();
}else{
return “查无此人!”;
}
@RequestMapping("/update")
@ResponseBody
public int update(){
userMapper.update(28, “zhangsi”);
return 1;
}
@RequestMapping("/insert")
@ResponseBody
public String insert(){
userMapper.insert(4, "zym", 24);
return "success";
}
@RequestMapping("/delete")
@ResponseBody
public String delete(){
userMapper.delete("zhangsi");
return "success";
}
}
只是一个简单的增删改查。最后我们写我们的启动类,也就是application类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
注解@SpringBootApplication不能丢,没有这个注解启动后什么也查不出来。
然后运行这个类,也就是启动,不需要我们去启动tomcat服务,它会自动启动。
启动不报错,并且出现Spring boot的版本说明Spring boot框架搭建成功。如下图所示:
图中的v1.5.6.RELEASE就是Spring boot的版本号。
启动成功后会在最后一行显示你的包名.Application,如图中hello.Application
都没有任何问题的话打开浏览器,在浏览器输入localhost:8080/你自己定义的路径。
像我的就是localhost:8080/home/find,这个路径是在controller中RequestMapping定义的。回车之后会在页面显示你想要的信息了。
三、Spring cloud服务注册发现实现
将服务注册到注册中心去,注册中心会不定时的检测每个项目是否正常运行或被注册,下面是实现步骤:
第一步:我们先创建注册中心
首先创建一个Spring boot应用(此项目采用eclipse+maven开发),先创建一个maven-project root父类便于版本控制。
此处需要注意的是packaging选择pom。然后在pom中添加Spring cloud基本应用包。
Pom.xml内容如下:
4.0.0
com.slinsoft
spring-cloud
0.0.1-SNAPSHOT
pom
org.springframework.cloud
spring-cloud-starter-config
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-config-server
spring-root org.springframework.boot spring-boot-maven-plugin repackage org.apache.maven.plugins maven-compiler-plugin utf-8 1.8 1.8 创建注册中心项目Spring-demo-register并且通过maven指定父类目录。 在刚创建的Spring-root项目上右键新建project,选择maven module,创建Spring-demo-register。 编写Spring-demo-register项目依赖添加文件pom.xml 4.0.0 com.slinsoft spring-cloud 0.0.1-SNAPSHOT spring-cloud-register org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-config-server 添加注册中心启动类以及配置Spring-boot配置.properties/.yaml文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190425200919436.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4Mzg0ODcy,size_16,color_FFFFFF,t_70)
启动类代码
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication //Spring-boot启动注解
@EnableEurekaServer //spring-cloud服务注解
public class Register {
public static void main(String[] args) {
SpringApplication.run(Register.class, args);
}
}
Application.yaml:
server:
port: 1111
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http:// e u r e k a . i n s t a n c e . h o s t n a m e : {eureka.instance.hostname}: eureka.instance.hostname:{server.port}/eureka/
完成这些之后启动启动类,浏览器访问localhost:1111
出现这个画面表示注册中心已经完成。
第二步 创建服务注册到注册中心
像上面一样创建一个maven module项目,命名为Spring-demo-a
配置Spring-demo-a的pom.xml文件
4.0.0
com.demo
spring-root
0.0.1-SNAPSHOT
spring-demo-a
org.springframework.cloud
spring-cloud-starter-eureka
添加注册启动类以及配置Spring-boot配置.properties/.yaml
PortalApplication.Java
package com;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient //Eureka Client
public class PortalApplication {
public static void main(String[] args) {
SpringApplication.run(PortalApplication.class, args)
}
}
Application.yaml
server:
port: 2222
spring:
application:
name: spring-cloud-portal
#注册中心指向start
eureka:
instance:
instance-id: spring-cloud-portal
appname: ${spring.application.name}
client:
service-url:
defaultZone: http://127.0.0.1:1111/eureka/
#注册中心指向end
需要注意的是defaultZone 我是在本地测试,因此需要先启动之前的注册中心,保证注册中心是可用的。再次启动PortalApplication,并且访问localhost:1111
我们会发现有一个服务被注册到注册中心。这只是一个服务注册到注册中心,想要多个服务的话创建新服务的步骤和创建Spring-demo-a完全一致。
等上面的工作全部完成而且不报错就开始最后的测试,先启动注册中心类的启动类(一定要先启动这个类,不然会报错,connected refused),然后依次启动其他注册类,因为我们在每个启动类的配置文件中都配置了不同的端口,所以想要检测是否成功,就要依次访问每一个端口,查看是否成功。下面就是我所访问的端口和成功时页面的信息。(注意:在访问页面前先启动数据库)
Localhost:2222/home/find
查出来数据库中的数据,表示成功。还有另外一个端口
Localhost:3333/home/update
实现了更新功能,我在程序中定义了返回1就是成功,在页面中也看到了,在这说明一下,这两个端口操作的数据库是同一个数据库,你也可以操作不同的数据库,只要在.properties文件中改变数据库的表名即可。
接下来我们停掉一个服务,看看对另一个服务有没有什么影响(注意:不要把注册中心的服务停掉,这些服务都注册在注册中心了,注册中心停掉,在注册中心注册的所有服务将全部停掉。)
我们先来停掉3333端口的服务,然后再访问2222端口,依然能够查出数据,但是访问3333的时候报错,服务没有起来,也就是拒绝连接,反之是一样的。也就是说2222端口的服务和3333端口的服务相互之间没有影响。