SpringCloud-04

  1. 第五天:MybatisPlus+SpringCloud重构User

    1. 微服务实践

      1. 全新技术栈

2.微服务组件架构图

2.MyBatisPlus

  1. 介绍

使用SpringBoot + Mybatis + MybatisPlus(MP) 全新注解方式,自动产生SQL语句,替代旧的通用Mapper。旧的通用Mapper是基于Mybatis拦截器的机制,而新的MybatisPlus是基于注解扫描机制,在启动服务时就进行加载,所以性能比旧的通用Mapper方式高很多。

MyBatisPlus官网:http://mp.baomidou.com

2.实现方式

方案

描述

备注

MyBatis

CartMapper接口

CartMapper.xml映射文件

手写SQL语句

通用Mapper

CartMapper接口

继承SysMapper接口

自动生成SQL语句

MP(MyBatisPlus)

CartMapper接口

继承BaseMapper接口

自动生成SQL语句

3.BaseMapper底层接口

已经封装好了CRUD,单表、批量、分页等19个方法,极大减少开发者的工作量。

4.MybatisPlus注解

Pojo对象上标识,自动驼峰规则

@TableName("tb_cart")    //类和表的映射
public class Cart extends BasePojo{
private static final long serialVersionUID = 1L;
//@TableField(exist=false)  //数据库表中不存在的字段要标识

@TableId(value="id",type=IdType.AUTO)  //主键自增
private Long id;
@TableField("user_id")   //属性和字段的映射
private Long userId;
  • @TableName("tb_cart")                     //类和表的映射

  • @TableId(value="id",type=IdType.AUTO)  //主键自增

  • @TableField("user_id")                 //属性和字段的映射

