1 Star 0 Fork 0

缪克拉/springboot-api

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

Spring Boot简易代码

整合mybatisplus

引入依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis.version}</version>
</dependency>
配置文件 application.yml
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:6666/springboot_demo
    hikari:
      minimum-idle: 5
      maximum-pool-size: 20
      auto-commit: true
      idle-timeout: 30000
      pool-name: MyHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
mybatis-plus:
  mapper-locations: classpath*:mappers/*.xml
实体类
@Data
@TableName("`user`") // 表注解
public class User {
    @TableId(type = IdType.AUTO)  // 主键注解
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
mapper接口
// mapper.UserMapper
public interface UserMapper extends BaseMapper<User> {

}
直接使用Mapper处理数据
@SpringBootTest(classes = Application.class)
public class SampleTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println("测试...");
        List<User> list = userMapper.selectList(null);
        System.out.println(list);
        list.forEach(item -> {
            System.out.println("Name:" + item.getName());
        });
    }

    @Test
    public void testInsert() {
        User user = new User();
        user.setName("John Doe");
        user.setAge(30);
        user.setEmail("john.doe@example.com");
        userMapper.insert(user);
    }

    @Test
    public void testUpdate() {
        User userToUpdate = userMapper.selectById(1L);
        userToUpdate.setEmail("new.email@example.com");
        userMapper.updateById(userToUpdate);
    }

    @Test
    public void testSelectById() {
        User user = userMapper.selectById(1L);
        System.out.println(user);
    }

    @Test
    public void deleteById() {
        userMapper.deleteById(1L);
    }
}
使用IService接口的方式
  • 继承IService接口

    public interface UserService extends IService<User> {
    }
    
  • 继承ServiceImpl接口,实现UserService的实现类

    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    }
    
    
  • 测试IService方式

        @Test
        public void testInsertService() {
            User user = new User();
            user.setName("John Doe");
            user.setAge(30);
            user.setEmail("john.doe@example.com");
            userService.save(user);
        }
    
        @Test
        public void testDeleteService() {
            userService.removeById(1L);
        }
    
        @Test
        public void testUpdateService() {
            User userToUpdate = userService.getById(2L);
            userToUpdate.setEmail("new.email@example.com");
            userService.updateById(userToUpdate);
        }
    
        @Test
        public void testSelectService() {
            List<User> list = userService.list();
            System.out.println(list);
            list.forEach(item -> {
                System.out.println("Name:" + item.getName());
            });
        }
    
        @Test
        public void testSelectByIdService() {
            User user = userService.getById(2L);
            System.out.println(user);
        }
    
复杂的数据处理
@SpringBootTest(classes = Application.class)
public class SampleTest {

    @Autowired
    private UserMapper userMapper;

    /**
     * QueryWrapper
     */
    @Test
    public void testQueryWrapper() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "John Doe")
                .between("age", 20, 30)
                .isNotNull("email");
        List<User> users = userMapper.selectList(queryWrapper);
        System.out.println(users);
    }

    /**
     * UpdateWrapper
     */
    @Test
    public void testUpdateWrapper() {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("email", "new.email@example.com")
                .eq("name", "John Doe")
                .between("age", 20, 30)
                .isNotNull("email");
        int rows = userMapper.update(null, updateWrapper);
        System.out.println(rows + " rows updated");
    }

    /**
     * Wrapper自定义SQL
     */
    @Test
    public void testWrapper() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("name = {0}", "John Doe");
        List<User> users = userMapper.selectList(queryWrapper);
        System.out.println(users);
    }

    /**
     * LambdaQueryWrapper
     */
    @Test
    public void testLambdaQueryWrapper() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery(User.class);
        userLambdaQueryWrapper.eq(User::getName, "John Doe")
                .between(User::getAge, 20, 30)
                .isNotNull(User::getEmail);
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

    /**
     * LambdaUpdateWrapper
     */
    @Test
    public void testLambdaUpdateWrapper() {
        LambdaUpdateWrapper<User> userLambdaUpdateWrapper = Wrappers.lambdaUpdate(User.class);
        userLambdaUpdateWrapper.set(User::getEmail, "new.email@example.com")
                .eq(User::getName, "John Doe")
                .between(User::getAge, 20, 30)
                .isNotNull(User::getEmail);
        int rows = userMapper.update(null, userLambdaUpdateWrapper);
        System.out.println(rows + " rows updated");
    }

    /**
     * 复杂的查询 比如连表
     */
    @Test
    public void testSelectWithOrder() {
        OrderUserDTO orderUserDTO = orderWithUserMapper.selectOrderWithUser(1L);
        System.out.println(orderUserDTO);
    }
}
复杂数据查询
  • 定义Mapper接口

    public interface OrderWithUserMapper {
        OrderUserDTO selectOrderWithUser(Long orderId);
    }
    
    
  • 编写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.miaokela.mapper.OrderWithUserMapper">
        <resultMap id="OrderUserMap" type="com.miaokela.dto.OrderUserDTO">
            <result property="orderId" column="order_id"/>
            <result property="orderDetails" column="order_details"/>
            <result property="userId" column="user_id"/>
            <result property="userName" column="user_name"/>
        </resultMap>
    
        <select id="selectOrderWithUser" resultMap="OrderUserMap">
            SELECT
                o.id AS order_id,
                o.order_details,
                u.id AS user_id,
                u.name AS user_name
            FROM
                `order` o LEFT JOIN `user` u ON o.user_id = u.id
            WHERE
                o.id = #{orderId}
        </select>
    </mapper>
    
  • 编写实体类

    @Data
    public class OrderUserDTO {
        private Long orderId;
        private String orderDetails;
        private Long userId;
        private String userName;
    }
    
  • 测试查询

    @SpringBootTest(classes = Application.class)
    public class SampleTest {
    
        @Autowired
        private OrderWithUserMapper orderWithUserMapper;
    
        /**
         * 复杂的查询 比如连表
         */
        @Test
        public void testSelectWithOrder() {
            OrderUserDTO orderUserDTO = orderWithUserMapper.selectOrderWithUser(1L);
            System.out.println(orderUserDTO);
        }
    }
    

