首页 > 其他分享 >Spring Cloud中从0-1实现高效的API接口,快来简单有效的方式来构建API接口

Spring Cloud中从0-1实现高效的API接口,快来简单有效的方式来构建API接口

时间:2024-03-30 11:00:12浏览次数:22  
标签:Mapper 4.1 Spring private id API 接口 public User

目录

1. 添加POM依赖

2. 构建目录结构

3. 构建文件

4. 实现API接口

4.1. MyBatis

4.1.1. 控制层(Controller)

4.1.2. 服务接口层 (Service Interface)

4.1.3. 服务层(Service Implementation)

4.1.4. 实体类(Entity)

4.1.5. 数据访问层(Mapper)

 4.1.6. JUnit单元测试

Controller层测试

Mapper层测试

 4.2. Spring Data JPA

 4.2.1. 控制层(Controller)

4.2.2. 服务层(Service)

4.2.3. 实体类(Entity)

4.2.4. 数据访问层(Repository)

4.2.5. JUnit单元测试

Controller层测试

Service层测试

5. 总结


        为了从零开始实现一个高效的API接口,下面将通过Spring Cloud构建一个简单的用户服务作为示例。这个服务将包括获取用户详情的API。将逐步介绍控制层、服务层、服务接口层、数据访问层等层面的具体实现方式及作用,同时利用JUnit进行单元测试。

1. 添加POM依赖

        首先,在`pom.xml`中添加必要的Spring Boot和Spring Cloud等依赖。下面是一个基本的示例:

<dependencies>
    <!-- Spring Cloud 相关依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
    <!-- Spring Boot 和 Web 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MyBatis 依赖 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    <!-- MySQL 驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- Spring Boot 测试相关依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- Spring Data JPA启动器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- Lombok库,减少样板代码 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- Spring Boot 测试启动器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 构建目录结构

        创建以下目录结构来组织代码:

src/
|- main/
   |- java/
      |- com/
         |- example/
            |- api/
               |- Application.java
               |- controller/   // 控制层
               |- service/      // 服务层
               |- service/impl/ // 服务接口实现层
               |- repository/   // 数据访问层(Mapper或Repository)
               |- entity/       // 实体类
               |- dto/          // 数据传输对象
   |- resources/
      |- application.yml
      |- mapper/  // MyBatis的Mapper XML文件存放目录
|- test/
   |- java/
      |- com/
         |- example/
            |- api/
               |- controller/
               |- service/
               |- mapper/

3. 构建文件

        在`application.yml`中配置应用程序参数,比如服务端口、数据库连接和自定义参数。

server:
  port: 8080
  
spring:
  application:
    name: spring-cloud-api-service
    
  datasource:
    url: jdbc:mysql://localhost:3306/db_example?serverTimezone=UTC&useSSL=false
    username: db_user
    password: db_password
    driverClassName: com.mysql.cj.jdbc.Driver
    
