使用SpringBoot、SpringCloud、Mybatis创建一个简单CURD的Rest风格微服务架构。
源码:https://github.com/hnyydp/microservice
项目代码结构:
1、父工程建立
首先建立一个父项目microservice
,用来统一管理项目依赖版本,注意创建的是maven pom项目。
pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<druid.version>1.1.6</druid.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringCloud,注意导入类型为pom -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot,注意导入类型为pom -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.13.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring-Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2、公共模块创建,主要存放实体类,工具类等一些共用的东西。
创建maven module项目microservice-common
,默认的jar类型
pom.xml
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
创建实体类:Dept.java
@Data //使用Lombok简化工作
//@Accessors(chain=true) //可以使用链式风格
public class Dept implements Serializable {
private Integer deptId;
private String deptName;
}
创建完成后,maven clean install
生成jar到本地仓库,方便其他项目引用。
3、服务提供模块创建
创建maven module项目 microservice-dept-provider-8001
,以后可能有多个服务,带上端口号,便于区分
pom.xml
<dependencies>
<!-- 引入公共模块 -->
<dependency>
<groupId>org.pu</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
配置application.yml
server:
context-path: /
port: 8001 #配置端口
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_springcloud?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
#mybatis配置
mybatis:
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置文件
type-aliases-package: org.pu.dept.entity # entity别名所在类
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
编写dao层操作DeptMapper.java
/**
* 数据库操作
* 注意添加mybatis @Mapper注解
* @author dave
*
*/
@Mapper
public interface DeptMapper {
@Select("select * from t_dept")
@Results({ @Result(id = true, column = "dept_id", property = "deptId"),
@Result(column = "dept_name", property = "deptName") })
public List<Dept> selectList();
@Select("select * from t_dept where dept_id = #{id}")
public Dept selectById(Integer id);
@Update("update t_dept t set t.dept_name = #{deptName} where dept_id = #{deptId}")
public int update(Dept dept);
@Options(useGeneratedKeys = true, keyProperty = "deptId")
@Insert("insert into t_dept (dept_name) values (#{deptName})")
public int insert(Dept dept);
@Delete("delete from t_dept where dept_id = #{id}")
public int deleteById(Integer id);
}
编写Service接口DeptService
和它的实现类DeptServiceImpl
public interface DeptService {
//查询所有
public List<Dept> selectList();
//通过ID查询
public Dept selectById(Integer id);
//更新
public int update(Dept dept);
//插入
public int insert(Dept dept);
//删除
public int deleteById(Integer id);
}
@Service("deptService")
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
public List<Dept> selectList() {
return deptMapper.selectList();
}
//......
}
编写Controller层DeptController.java
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/depts")
public List<Dept> depts() {
return deptService.selectList();
}
@GetMapping("/dept/{id}")
public Dept dept(@PathVariable(value = "id") Integer id) {
return deptService.selectById(id);
}
@PostMapping("/dept")
public Dept insert(@RequestBody Dept dept) {
deptService.insert(dept);
return dept;
}
@PutMapping("/dept")
public Dept update(@RequestBody Dept dept) {
deptService.update(dept);
return dept;
}
@DeleteMapping("/dept/{id}")
public boolean delete(@PathVariable(value = "id") Integer id) {
return deptService.deleteById(id) > 0;
}
}
启动项目后,使用Postman进行测试:
4、消费端模块创建
创建maven module项目 microservice-dept-consumer-80
,带上端口号,便于区分
pom.xml
<dependencies>
<!-- 引入公共模块 -->
<dependency>
<groupId>org.pu</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置application.yml
server:
context-path: /
port: 80
传统情况下在java代码里访问restful服务,一般使用Apache
的HttpClient
。不过此种方法使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate
。 springcloud消费者,服务提供者之间的交互是HTTP REST方式 ,比dubbo RPC方式更加灵活方便点;
具体可参考官方API文档:
编写配置类RestTemplateConfig
,将RestTemplate加入容器:
@Configuration
public class RestTemplateConfig {
/**
* 调用restful服务模版,客户端模版工具
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
编写Controller层DeptConsumerController
:
@RequestMapping("/consumer")
@RestController
public class DeptConsumerController {
private final static String URL_PREFIX = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@SuppressWarnings("unchecked")
@GetMapping("/depts")
public List<Dept> depts() {
return restTemplate.getForObject(URL_PREFIX + "/depts", List.class);
}
@GetMapping("/dept/{id}")
public Dept dept(@PathVariable(value = "id") Integer id) {
return restTemplate
.getForObject(URL_PREFIX + "/dept/" + id, Dept.class);
}
@PostMapping("/dept")
public Dept insert(@RequestBody Dept dept) {
return restTemplate.postForObject(URL_PREFIX + "/dept", dept,
Dept.class);
}
@PutMapping("/dept")
public Dept update(@RequestBody Dept dept) {
restTemplate.put(URL_PREFIX + "/dept", dept, Dept.class);
return dept;
}
@DeleteMapping("/dept/{id}")
public boolean delete(@PathVariable(value = "id") Integer id) {
try {
restTemplate.delete(URL_PREFIX + "/dept/" + id);
return true;
} catch (Exception e) {
return false;
}
}
}
启动消费者应用,使用Postman测试: