前置知识:JavaWeb、Mysql、Springboot等入门知识
此部分请跳到:
https://blog.csdn.net/bobo553443/article/details/81383194
此部分请跳到:https://blog.csdn.net/GDUT_xin/article/details/108986323
创建一个普通的 Springboot 项目
此部分请跳到:
https://blog.csdn.net/qq_34491508/article/details/91369794
spring-boot-starter-web包中含有spring-boot-starter,要将spring-boot-starter去掉,以免包冲突!
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.3version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
根据自身情况配置!
#restful端口
server.port=8080
#数据源
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.url = jdbc:mysql://localhost:3306/*?serverTimezone=UTC
#redis
spring.redis.host=localhost
spring.redis.port=6379
#缓存
spring.cache.type=redis
spring.cache.cache-names=redisCache
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.net.UnknownHostException;
/**
* 自定义序列化,防止乱码
*/
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//String的序列化器
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 允许跨域
*/
@Configuration
public class CrossConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}
要在数据库中添加对应的表以供测试!
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import java.io.Serializable;
@Component
public class User implements Serializable {
private Integer id;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
'}';
}
public User() {
}
}
@Mapper//sql映射类
public interface UserDao {
/*
mybatis的sql映射方法
@Param是给参数给定义一个参数名
#{}是springEL,根据参数名取值
*/
@Select("select * from user where id = #{id} and password = #{password}")
User getUserByIdAndPassword(@Param("id") int id, @Param("password") String password);
@Select("select * from user where id = #{id}")
User getUserById(@Param("id")int id);
}
接口
import com.xmvp.pojo.User;
import java.util.List;
public interface UserService {
User login(int id, String password);
User getUserById(int id);
}
实现类
import com.xmvp.dao.UserDao;
import com.xmvp.pojo.User;
import com.xmvp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private final UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public User login(int id, String password) {
return userDao.getUserByIdAndPassword(id,password);
}
@Override
public User getUserById(int id) {
return userDao.getUserById(id);
}
}
import com.xmvp.pojo.User;
import com.xmvp.service.UserService;
import org.springframework.cache.annotation.CachePut;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @RestController 默认包含以下注解
* @Controller 控制层组件
* @ResponseBody 直接返回给页面JSON
*/
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
/*
restful风格,按资源路径规范取资源
{}是接受相应位置的值来赋值
@PathVariable 是将{}中的同名变量拿来作方法的输入值
因为输入相同id和密码的概率小,无需缓存
*/
@RequestMapping(value ="/user/{id}/{password}",method = RequestMethod.GET)
public User login(@PathVariable int id,@PathVariable String password){
User user = userService.login(id,password);
return user;
}
/**
* 查询某个id的次数可能会很多,@Cacheable 加入缓存机制
* #result可以取得方法的返回值,#id取得参数id的值,value是redis的key的前缀
* condition如果表达式结果为true则会执行缓存的相关操作
*/
@RequestMapping(value = "/user/id/{id}",method = RequestMethod.GET)
@CachePut(value = "redisCache",condition = "#result != 'null'",key = "'user_'+#id")
public User getUserById(@PathVariable int id){
return userService.getUserById(id);
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
/**
* 允许缓存(这里用redis)
*/
@EnableCaching
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
启动 main 方法后,开启浏览器,根据 Controller 层中@RequestMapping注解中的restful风格的资源路径规范输入!
输入示例:
查询:localhost:8080/user/id/10000
登录:localhost:8080/user/10000/10000
得到JSON字符串即为搭建后台成功!把接口交给前端程序员就可以了!
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
public class RedisTest {
@Autowired
/*
指定别名
会使用我们RedisConfig定义的RedisTemplate类
*/
@Qualifier(value = "redisTemplate")
private RedisTemplate redisTemplate;
@Test
void test(){
/*
还记得@Cacheable(value = "redisCache",condition = "#result != 'null'",key = "'user_'+#id")吗?
key是 [redis库名]::[key]
*/
System.out.println(redisTemplate.opsForValue().get("redisCache::user_10000"));
}
}
运行得到的是String序列化后的结果
后台 redis-cli 输入与输出示例:
127.0.0.1:6379> keys *
1) "redisCache::user_10000"
127.0.0.1:6379> get redisCache::user_10000
"\xac\xed\x00\x05sr\x00\x12com.xmvp.pojo.User\x1dL\xfa\xd9\xdd\xb58m\x02\x00\x04L\x00\x05emailt\x00\x12Ljava/lang/String;L\x00\x02idt\x00\x13Ljava/lang/Integer;L\x00\x04nameq\x00~\x00\x01L\x00\bpasswordq\x00~\x00\x01xpt\x00\[email protected]\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00'\x10t\x00\x05admint\x00\x0510000"
可以看到对象以String方式存储着
127.0.0.1:6379> info
#...
# Clients
connected_clients:2
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
可以看到有两个连接,一个是目前的控制台,一个是Springboot。