  • @TableField(exist=false)               //表中不存在的字段要标识

5.条件构造器

Mybatis提供QBC( Query By Criteria),实现面向对象的查询方式。

实体包装器 EntityWrapper,用于处理 sql 拼接,排序,实体参数查询等。注意其使用的是数据库字段而不是java属性。

例如:翻页查询

public Page<T> selectPage(Page<T> page, EntityWrapper<T> entityWrapper) {
if (null != entityWrapper) {
entityWrapper.orderBy(page.getOrderByField(), page.isAsc());
}
page.setRecords(baseMapper.selectPage(page, entityWrapper));
return page;
}

拼接SQL方式 一:

EntityWrapper<User> ew = new EntityWrapper<User>();
ew.setEntity(new User(1));
ew.where("user_name={0}", "'tonychen'").and("id=1")
.orNew("user_status={0}", "0").or("status=1")
.notLike("user_nickname", "tony")
.andNew("new=xx").like("hhh", "ddd")
.andNew("pwd=11").isNotNull("n1,n2").isNull("n3")
.groupBy("x1").groupBy("x2,x3")
.having("x1=11").having("x3=433")
.orderBy("name").orderBy("birthday,address");
System.out.println(ew.getSqlSegment());

拼接 SQL方式 二:

int buyCount = selectCount(Condition.create()
.setSqlSelect("sum(quantity)")
.isNull("order_id")
.eq("user_id", 1)
.eq("type", 1)
.in("status", new Integer[]{0, 1})
.eq("product_id", 1)
.between("created_time", startDate, currentDate);

6.拓展:MP工作原理

3.用户模块

  1. 项目结构

jt-user-consumer使用hystrix、ribbon、feign。复用之前的eureka和zuul,只在zuul增加映射路径。

注意feign中传递参数会自动转换成字符类型,如日期类型,所以只能靠字符串接参。

2.jt-gateway-zuul

application.yml

server:
port: 8050
spring:
application:
name: gateway-zuul
eureka:
client:
serviceUrl:
defaultZone: http://user:password123@localhost:8761/eureka
zuul:
ignoredServices: '*'
routes:
app-jt-user-consumer:
path: /jt/**
serviceId: jt-user-consumer
app-sidecar:
path: /sidecar/**
serviceId: sidecar

4.提供者

  1. 项目结构

2.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.jt</groupId>
<artifactId>jt-user</artifactId>
<version>0.0.1-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- mybatisplus/mybatis/jdbc/druid -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatisplus与springboot整合 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<!-- MP 核心库 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.2</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.0</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>
</project>

3.pojo

package cn.jt.pojo;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
//利用MybatisPlus的注解
@TableName(value="user") //类和数据库表的映射
public class User {
@TableId(type=IdType.AUTO)      //主键,自增
private Integer id;
private String name;

//对日期类型进行格式转换
private String birthday;
private String address;


public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}

4.UserMapper

package cn.jt.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import cn.jt.pojo.User;
//使用MP后,继承BaseMapper接口,实现单表CRUD SQL语句
public interface UserMapper extends BaseMapper<User>{
}

5.UserServiceImpl

package cn.jt.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.jt.mapper.UserMapper;
import cn.jt.pojo.User;
@Service
public class UserServiceImpl implements UserService{
@Autowired //注入Mapper
private UserMapper userMapper;

//查询所有
public List<User> find(){
return userMapper.selectList(null);
}

//新增
public void insert(User user){
userMapper.insert(user);
}

//修改
public void update(User user){
userMapper.updateById(user);
}

//批量删除
public void delete(List<Integer> ids){
userMapper.deleteBatchIds(ids);
}
}

6.UserService

package cn.jt.service;
import java.util.List;
import cn.jt.pojo.User;
public interface UserService {
public List<User> find();
public void insert(User user);
public void update(User user);
public void delete(List<Integer> ids);
}

7.UserController

package cn.jt.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.jt.pojo.User;
import cn.jt.service.UserService;
@RestController   //微服务调用,返回对象json串
@RequestMapping("/user")
public class UserController {
@Autowired //注入UserService接口
private UserService userService;

@RequestMapping("/find")
public List<User> find(){
return userService.find();
}

@RequestMapping("/insert/{name}/{birthday}/{address}")
public String insert(User user){
try{
userService.insert(user);
return "insert success.";
}catch(Exception e){
return "insert error.";
}
}

@RequestMapping("/update/{name}/{birthday}/{address}/{id}")
public String update(User user){
try{
userService.update(user);
return "update success.";
}catch(Exception e){
return "update error.";
}
}

@RequestMapping("/delete/{id}")
public String delete(@PathVariable Integer id){
try{
List<Integer> ids = new ArrayList<Integer>();
ids.add(id);

userService.delete(ids);
return "delete success.";
}catch(Exception e){
return "delete error.";
}
}

}

8.application.yml

server:
port: 7900

spring:
application:
name: jt-user
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb
username: root
password: root

eureka:
client:
serviceUrl:
defaultZone: http://user:password123@localhost:8761/eureka
mybatis:
mapUnderscoreToCamelCase: true
typeAliasesPackage: cn.jt.pojo
mapperLocations: classpath:mappers/*.xml

mybatis-plus:
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.jt.mapper: debug   

5.消费者

  1. 项目结构

2.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.jt</groupId>
<artifactId>jt-user-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
</project>

3.pojo

package cn.jt.pojo;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
//利用MybatisPlus的注解
@TableName(value="user") //类和数据库表的映射
public class User {
@TableId(type=IdType.AUTO)      //主键,自增
private Integer id;
private String name;

//对日期类型进行格式转换
private String birthday;
private String address;


public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}

4.UserFeign

package cn.jt.feign;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.jt.pojo.User;
@FeignClient("jt-user")     //指向访问的提供者
public interface UserFeign {
@RequestMapping("/user/find")
public List<User> find();

@RequestMapping("/user/insert/{name}/{birthday}/{address}")
public String insert(@PathVariable("name") String name,
@PathVariable("birthday") String birthday,
@PathVariable("address") String address);

@RequestMapping("/user/update/{name}/{birthday}/{address}/{id}")
public String update(@PathVariable("name") String name,
@PathVariable("birthday") String birthday,
@PathVariable("address") String address,
@PathVariable("id") Integer id);

@RequestMapping("/user/delete/{id}")
public String delete(@PathVariable("id") Integer id);
}

5.UserController

package cn.jt.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.jt.feign.UserFeign;
import cn.jt.pojo.User;
@RestController
@RequestMapping("/user")
public class UserController {
//注入Feign接口
@Autowired
private UserFeign userFeign;

@RequestMapping("/find")
public List<User> find(){
return userFeign.find();
}

@RequestMapping("/insert/{name}/{birthday}/{address}")
public String insert(User user){

return userFeign.insert(user.getName(), user.getBirthday(), user.getAddress());
}

@RequestMapping("/update/{name}/{birthday}/{address}/{id}")
public String update(User user){
return userFeign.update(user.getName(),user.getBirthday(),user.getAddress(),user.getId());
}

@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id){
return userFeign.delete(id);
}
}

6.RunAppUserConsumer

package cn.jt;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringCloudApplication
@EnableFeignClients
public class RunAppUserConsumer {
public static void main(String[] args) {
SpringApplication.run(RunAppUserConsumer.class, args);
}
}

7.application.yml

server:
port: 9001
spring:
application:
name: jt-user-consumer
eureka:
client:
serviceUrl:
defaultZone: http://user:password123@localhost:8761/eureka
logging:
level:
root: INFO

作者:Darren

QQ :603026148

以上内容归Darren所有,如果有什么错误或者不足的地方请联系我,希望我们共同进步。