整体框架
- springboot框架+mysql+freemarker
- 3层架构
- springboot+Session
- springboot+Redis
- springboot+JPA
- springboot+mybatis
springboot+Redis+session
首先引入pom引入redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
yml文件配置
/ / 配置 ip和 端口
redis:
host: 192.168.30.113
port: 6379
登陆
根据登陆的流程看出利用redis存储和cookies存储token得到redis的openid value
- 查找数据库找是否有该openid
- 把token和openid用于redis的key和value存储到redis中
- 把token存储到cookies中
代码
//openid和数据库中的数据配对
SellerInfo sellerInfo = sellerService.findByOpenid(openid);
if (sellerInfo == null) {
map.put("msg", ResultEnum.LOGIN_FAIL.getMessage());
map.put("url","sell/seller/order/List");
return new ModelAndView("common/error");
}
//把token放到redis中
String token = UUID.randomUUID().toString();
Integer expire= RedisConstant.EXPIRE;
redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX,token),openid,expire, TimeUnit.SECONDS);
//设置token到cookies中,从token中取到value值,然后从value值中得到reids中根据tokenid得到openid
CookieUtil.set(response, CookieConstant.TOKEN,token,CookieConstant.EXPIRE);
return new ModelAndView("redirect:/sell/seller/order/list");
/**
* 设置cookies
* @param response 请求
* @param name key
* @param value value
* @param maxAge 过期时间
*/
public static void set(HttpServletResponse response,String name,String value,int maxAge){
Cookie cookie= new Cookie(name,value);
cookie.setPath("/");
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
退出登陆
- 首先从cookie中得到token
- 如果cookie不为空,则删除redis中数据
- 清楚cookis中的数据为null
//cookies里面查询
Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
if (cookie != null) {
//清除redis
redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX,cookie.getName()));
// 清楚cookies
CookieUtil.set(response,CookieConstant.TOKEN,null,0);
}
map.put("msg",ResultEnum.LOGOUT_SUCCESS.getMessage());
map.put("url","sell/seller/order/list");
return new ModelAndView("common/success",map);
/**
* 得到cookie
* @param request 响应
* @param name
* @return
*/
public static Cookie get(HttpServletRequest request,String name){
Map<String, Cookie> CookieMap = readCookieMap(request);
if(CookieMap!=null){
if(CookieMap.containsKey(name)){
return CookieMap.get(name);
}else {
return null;
}
}
return null;
}
springboot+JPA
1引入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
2 yml文件配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: judy
url: jdbc:mysql://localhost/sell?characterEncoding=utf-8&useSSL=false
jpa:
show-sql: true
3 代码
JpaRepository<OrderDetailEntity,Integer> 表示表实体和id类型
@Component
public interface OrderDetilRepository extends JpaRepository<OrderDetailEntity,Integer> {
//订单详情表
List<OrderDetailEntity> findByOrderId(Integer orderId);
}
@Query: 查询
@Modifying :更新
springboot+mybatis
引入pom文件
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
配置mybatis
mybatis:
mapper-locations: classpath:mapper/*.xml
扫描mapper
你不扫描mapper肯定不能读取sql啊
//mybatis的扫描包
@MapperScan(basePackages = "com.judy.demo.mapper")
代码
@ insert
@ select
@ update
@ delete
…在mapper写sql,不说了…
思路
- 如果进行前后端分离写代码,(判空的时候怎么办)
- 如果回复统一code码
- 拦截器使用
- 封装异常
注解使用
@SpringBootApplication:
@SpringBootApplication = @Configuration + @ EnableAutoConfiguration + @ComponentScan
@Configuration与@Bean 是一对,一般在项目中都是这样使用的
//表示这个类是bean定义的源
@Configuration
public class ComponentDemo{
//负责告诉容器返回的对象会交给springioc容器管理
@Bean
public String judy(){
String a = new String();
return a;
}
@Bean
public Integer judyInt(){
Integer a = new Integer(2);
return a;
}
}
@ EnableAutoConfiguration : 自动载入应用程序所需的所有Bean, 依赖于springboot在类路径中查找
@ComponentScan : 会自动扫描指定包下所有标有@Component类,并且注为Bean, 还有@Component下的注解,@service @Repository @Controller
@MapperScan
一般是在项目启动的时候要扫描到mapper
@SpringBootApplication
//mybatis的扫描包
@MapperScan(basePackages = "com.judy.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@JsonSerialize
一般是序列化为指定的类型
@JsonSerialize(using = Date2LongSerializer.class)
private Date updateTime;
@JsonIgnore
它是在属性上使用的,一般用于序列化的时候自动忽略该属性,用于前后端联调的时候使用
@Entity与@Table(name=“order_detail”)
@Entity实体类一般是和表的名字对应,如果不对应的时候可以使用@Table用来指定表的名字
@DynamicUpdate(true)
当设置为true的时候表示更新的时候如果属性的值为null则不会更新,默认为false
@JsonProperty
前端传值的时候序列化为另一个属性名
断言
一般在调试和测试的使用到,最好在项目中要保持一致性
0:预期值,实际值
Assert.assertEquals(0,orderDTOPage.getTotalElements());
不为空
Assert.assertNotNull(byCategoryType);
不等于0则正确
Assert.assertNotEquals(0,productCategoryEntityList.size());
........
拦截
例如判断用户是否登陆过
使用@compent容器管理
@Pointcut切点
@Pointcut("execution(public * com.judy.demo.Controler.Seller*.*(..))"+"&& !execution(public * com.judy.demo.Controler.SellerUserController.*(..))")
public void verify(){}
@Before("verify()")
public void doVerify() throws SellerAuthorizeAspect {
ServletRequestAttributes attributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
if(cookie==null){
log.warn("登陆失败,cookies中查不到token");
throw new SellerAuthorizeAspect();
}
//去redis中查询
String tokenValue=redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX,cookie.getName()));
if (StringUtils.isEmpty(tokenValue)){
log.warn("登陆校验失败redis中没有token");
throw new SellerAuthorizeAspect();
}
}
额外补充(redis缓存知识点)
@Cacheable(cacheNames=“product”,key=“123”)
当线程执行到这个方法的时候,返回值就会缓存上,当下次执行的时候直接从缓存中取出,首先说明cacheNames和key都是表示的redis的key,key可以不写,如果不写表示的是参数值
@CachePut: 更新
@CacheEvict : 删除
必须要提醒的是由缓存那么相应的也应该有删除,避免出现脏数据
unless : 表示如果为空则不存储, 如果不加会报错, 有一次项目上线的时候没有加unless 结果报错了