统一响应格式

// utils.ApiResponse
@Data
public class ApiResponse<T> {
    private int code;
    private String message;
    private T data;

    public ApiResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

全局异常处理

// utils.GlobalExceptionHandler
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApiResponse<String> hanldeException(Exception e) {
        return new ApiResponse<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误", null);
    }
}

Swagger接口文档

引入依赖
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>
编写配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.quickstart.controller"))
            .paths(PathSelectors.any())
            .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
            .title("API 文档")
            .description("API 文档描述")
            .version("1.0")
            .build();
    }
}
访问地址

http://localhost:8080/doc.html

基础jwt认证

引入依赖
<!-- jwt -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
JWT处理工具类

生成token,校验token

@Component
public class JwtUtil {
    private String secret = "yourSecretKey"; // 用于签名和验证JWT的密钥
    private Integer expireTime = 1000 * 60 * 60 * 10;

    // 从JWT令牌中提取用户名
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    // 从JWT令牌中提取特定的声明(claim)
    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        try {
            final Claims claims = getAllClaimsFromToken(token);
            return claimsResolver.apply(claims);
        } catch (Exception e) {
            return null;
        }
    }

    // 为获取任何信息而解析JWT令牌
    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    // 验证JWT令牌
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()));
    }

    // 生成JWT令牌
    public String generateToken(UserDetails userDetails) {
        return Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expireTime)) // 设置过期时间
                .signWith(SignatureAlgorithm.HS512, secret).compact();
    }
}
添加过滤器
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String authToken = request.getHeader("Authorization");
        if (authToken != null && authToken.startsWith("Bearer ")) {
            authToken = authToken.substring(7);
            String username = jwtUtil.getUsernameFromToken(authToken);

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                if (jwtUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);
    }
}
注册过滤器
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String authToken = request.getHeader("Authorization");
        if (authToken != null && authToken.startsWith("Bearer ")) {
            authToken = authToken.substring(7);
            String username = jwtUtil.getUsernameFromToken(authToken);

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                if (jwtUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);
    }
}

获取用户信息

上面提到一个Spring Security的UserDetailsService的实现,用来获取用户信息

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final PasswordEncoder passwordEncoder;

    public CustomUserDetailsService(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO 这里仅为示例,实际应用中应该从数据库或其他地方根据用户名查找用户信息
        if ("admin".equals(username)) {
            return User.builder()
                    .username("admin")
                    .password(passwordEncoder.encode("password"))
                    .roles("ADMIN") // 或者.authorities("ROLE_ADMIN")
                    .build();
        } else {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
    }
}

整合redis

引入依赖
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <exclusions>
        <exclusion>
          <groupId>io.lettuce</groupId>
          <artifactId>lettuce-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
    </dependency>
添加配置
spring:
  redis:
    host: localhost
    port: 6379
    timeout: 1000
    jedis:
      min-idle: 5
      max-idle: 10
      max-active: 10
      max-wait: 2000
创建配置类

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置序列化工具,这里使用JSON序列化
        Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);

        // 配置RedisTemplate
        template.setValueSerializer(jacksonSeial);
        template.setHashValueSerializer(jacksonSeial);
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        template.afterPropertiesSet();

        return template;
    }
}

测试插入

@SpringBootTest(classes = Application.class)
public class QuickStartTest {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Test
    public void testInsertRedis() {
        redisTemplate.opsForValue().set("name", "miaokela");
    }
}

定时任务 Task

配置类
@Component
public class MyScheduledTasks {

    @Scheduled(fixedRate = 5000)
    public void resportCurrentTime() {
        System.out.println("当前时间: " + System.currentTimeMillis());
    }

    @Scheduled(cron = "0 0 1 * * ?")
    public void executeDaily() {
        System.out.println("执行日常任务");
    }
}
注册
@SpringBootApplication
@MapperScan("com.quickstart.mapper")
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Docker部署

Dockerfile
# 使用官方Java运行时环境作为基础镜像
FROM openjdk:8-jdk-alpine

# 指定维护者信息
LABEL maintainer="yourname@example.com"

# 添加一个卷,指向外部的/tmp,因为Spring Boot使用的内嵌Tomcat容器默认使用/tmp作为工作目录
VOLUME /tmp

# 将jar文件添加到容器中
ADD target/myproject-1.0-SNAPSHOT.jar myproject-1.0-SNAPSHOT.jar

# 声明运行时容器提供服务端口
EXPOSE 8080

# 配置容器启动后执行的命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/myproject-1.0-SNAPSHOT.jar"]
创建镜像
docker build -t spring-boot-app .

创建并运行容器

docker run -d -p 8081:8080 spring-boot-app 
MIT License Copyright (c) 2024 缪克拉 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

restapi需要的相关组件 展开 收起
README
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/miaokela/springboot-api.git
git@gitee.com:miaokela/springboot-api.git
miaokela
springboot-api
springboot-api
master

搜索帮助