使用Spring Boot和MyBatis Plus整合实现商品二维码生成

前言

二维码已经成为现代商业的常用工具,二维码不仅能够实现快速付款,还能够实现商品信息的展示。在这篇文章中,我们将使用Spring Boot和MyBatis Plus整合来实现商品二维码的生成。在本文中,我们将讨论如何使用Spring Boot和MyBatis Plus实现商品信息的查询、生成二维码、以及二维码的显示与分享等操作。

开发环境

以下是本篇文章使用的开发环境:

  • JDK 1.8+
  • IntelliJ IDEA
  • Spring Boot 2.3.0.RELEASE
  • MyBatis Plus 3.4.0
  • MySQL 5.6+

项目结构

我们先来看一下我们的项目结构:

├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           ├── config
│   │   │           │   └── MyBatisPlusConfig.java
│   │   │           ├── controller
│   │   │           │   └── GoodsController.java
│   │   │           ├── dao
│   │   │           │   └── GoodsMapper.java
│   │   │           ├── pojo
│   │   │           │   └── Goods.java
│   │   │           ├── service
│   │   │           │   ├── IGoodsService.java
│   │   │           │   └── impl
│   │   │           │       └── GoodsServiceImpl.java
│   │   │           └── util
│   │   │               ├── QRCodeUtil.java
│   │   │               └── WxShareUtil.java
│   │   ├── resources
│   │   │   ├── application.properties
│   │   │   ├── mapper
│   │   │   │   └── GoodsMapper.xml
│   │   │   └── static
│   │   │       └── images
│   │   │           └── qrcode
│   │   └── webapp
│   └── test
└── pom.xml

在以上项目结构中,我们使用Maven作为构建工具,项目主要包括了config、controller、dao、pojo、service、util这几个包。

数据库设计

本文我们将实现的是一个购物系统。其中,商品信息的存储我们使用了MySQL数据库。在这里,我们先来看下我们需要存储哪些信息。

  • 商品编号(goods_id)
  • 商品名称(goods_name)
  • 商品价格(goods_price)
  • 商品库存(goods_stock)
  • 商品描述(goods_description)
  • 商品图片(goods_image)

以下是我们的商品信息表的设计:

