包含依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
安装插件
在类上面添加@Data注解,就不用再写get和set和toString方法了,而且不影响性能,性能和手写一样
单元测试的@TransActional注解会自动回滚,他会自动带有@Rollback(true),不会修改数据库中的数据,如果需要修改数据库就不要使用@TransActional注解或者添加@Rollback(flase)
@Data
public class ResultVO<T> {
/** 错误码. */
private Integer code;
/** 提示信息. */
private String msg;
/** 具体内容. */
private T data;
}
@Data
public class ProductVO {
@JsonProperty("name")
private String categoryName;
@JsonProperty("type")
private Integer categoryType;
@JsonProperty("foods")
private List<ProductInfoVO> productInfoVOList;
}
@Data
public class ProductInfoVO {
@JsonProperty("id")
private String productId;
@JsonProperty("name")
private String productName;
@JsonProperty("price")
private BigDecimal productPrice;
@JsonProperty("description")
private String productDescription;
@JsonProperty("icon")
private String productIcon;
}
不建议,最好再重新建个类,数据传输对象,在每个层之间传数据用的
异常类
public class SellException extends RuntimeException{
private Integer code;
public SellException(ResultEnum resultEnum) {
super(resultEnum.getMessage());
this.code = resultEnum.getCode();
}
public SellException(Integer code, String message) {
super(message);
this.code = code;
}
}
异常方法参数枚举
@Getter
public enum ResultEnum {
PARAM_ERROR(1, "参数不正确"),
PRODUCT_NOT_EXIST(10, "商品不存在"),
PRODUCT_STOCK_ERROR(11, "商品库存不正确"),
;
private Integer code;
private String message;
ResultEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
异常使用
在service使用
//1. 查询商品(数量, 价格)
for (OrderDetail orderDetail: orderDTO.getOrderDetailList()) {
ProductInfo productInfo = productService.findOne(orderDetail.getProductId());
if (productInfo == null) {
throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
}
初始化
BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
不能直接使用±*/,只能使用BigDecimal的类方法
productInfo.getProductPrice()*orderDetail.getProductQuantity())的BigDecimal的乘法如下:
productInfo.getProductPrice() .multiply(new BigDecimal(orderDetail.getProductQuantity()))
a+b:
a.add(d);
public class KeyUtil {
/**
* 生成唯一的主键
* 格式: 时间+随机数
* @return
*/
public static synchronized String genUniqueKey() {
Random random = new Random();
Integer number = random.nextInt(900000) + 100000;
return System.currentTimeMillis() + String.valueOf(number);
}
}
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
dependency>
List<OrderDetail> orderDetailList = new ArrayList<>();
try {
orderDetailList = gson.fromJson(orderForm.getItems(),
new TypeToken<List<OrderDetail>>() {
}.getType());
} catch (Exception e) {
log.error("【对象转换】错误, string={}", orderForm.getItems());
throw new SellException(ResultEnum.PARAM_ERROR);
}
转换成功,但会有些发生错乱
一条键值对不要有回车
去掉多余的引号
对于非必须返回的值,且返回为空时再此属性的类上加上@JsonInclude(JsonInclude.Include.NON_NULL)
加上注解后,为null不再返回
必须返回的字段,且不能返回为null,需要在类中给定默认初始值
9-1 卖家订单-service
controller
/**
* 订单列表
* @param page 第几页, 从1页开始
* @param size 一页有多少条数据
* @return
*/
@GetMapping("/list")
public ModelAndView list(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size,
Map<String, Object> map) {
PageRequest request = PageRequest.of(page - 1, size);
Page<OrderDTO> orderDTOPage = orderService.findList(request);
map.put("orderDTOPage", orderDTOPage);
map.put("currentPage", page);
map.put("size", size);
// orderDTOPage.getTotalPages()
return new ModelAndView("order/list", map);
}
service
@Override
public Page<OrderDTO> findList(Pageable pageable) {
Page<OrderMaster> orderMasterPage = orderMasterRepository.findAll(pageable);
List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterPage.getContent());
return new PageImpl<>(orderDTOList, pageable, orderMasterPage.getTotalElements());
}
官网
http://www.ibootstrap.cn/
9-3 卖家-订单-controller(下) (15:30)
9-4 卖家订单-controller-翻页 (16:59)
9-5 卖家订单-controller-取消订单 (17:51)
9-6 卖家订单-controller-订单详情 (16:50)
9-7 卖家订单-controller-完结订单 (05:11)
第10章 卖家端通用功能和上下架
10-1 关于模版的小技巧 (02:57)
10-2 实现边栏 (11:08)
10-3 实现商品列表 (16:10)
10-4 商品上下架-service (09:10)
10-5 商品上下架-controller (07:25)
第11章 卖家端新增商品和类目
11-1 卖家商品-新增修改页面 (21:06)
11-2 卖家商品-修改表单提交 (11:16)
11-3 卖家商品-新增功能 (06:49)
11-4 卖家类目功能开发 (18:15)
12-2 分布式session理论(下) (05:47)
12-3 卖家信息表-dao开发 (06:12)
12-4 卖家扫码登录service开发 (03:02)
12-5 卖家扫码登录获取openid (19:15)
12-6 登录成功 (24:16)
12-7 登出成功 (13:17)
@Aspect
@Component
@Slf4j
public class SellerAuthorizeAspect {
@Autowired
private StringRedisTemplate redisTemplate;
@Pointcut("execution(public * com.imooc.controller.Seller*.*(..))" +
"&& !execution(public * com.imooc.controller.SellerUserController.*(..))")
public void verify() {}
@Before("verify()")
public void doVerify() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//查询cookie
Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
if (cookie == null) {
log.warn("【登录校验】Cookie中查不到token");
throw new SellerAuthorizeException();
}
//去redis里查询
String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
if (StringUtils.isEmpty(tokenValue)) {
log.warn("【登录校验】Redis中查不到token");
throw new SellerAuthorizeException();
}
}
}
12-9 微信模版消息推送 (21:05)
12-10 webSocket消息推送 (26:37)
@ControllerAdvice
public class SellExceptionHandler {
@Autowired
private ProjectUrlConfig projectUrlConfig;
//拦截登录异常
//http://sell.natapp4.cc/sell/wechat/qrAuthorize?returnUrl=http://sell.natapp4.cc/sell/seller/login
@ExceptionHandler(value = SellerAuthorizeException.class)
// @ResponseStatus(HttpStatus.FORBIDDEN)
public ModelAndView handlerAuthorizeException() {
return new ModelAndView("redirect:"
.concat(projectUrlConfig.getWechatOpenAuthorize())
.concat("/sell/wechat/qrAuthorize")
.concat("?returnUrl=")
.concat(projectUrlConfig.getSell())
.concat("/sell/seller/login"));
}
@ExceptionHandler(value = SellException.class)
@ResponseBody
public ResultVO handlerSellerException(SellException e) {
return ResultVOUtil.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(value = ResponseBankException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public void handleResponseBankException() {
}
}
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
public interface ProductCategoryMapper {
@Insert("insert into product_category(category_name, category_type) values (#{categoryName, jdbcType=VARCHAR}, #{category_type, jdbcType=INTEGER})")
int insertByMap(Map<String, Object> map); //写入成功返回1,失败返回0
@Insert("insert into product_category(category_name, category_type) values (#{categoryName, jdbcType=VARCHAR}, #{categoryType, jdbcType=INTEGER})")
int insertByObject(ProductCategory productCategory);
@Select("select * from product_category where category_type = #{categoryType}")
@Results({
@Result(column = "category_id", property = "categoryId"),
@Result(column = "category_name", property = "categoryName"),
@Result(column = "category_type", property = "categoryType")
})
ProductCategory findByCategoryType(Integer categoryType);
@Select("select * from product_category where category_name = #{categoryName}")
@Results({
@Result(column = "category_id", property = "categoryId"),
@Result(column = "category_name", property = "categoryName"),
@Result(column = "category_type", property = "categoryType")
})
List<ProductCategory> findByCategoryName(String categoryName);
@Update("update product_category set category_name = #{categoryName} where category_type = #{categoryType}")
int updateByCategoryType(@Param("categoryName") String categoryName,
@Param("categoryType") Integer categoryType);
@Update("update product_category set category_name = #{categoryName} where category_type = #{categoryType}")
int updateByObject(ProductCategory productCategory);
@Delete("delete from product_category where category_type = #{categoryType}")
int deleteByCategoryType(Integer categoryType);
ProductCategory selectByCategoryType(Integer categoryType);
}
@SpringBootApplication
@MapperScan(basePackages = "com.imooc.dataobject.mapper")
@EnableCaching
public class SellApplication {
public static void main(String[] args) {
SpringApplication.run(SellApplication.class, args);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class ProductCategoryMapperTest {
@Autowired
private ProductCategoryMapper mapper;
@Test
public void insertByMap() throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("categoryName", "师兄最不爱");
map.put("category_type", 101);
int result = mapper.insertByMap(map);
Assert.assertEquals(1, result);
}
@Test
public void insertByObject() {
ProductCategory productCategory = new ProductCategory();
productCategory.setCategoryName("师兄最不爱");
productCategory.setCategoryType(102);
int result = mapper.insertByObject(productCategory);
Assert.assertEquals(1, result);
}
@Test
public void findByCategoryType() {
ProductCategory result = mapper.findByCategoryType(102);
Assert.assertNotNull(result);
}
@Test
public void findByCategoryName() {
List<ProductCategory> result = mapper.findByCategoryName("师兄最不爱");
Assert.assertNotEquals(0, result.size());
}
@Test
public void updateByCategoryType() {
int result = mapper.updateByCategoryType("师兄最不爱的分类", 102);
Assert.assertEquals(1, result);
}
@Test
public void updateByObject() {
ProductCategory productCategory = new ProductCategory();
productCategory.setCategoryName("师兄最不爱");
productCategory.setCategoryType(102);
int result = mapper.updateByObject(productCategory);
Assert.assertEquals(1, result);
}
@Test
public void deleteByCategoryType() {
int result = mapper.deleteByCategoryType(102);
Assert.assertEquals(1, result);
}
@Test
public void selectByCategoryType() {
ProductCategory productCategory = mapper.selectByCategoryType(101);
Assert.assertNotNull(productCategory);
}
}
13-3 mybatis注解方式使用_B
13-4 mybatis xml方式使用 (08:16)
13-10 redis缓存的使用(下) (14:14)
14-1 项目部署 (17:33)
第15章 课程总结
15-1 13.总结 (04:19)
第16章 SpringBoot2.x版
16-2 升级到2.1.1 (21:56)
16-3 支付理论 (06:48)
16-4 授权1 (19:09)
16-5 授权2 (19:58)
16-7 支付1 (11:54)
16-8 支付2 (12:44)
第17章 实战-ID-187-SpringCloud体验章
17-1 导学 (11:57)
17-2 微服务和其他常见架构 (11:45)
17-3 从一个极简的微服务架构开始 (09:08)
17-4 Spring Cloud Eureka (01:33)
17-5 Eureka Server (17:17)
17-6 Eureka Client的使用 (16:07)
17-7 Eureka的高可用 (10:32)
17-8 Eureka总结_音频.mp4 (02:31)
17-9 分布式下服务注册的地位和原理 (11:53)