前言
二维码已经成为现代商业的常用工具,二维码不仅能够实现快速付款,还能够实现商品信息的展示。在这篇文章中,我们将使用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 {
@Bean
public 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 {
@Override
public boolean addGoods(Goods goods) {
return save(goods);
}
@Override
public boolean deleteGoodsById(Integer goodsId) {
return removeById(goodsId);
}
@Override
public boolean updateGoods(Goods goods) {
return updateById(goods);
}
@Override
public Goods getGoodsById(Integer goodsId) {
return getById(goodsId);
}
@Override
public 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);
// 构造一个空的bufferedImage
int 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) {
// 在二维码中添加logo
insertImage(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;
}
// 插入logo
Graphics2D 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 {
@Autowired
private IGoodsService goodsService;
/**
* 获取商品列表
*/
@GetMapping("/list")
public List<Goods> getGoodsList() {
return goodsService.getGoodsList();
}
/**
* 添加商品
*/
@PostMapping
public 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的基础上完成的。
最后,希望本文能对大家有所帮助,也欢迎大家批评指正