Rest
以Dept部门模块做一个微服务通用案例
Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务;
分模块架构:
一个Project带着多个Module子模块
MicroServiceCloud父工程(Project)下初次带着三个子模块(Module)
下图中,如果entity在1.2\1.3\1.4\1.5子模块中都要用到,可以在api公共模块中定义entity,让剩余模块直接调用,不用再在每个模块里都写一遍entity
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事,从技术角度看就是一种小而独立的处理过程,类似进程概念,能够自行单独启动或销毁,拥有自己独立的数据库。
父工程构建
microservicecloud-api公共子模块Module
部门dept实体类
java
@Data
@NoArgsConstructor
@Accessors(chain = true) //chain为true,说明它支持链式写法
//所有实体类务必序列化,方便在网络传输
public class Dept implements Serializable {
private Long deptno; //主键
private String dname; //部门名称
private String db_source; //来自哪个数据库,因为微服务架构可以一个服务对应一个数据库,同一个信息被存储到不同数据库
public Dept(String dname) {
this.dname = dname;
}
/*
链式写法:
Dept dept = Dept();
dept.setDeptNo(11).setDname("ss").setDb_source("db1");
*/
}
microservicecloud-provider-dept-8001部门微服务提供者Module
application.yml
yaml
server:
port: 8001
mybatis:
type-aliases-package: com.cht.springcloud.pojo # 所有entity别名类所在包
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置文件所在路径
mapper-locations: classpath:mybatis/mapper/*.xml #mapper映射文件
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8 # 数据库名称
username: root
password: root
mybatis配置文件:
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
Dao层------DeptDao
java
@Mapper
@Repository
public interface DeptDao {
boolean addDept(Dept dept);
Dept queryById(Long id);
List<Dept> queryAll();
}
Dao的实现mapper
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cht.springcloud.dao.DeptDao">
<insert id="addDept" parameterType="Dept">
insert into dept(dname,db_source) values(#{dname},DATABASE());
</insert>
<select id="queryById" resultType="Dept" parameterType="Long">
select * from dept where deptno = #{deptno}
</select>
<select id="queryAll" resultType="Dept" >
select * from dept
</select>
</mapper>
Service层及其实现类Impl
java
public interface DeptService {
boolean addDept(Dept dept);
Dept queryById(Long id);
List<Dept> queryAll();
}
java
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao deptDao;
@Override
public boolean addDept(Dept dept) {
return deptDao.addDept(dept);
}
@Override
public Dept queryById(Long id) {
return deptDao.queryById(id);
}
@Override
public List<Dept> queryAll() {
return deptDao.queryAll();
}
}
Controller
java
//提供restful服务
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/dept/add")
public boolean addDept(Dept dept){
return deptService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id") Long id){
return deptService.queryById(id);
}
@GetMapping("/dept/list")
public List<Dept> queryAll(){
return deptService.queryAll();
}
microservicecloud-consumer-dept-80部门微服务消费者Module
ConfigBean
java
@Configuration //boot优化了spring spring用的配置文件叫applicationContext.xml 现在用的是注解版的配置 @Configuration配置
public class ConfigBean {
@Bean
@LoadBalanced //这样你再用RestTemplate去访问的时候就自带负载均衡了
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
// applicationContext.xml == ConfigBean(@Configuration)
// <bean id = "userService" class = "com.atguigu.tmall.UserServiceImpl"> 原本xml中的写法
消费者Controller,只消费,所以没有service,通过rest调用8001模块的controller
java
@RestController
public class DeptConsumerController {
//消费者:不应该有service层
//RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
//参数可以通过map,实体,url传过去
@Autowired
private RestTemplate restTemplate;//提供多种便捷访问远程http服务的方法,简单的restful风格服务
/**
* 服务提供方地址前缀
* 这里的地址,应该是一个变量,通过服务名来访问
*/
private static final String REST_URL_PREFIX = "http://localhost:8001";
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
// getForObject(服务提供方地址(接口),返回类型.class) 其中的get表示Get请求,因为也有postForObject
/*ForObject表示拿到一个对象*/
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept) {
// postForObject(服务提供方地址(接口),参数实体,返回类型.class)
//可以用http://localhost/consumer/dept/add?dname=小葵,完成添加,只不过dname在数据库没有显示出来,但记录增加了
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
@RequestMapping("/consumer/dept/list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}