CREATE TABLE `goods` (`goods_id` int(11) NOT NULL COMMENT '商品编号',`goods_name` varchar(255) NOT NULL COMMENT '商品名称',`goods_price` decimal(10,2) NOT NULL COMMENT '商品价格',`goods_stock` int(11) NOT NULL COMMENT '商品库存',`goods_description` varchar(255) DEFAULT NULL COMMENT '商品描述',`goods_image` varchar(255) NOT NULL COMMENT '商品图片',PRIMARY KEY (`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品信息表';

MyBatis Plus配置

MyBatis Plus是MyBatis的增强工具,它简化了MyBatis操作,让开发人员更加专注于业务开发。我们在这里配置MyBatis Plus,以便让它在我们的项目中更好地发挥作用。

@Configuration
@MapperScan("com.example.dao")
public class MyBatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}

我们使用了@Configuration来注解这个类,表示这是一个配置类。在这个配置类中,我们使用了@MapperScan注解来扫描我们的Mapper接口,并将它们注入到Spring容器中。同时,我们还配置了一个PaginationInterceptor,它是MyBatis Plus提供的分页插件,让我们在分页查询的时候更加方便。

商品实体类

商品实体类对应了数据库中的goods表,包含了商品的所有信息字段。

@Data
public class Goods {private Integer goodsId;private String goodsName;private BigDecimal goodsPrice;private Integer goodsStock;private String goodsDescription;private String goodsImage;
}

我们使用了@Data注解来自动生成getter和setter方法,这样我们就可以在其他地方方便地使用商品实体类了。

商品DAO接口

我们使用MyBatis Plus提供的BaseMapper来实现商品信息的查询、添加、修改、删除等操作。

public interface GoodsMapper extends BaseMapper<Goods> {
}

我们只需要继承BaseMapper接口,MyBatis Plus就会自动帮我们生成相应的SQL语句了。

商品Service接口

商品Service接口对应了我们的业务需求,实现了对商品的增删改查等操作。

public interface IGoodsService {boolean addGoods(Goods goods);boolean deleteGoodsById(Integer goodsId);boolean updateGoods(Goods goods);Goods getGoodsById(Integer goodsId);List<Goods> getGoodsList();
}

我们定义了添加商品、删除商品、修改商品、查询商品、查询商品列表等几个方法。在这里,我们使用了boolean类型的返回值来表示这些操作是否执行成功。

商品Service实现类

现在我们来实现IGoodsService接口中的方法。

@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {@Overridepublic boolean addGoods(Goods goods) {return save(goods);}@Overridepublic boolean deleteGoodsById(Integer goodsId) {return removeById(goodsId);}@Overridepublic boolean updateGoods(Goods goods) {return updateById(goods);}@Overridepublic Goods getGoodsById(Integer goodsId) {return getById(goodsId);}@Overridepublic List<Goods> getGoodsList() {return list();}
}

我们使用了@Service注解来将这个类注入到Spring容器中。在这里,我们继承了ServiceImpl类,它是MyBatis Plus提供的Service实现类。我们的操作就是在这个类中实现的。

生成二维码

现在我们来讨论如何使用Java代码生成含商品信息的二维码。我们使用了zxing这个Java库来生成二维码。

public class QRCodeUtil {// 生成二维码的大小private static final int QRCODE_SIZE = 300;// 生成二维码的文件格式private static final String QRCODE_FORMAT = "png";// 二维码字体的设置private static final Map<EncodeHintType, Object> hints = new HashMap<>();static {hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);hints.put(EncodeHintType.MARGIN, 2);}/*** 生成二维码** @param content    二维码内容* @param image      logo文件* @param needCompress 是否需要压缩* @return 二维码图片* @throws IOException io异常* @throws WriterException WriterException异常*/public static BufferedImage createImage(String content, File image, boolean needCompress) throws IOException, WriterException {// 生成二维码的核心代码BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);// 构造一个空的bufferedImageint width = bitMatrix.getWidth();int height = bitMatrix.getHeight();BufferedImage imageBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 将矩阵数据画到bufferedImage中去for (int x = 0; x < width; x++) {for (int y = 0;y < height; y++) {imageBuffer.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}if (image != null) {// 在二维码中添加logoinsertImage(imageBuffer, image, needCompress);}return imageBuffer;}/*** 将图片添加到二维码中间** @param source       二维码图片* @param insertImage  logo图片* @param needCompress 是否需要压缩* @throws IOException io异常*/private static void insertImage(BufferedImage source, File insertImage, boolean needCompress) throws IOException {Image src = ImageIO.read(insertImage);int width = src.getWidth(null);int height = src.getHeight(null);if (needCompress) {if (width > QRCODE_SIZE * 0.2) {width = (int) (QRCODE_SIZE * 0.2);}if (height > QRCODE_SIZE * 0.2) {height = (int) (QRCODE_SIZE * 0.2);}Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = tag.getGraphics();g.drawImage(image, 0, 0, null);g.dispose();src = image;}// 插入logoGraphics2D graph = source.createGraphics();int x = (QRCODE_SIZE - width) / 2;int y = (QRCODE_SIZE - height) / 2;graph.drawImage(src, x, y, width, height, null);Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);graph.setStroke(new BasicStroke(3f));graph.draw(shape);graph.dispose();}
}

在这个类中,我们定义了一个createImage方法来生成二维码。它接受三个参数:二维码的内容、logo文件、以及是否需要压缩。

微信分享

在本文中,我们使用了WxShareUtil类来实现微信分享。WxShareUtil是一个封装好的Java类,它使用了微信提供的API来实现微信分享的功能。在这里,我们只需要调用这个类中的方法即可。

public class WxShareUtil {/*** 分享链接到朋友圈** @param title   链接标题* @param desc    链接描述* @param linkUrl 链接url* @param imgUrl  分享图片url*/public static void shareLinkToTimeline(String title, String desc, String linkUrl, String imgUrl) {WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();config.setAppId("your app id");config.setSecret("your app secret");WxMpService wxMpService = new WxMpServiceImpl();wxMpService.setWxMpConfigStorage(config);try {WxMpMaterialNews wxMpMaterialNews = new WxMpMaterialNews();WxMpMaterialNews.WxMpMaterialNewsArticle article = new WxMpMaterialNews.WxMpMaterialNewsArticle();article.setTitle(title);article.setDescription(desc);article.setUrl(linkUrl);article.setThumbMediaId(wxMpService.getMaterialService().mediaUpload(WxConsts.MaterialType.IMAGE, ResourceUtils.getFile(imgUrl)));wxMpMaterialNews.addArticle(article);wxMpService.getMaterialService().materialNewsUpload(wxMpMaterialNews);// 分享链接到朋友圈WxMpKefuMessage wxMpKefuMessage = WxMpKefuMessage.NEWS().addArticle(article).toUser("@all").build();wxMpService.getKefuService().sendKefuMessage(wxMpKefuMessage);} catch (WxErrorException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();}}
}

在这个类中,我们定义了一个shareLinkToTimeline方法来分享链接到朋友圈。它接受四个参数:链接标题、链接描述、链接url、以及分享图片url。在这里,我们使用了微信提供的Java SDK来实现分享操作。

商品Controller

现在我们来实现商品相关的Controller。

@RestController
@RequestMapping("/goods")
public class GoodsController {@Autowiredprivate IGoodsService goodsService;/*** 获取商品列表*/@GetMapping("/list")public List<Goods> getGoodsList() {return goodsService.getGoodsList();}/*** 添加商品*/@PostMappingpublic boolean addGoods(@RequestBody Goods goods) {return goodsService.addGoods(goods);}/*** 修改商品信息*/@PutMapping("/{goodsId}")public boolean updateGoods(@PathVariable Integer goodsId, @RequestBody Goods goods) {goods.setGoodsId(goodsId);return goodsService.updateGoods(goods);}/*** 删除商品*/@DeleteMapping("/{goodsId}")public boolean deleteGoods(@PathVariable Integer goodsId) {return goodsService.deleteGoodsById(goodsId);}/*** 生成商品二维码*/@GetMapping("/{goodsId}/qrcode")public ResponseEntity<InputStreamResource> generateQRCode(@PathVariable Integer goodsId) {try {// 获取商品信息Goods goods = goodsService.getGoodsById(goodsId);if (goods == null) {return ResponseEntity.notFound().build();}// 生成二维码File imageFile = new File("src/main/resources/static/images/qrcode/" + goodsId + ".png");if (!imageFile.exists()) {imageFile.getParentFile().mkdirs();QRCodeUtil.createImage(JSONObject.toJSONString(goods), null, true);}// 返回二维码的输入流FileInputStream fileInputStream = new FileInputStream(imageFile);return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).contentLength(imageFile.length()).body(new InputStreamResource(fileInputStream));} catch (Exception e) {e.printStackTrace();return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}}/*** 在微信中分享商品*/@GetMapping("/{goodsId}/share")public void shareGoods(@PathVariable Integer goodsId) {try {// 获取商品信息Goods goods = goodsService.getGoodsById(goodsId);if (goods == null) {return;}// 分享链接到朋友圈WxShareUtil.shareLinkToTimeline(goods.getGoodsName(), goods.getGoodsDescription(), "http://localhost:8080/goods/" + goodsId + "/qrcode", "src/main/resources/static/images/logo.png");} catch (Exception e) {e.printStackTrace();}}
}

在这个Controller中,我们实现了获取商品列表、添加商品、修改商品、删除商品、生成商品二维码、分享商品等几个操作。在生成商品二维码的时候,我们使用了QRCodeUtil来生成二维码图片,并将其保存到本地。在分享商品的时候,我们使用了WxShareUtil来实现微信分享操作。

总结

在本文中,我们学习了如何使用Spring Boot和MyBatis Plus来实现商品二维码的生成,并且能够用微信等工具扫码查看。我们通过实现商品信息的增删改查来满足我们的业务需求,并且通过Java代码生成二维码和微信分享来实现了商品信息的展示和分享等功能。这些操作都是在Spring Boot和MyBatis Plus的基础上完成的。

最后,希望本文能对大家有所帮助,也欢迎大家批评指正


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部