SpringCloud整合Mybatis做增删改查
一、springCloud简单介绍
springCloud是一套微服务解决方案,springCloud依赖于springBoot。他提供了微服务开发所需的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。最重要的是,跟spring boot框架一起使用的话,会让你开发微服务架构的云服务非常好的方便。 SpringBoot旨在简化创建产品级的 Spring 应用和服务,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能。
springCloud常用的六大组件
服务发现 —— Eureka
服务调用 —— Feign
服务熔断 —— Hystrix
负载均衡 —— Ribbon
服务网关 —— Zuul
分布式配置— Config
springCloud与dubbo的区别
Dubbo只实现了服务治理,而springCloud下面有N多个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面。
依上说的,Dubbo就像是SpringCloud下的一个子项目,但是也不是说springCloud中有的功能组件Dubbo就不能实现,只是Dubbo它自身不提供,需要另外整合来实现功能。
举个栗子,Dubbo就像是一太组装机,可以自由组装使用,而springCloud就像是一个名牌机器,自身高配齐全,也不能说Dubbo不好,它在高手手中使用起来还是好用的。
二、话不多说,上代码
首先创建一个springBoot项目,取名eureka
这里注意springCloud和springBoot版本要对应,这里用的是springBoot2.2.1.RELEASE,springCloud Hoxton.RELEASE,
eureka-server版本为2.2.0
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fz</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
<version>2.2.0.RELEASE</version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这个地方容易踩坑,尽量跟上面版本保持一致
Resources下创建application.yml
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka #设置服务注册中心地址
register-with-eureka: false #IP指定是服务器还是本机ip
server:
enable-self-preservation: false #是否将自己注册到服务中心
fetch-registry: false #是否开启服务发现
spring:
application:
name: eureka #服务名
server:
port: 8761 #端口号
springBoot启动类上加上注解 @EnableEurekaServer,启动项目
访问 http://localhost:8761
出现如下,就已经创建成功了
三、创建服务提供者 provider-one
创建数据库cloud,执行sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (3, '张三');
SET FOREIGN_KEY_CHECKS = 1;
创建application.properties
```yaml
spring.datasource.url=jdbc:mysql://localhost:3306/cloud?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.typeAliasesPackage=com.fz.providerone.entity
mybatis.mapperLocations=classpath:mapper/*.xml
server.port=8002
spring.application.name=provider-user
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
编写增删改查方法
实体类,
@Data //引入lombak依赖
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String username;
}
dao层
package com.fz.providerone.dao;
import com.fz.providerone.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface UserDao {
/**
* 新增用户
* @param user
*/
void createUser(User user);
/**
* 查询用户列表
* @return
*/
List<User> findAllUser();
/**
* 删除用户
* @param id
*/
void delUser(String id);
/**
* 修改用户
* @param user
*/
void updateUser(User user);
}
service
package com.fz.providerone.service;
import com.fz.providerone.entity.User;
import java.util.List;
public interface IUserService {
/**
* 新增用户
* @param user
*/
public void createUser(User user);
/**
* 查询用户列表
* @return
*/
public List<User> findAllUser();
/**
* 删除用户
* @param id
*/
void delUser(String id);
/**
* 修改用户
* @param user
*/
void updateUser(User user);
}
service实现
package com.fz.providerone.service.impl;
import com.fz.providerone.dao.UserDao;
import com.fz.providerone.entity.User;
import com.fz.providerone.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Component
public class UserServiceImpl implements IUserService {
@Autowired
UserDao userDao;
@Override
public void createUser(User user) {
userDao.createUser(user);
}
@Override
public List<User> findAllUser() {
return userDao.findAllUser();
}
@Override
public void delUser(String id) {
userDao.delUser(id);
}
@Override
public void updateUser(User user) {
userDao.updateUser(user);
}
}
Controller
package com.fz.providerone.controller;
import com.fz.providerone.entity.User;
import com.fz.providerone.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
IUserService service;
@RequestMapping("/userList")
public List getUserList(){
return service.findAllUser();
}
@RequestMapping("/add")
public String addUser(@RequestBody User user){
if (user!=null) {
service.createUser(user);
return "success";
}else{
return "error";
}
}
@RequestMapping("/delUser")
public String delUser(@RequestParam String id){
try {
service.delUser(id);
return "del success";
} catch (Exception e) {
e.printStackTrace();
return "del false";
}
}
@RequestMapping("/updateUser")
public String updateUser(@RequestBody User user){
try {
service.updateUser(user);
return "update success";
} catch (Exception e) {
e.printStackTrace();
return "update false";
}
}
//测试方法,返回服务器端接口,以判断是哪个服务
@Value("${server.port}")
String port;
@RequestMapping("/hi")
public String home(@RequestParam(value = "name",defaultValue = "zhangsan")String name){
return "hi"+name+",i am from port:"+port;
}
}
mapper.xml
<?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="com.fz.providerone.dao.UserDao">
<select id="findAllUser" resultType="User">
select id,username from user
</select>
<insert id="createUser" parameterType="User">
insert into user values(#{id},#{username})
</insert>
<update id="updateUser" parameterType="User">
update user set username=#{username}
where id=#{id}
</update>
<delete id="delUser" parameterType="String">
delete from user where id=#{id}
</delete>
</mapper>
最后启动类添加注解@EnableEurekaClient
package com.fz.providerone;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ProviderOneApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderOneApplication.class, args);
}
}
启动后再去eureka服务上查看,client1服务已经注册上去
创建provider-two工程,直接把provider-one的代码复制过来,更改端口为8003,注意xml中的包名路径更改最后启动,刷新页面
四、创建服务消费工程consumer-ribbon
pom.xml依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fz</groupId>
<artifactId>consumer-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer-ribbon</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
server.port=8004
spring.application.name=consumer-ribbon
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
实体类
package com.fz.consumerribbon.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String username;
}
service层
package com.fz.consumerribbon.service;
import com.fz.consumerribbon.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class UserService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name){
return restTemplate.postForObject("http://PROVIDER-USER/user/hi?name="+name,null,String.class);
}
@HystrixCommand(fallbackMethod = "userListError")
public List userList(){
return restTemplate.postForObject("http://PROVIDER-USER/user/userList","",List.class);
}
@HystrixCommand(fallbackMethod = "addUserError")
public String addUser(User user){
return restTemplate.postForEntity("http://PROVIDER-USER/user/add",user,String.class).getBody();
}
@HystrixCommand(fallbackMethod ="updateUserError")
public String updateUser(User user){
return restTemplate.postForEntity("http://PROVIDER-USER/user/updateUser",user,String.class).getBody();
}
@HystrixCommand(fallbackMethod ="delUserError")
public String delUser(String id){
return restTemplate.postForObject("http://PROVIDER-USER/user/delUser?id="+id,null,String.class);
}
public String hiError(String name){
return "服务器开了小差,请休息一会再试!";
}
public List userListError(){
return null;
}
public String addUserError(User user){return "服务器开了小差,请休息一会再试!";}
public String updateUserError(User user){return "服务器开了小差,请休息一会再试!";}
public String delUserError(String id){return "服务器开了小差,请休息一会再试!";}
}
controller
package com.fz.consumerribbon.controller;
import com.fz.consumerribbon.entity.User;
import com.fz.consumerribbon.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/hi")
public String hi(@RequestParam String name){
return userService.hiService(name);
}
@RequestMapping(value ="/userList")
public List userList(){
return userService.userList();
}
@RequestMapping(value ="/addUser")
public String addUser(@RequestParam String id,String username){
User user =new User();
user.setId(id);
user.setUsername(username);
return userService.addUser(user);
}
@GetMapping(value ="/updateUser")
public String updateUser(@RequestParam String id,String username){
User user =new User();
user.setId(id);
user.setUsername(username);
return userService.updateUser(user);
}
@GetMapping(value ="/delUser")
public String delUser(@RequestParam String id){return userService.delUser(id);
}
}
启动类
package com.fz.consumerribbon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class ConsumerRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
启动consumer-ribbon工程
多次请求hi接口:http://localhost:8004/hi?name=test,下面信息会交替出现,说明负载均衡已经起作用了:
hi test ,i am from port:8002
hi test ,i am from port:8003
访问:http://localhost:8004/addUser?id=2&username=lisi,新增一条数据
success
再次访问:http://localhost:8004/userList, 出现以下信息说明新增成功!
[{“id”:“3”,“username”:“张三”},{“id”:“2”,“username”:“lisi”}]
访问:http://localhost:8004/updateUser?id=2&username=李四,修改数据
update success
访问:http://localhost:8004/delUser?id=2,删除数据
del success