mybatis:
  mapper-locations: classpath:/mybatis/*.xml
  type-aliases-package: com.example.api.entity

jpa:
  show-sql: true
  hibernate:
    ddl-auto: update

4. 实现API接口

        现在我们来具体实现API接口,分层介绍每一部分。

- 控制层 (Controller): 处理外部HTTP请求,将请求转发给服务层。
- 服务接口层 (Service Interface): 定义服务层的接口。
- 服务层 (Service Implementation): 实现服务接口层定义的接口,包含业务逻辑。
- 数据访问层 (Mapper & Mapper XML): 与数据库交互,执行CRUD操作。这里可使用MyBatis或Spring Data JPA等框架来实现。如果是使用MyBatis,你会有Mapper接口和对应的XML文件。

4.1. MyBatis

4.1.1. 控制层(Controller)

        控制层负责处理外部请求,并将请求转发到服务层。

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable("id") Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
}

4.1.2. 服务接口层 (Service Interface)

        服务接口层定义了服务层需要实现的方法。它是一种契约,规定了可供控制层调用的业务逻辑方法。

public interface UserService {
    User getUserById(Long id);
}

4.1.3. 服务层(Service Implementation)

        服务层实现了服务接口层定义的方法。这里包含了具体的业务逻辑,如调用Mapper层与数据库交互。

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User getUserById(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }
}

4.1.4. 实体类(Entity)

        数据传输对象用于服务层和控制层之间的数据传递。

public class User {
    private Long id;
    private String name;

    // getter和setter省略
}

4.1.5. 数据访问层(Mapper)

        数据访问层使用MyBatis Mapper接口与数据库进行交互。它定义了一些用于数据库操作的方法,这些方法的实现由MyBatis框架在运行时自动完成。

@Mapper
public interface UserMapper {
    User selectByPrimaryKey(Long id);
}

        MyBatis的Mapper XML文件定义了Mapper接口方法的SQL语句。对应的`UserMapper.xml`:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.api.mapper.UserMapper">
    <select id="selectByPrimaryKey" resultType="com.example.api.entity.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

 4.1.6. JUnit单元测试

Controller层测试
@WebMvcTest(UserController.class)
public class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void getUserByIdTest() throws Exception {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(1L);
        userDTO.setName("John Doe");

        given(userService.getUserById(1L)).willReturn(userDTO);

        mockMvc.perform(MockMvcRequestBuilders.get("/users/1")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("John Doe"));
    }
}
Mapper层测试
@DataJpaTest
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void selectByPrimaryKeyTest() {
        // 这里需要添加测试数据,或者使用一个内存数据库如H2
        User user = userMapper.selectByPrimaryKey(1L);
        assertNotNull(user);
        assertEquals("John Doe", user.getName());
    }
}

 4.2. Spring Data JPA

 4.2.1. 控制层(Controller)

        控制层负责处理外部请求,并将请求转发到服务层。

@RestController
@RequestMapping("/users")
@AllArgsConstructor
public class UserController {
    private final UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

4.2.2. 服务层(Service)

        服务层是业务逻辑的中心层,它从控制器接收命令,并利用数据访问层来实现这些命令。

@Service
@AllArgsConstructor
public class UserService {
    private final UserRepository userRepository;

    public User findById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("User not found"));
    }
}

4.2.3. 实体类(Entity)

        实体类是数据库表的映射。

@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    // 其他字段...
}

4.2.4. 数据访问层(Repository)

        Spring Data JPA的Repository负责数据持久化操作。

public interface UserRepository extends JpaRepository<User, Long> {
}

4.2.5. JUnit单元测试

Controller层测试
@WebMvcTest(UserController.class)
public class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void getUserByIdShouldReturnUser() throws Exception {
        User user = new User(1L, "John Doe");
        Mockito.when(userService.findById(1L)).thenReturn(user);

        mockMvc.perform(get("/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value(user.getName()));
    }
}
Service层测试
@ExtendWith(SpringExtension.class)
@DataJpaTest
public class UserServiceTest {
    @Autowired
    private UserRepository userRepository;

    private UserService userService;

    @BeforeEach
    public void setUp() {
        userService = new UserService(userRepository);
    }

    @Test
    public void findByIdShouldReturnUser() {
        User savedUser = userRepository.save(new User(1L, "John Doe"));
        User foundUser = userService.findById(savedUser.getId());
        
        assertThat(foundUser).isEqualTo(savedUser);
    }
}

5. 总结

        通过这种分层架构,可以清晰地组织代码,实现关注点分离,提高代码的可维护性和可扩展性。每一层的作用已经被清晰定义,并且示例代码为您提供了具体的实施方案。Junit测试确保了代码的正确性和稳定性。在实际的开发环境中,这个基础架构需要根据具体的需求进行适当的扩展和调整。还需要考虑错误处理、日志记录、安全性和其他高级特性。

标签:Mapper,4.1,Spring,private,id,API,接口,public,User
From: https://blog.csdn.net/Ead_Y/article/details/136983708

相关文章

  • SpringBoot + Activiti 工作流搭建与实现(附文档+源码)
      前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。一、项目形式springboot+vue+activiti集成了activiti在线编辑器,流行的前后端分离部署开发模式,快速开发平台,可插拔工作流服务......
  • Vue父组件拿到接口的数据,并把数据传给子组件的问题;同时,父组件数据更新,子组件同样拿到
    参考文档:https://blog.csdn.net/qq_33723676/article/details/128143924问题一:父组件向子组件传值,子组件拿到的是空数据。在vue中,有时需要在父组件页面调用接口时,并把数据传给子组件。一般的做法中,子组件拿不到父组件传过来的值。原因是什么捏???原因就是:父组件跟子组件获取数据是......
  • 基于Java+Springboot框架自习室教室座位预约系统设计与实现
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。项目配有对应开发文档、开题报告、任务书、P......
  • typescript——3.接口
    接口初探接口:约束、限制下面通过一个简单示例来观察接口是如何工作的:functionprintLabel(labelledObj:{label:string}){console.log(labelledObj.label);}letmyObj={size:10,label:"Size10Object"};printLabel(myObj);类型检查器会查看printLa......
  • 如何使用spring状态机
    让我们通过一个具体的例子来深入了解Spring状态机的使用。这个例子将模拟一个简单的订单处理流程,其中订单有三个状态:待支付(`NEW`)、已支付(`PAID`)、已完成(`COMPLETED`)。订单状态的转换通过两个事件触发:支付(`PAY`)和完成订单(`COMPLETE`)。步骤1:添加依赖首先,确保你的项目中包含......
  • 【Kingbase8数据库】springboot jpa集成Kingbase8各种报错
    AccesstoDialectResolutionInfocannotbenullwhen‘hibernate.dialect’notset去了stackoverflow:java-SpringBootJPA-AccesstoDialectResolutionInfocannotbenullwhen‘hibernate.dialect’notset-StackOverflow不是PostgreSQL,那就换成mysql的嘛:spr......
  • 查询手机号码是否支持携号转网的API接口
      手机号码携号转网已经成为了一个热门话题,很多人在选择运营商时都会考虑这个因素。然而,要知道一个手机号码是否支持携号转网,并且查询其转网前及转网后所归属的运营商,是一件比较困难的事情。不过,幸运的是,有一些API接口可以帮助我们实现这个功能。今天,我要向大家介绍的就是一......
  • Springboot+vue的高校科研信息管理系统(有报告)。Javaee项目,springboot vue前后端分离项
    演示视频:Springboot+vue的高校科研信息管理系统(有报告)。Javaee项目,springbootvue前后端分离项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Vue+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系......
  • 基于Springboot的研究生调研管理系统(有报告)。Javaee项目,springboot项目。
    演示视频:基于Springboot的研究生调研管理系统(有报告)。Javaee项目,springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Vue+Maven+Layui+Elementui来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系......
  • springcloudgatewayRCE(spEl表达式)
    CVE-2022-22947SpringCloudGatewayRemoteCodeExecute漏洞/SpELCodeInjection漏洞基本介绍cloud全家桶网关作用l智能路由l负载均衡l协议转换l权限校验l限流熔断l黑白名单lAPI监控l日志审计SpringCloutGateway使用<dependency><groupId>org.......