SpringBoot迷你微信小程序

SpringBoot+MyBatis搭一个简单的后台API接口给前台微信小程序使用
慕课网视频学习地址:
《SpringBoot+MyBatis搭建迷你小程序》:https://www.imooc.com/learn/945

假定一个简单的CRUD业务:管理一个区域列表,对其增删该查。
效果:
这里写图片描述

项目取名为:demo_springboot

初始化项目结构:

这里写图片描述

  • config :spring java config配置
  • dao:数据库访问接口
  • entity:数据库对象实体
  • handler:异常处理等。。
  • service:业务层
  • web:视图控制层
    DemoSpringbootApplication:SpringBoot启动类
后台接口

mysql数据库表:简单点,就一个,语句如下:

CREATE TABLE `tb_area` (
  `area_id` int(2) NOT NULL AUTO_INCREMENT,
  `area_name` varchar(255) NOT NULL COMMENT '区域名',
  `priority` int(11) NOT NULL DEFAULT '0' COMMENT '优先级',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`area_id`),
  UNIQUE KEY `UK_AREA` (`area_name`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

dao、mapper文件以及entity实体,使用mybatis generator逆向工程生成,就简单的增删查改,不再啰嗦。
只在dao里增加一个列表查询接口:

 List<TbArea> queryArea();

对于xml的sql:

<select id="queryArea" resultType="com.kay.entity.TbArea">
    SELECT <include refid="Base_Column_List" />
    FROM tb_area
    ORDER BY priority
  </select>

简单的pom.xml 依赖,这里就用c3p0连接池好了:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.kay</groupId>
	<artifactId>demo_springboot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo_springboot</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.34</version>
		</dependency>

		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>

			<plugin>
				<groupId>org.mybatis.generator</groupId>
				<artifactId>mybatis-generator-maven-plugin</artifactId>
				<version>1.3.2</version>
				<configuration>
					<verbose>true</verbose>
					<overwrite>true</overwrite>
					<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Spring配置,为了复习一下基础,这里就不简化配置了,直接写在java config里面:

手撸 datasource

package com.kay.config.dao;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * Created by kay on 2018/3/16.
 */
@Configuration
@MapperScan("com.kay.dao")
public class DataSourceConfiguration {

    @Value("${jdbc.driver}")
    private String jdbcDriverClass;

    @Value("${jdbc.url}")
    private String jdbcUrl;

    @Value("${jdbc.user}")
    private String jdbcUser;

    @Value("${jdbc.password}")
    private String jdbcPwd;

    @Bean(name="dataSource")
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(jdbcDriverClass);
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUser(jdbcUser);
        dataSource.setPassword(jdbcPwd);
        dataSource.setAutoCommitOnClose(false);
        return dataSource;
    }

}
package com.kay.config.dao;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * Created by kay on 2018/3/16.
 */
@Configuration
public class SqlSessionFacoryConfiguration {

    @Value("${mybatis_config_file}")
    private String mybatisConfigPath;

    @Value("${mapper_path}")
    private String mapperPath;

    @Value("${entity_package}")
    private String entityPackage;

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Bean("sqlSessionFactory")
    public SqlSessionFactoryBean creatSqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigPath));
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String packSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_URL_PREFIX;
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(packSearchPath+mapperPath));
        sqlSessionFactoryBean.setTypeAliasesPackage(entityPackage);
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }
}

Service也没什么好说了的,就是CRUD,直接贴Controller的接口吧:

package com.kay.web;

import com.kay.entity.TbArea;
import com.kay.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by kay on 2018/3/16.
 */
@RestController
@RequestMapping("/superadmin")
public class AreaController {

    @Autowired
    private AreaService areaService;

    /**
     * 列表查询
     * @return
     */
    @RequestMapping(value = "/listarea",method = RequestMethod.GET)
    private Map<String, Object> listArea() {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        List<TbArea> areas = areaService.queryArea();
        modelMap.put("areaList", areas);
        return modelMap;
    }

    /**
     * areaid 查询
     * @param areaId
     * @return
     */
    @RequestMapping(value = "/getareabyid",method = RequestMethod.GET)
    private Map<String, Object> getAreaById(Integer areaId) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        TbArea area = areaService.selectByPrimaryKey(areaId);
        modelMap.put("area", area);
        return modelMap;
    }

    /**
     * 添加area
     * @param area
     * @return
     */
    @RequestMapping(value = "/addarea",method = RequestMethod.POST)
    private Map<String, Object> addArea(@RequestBody TbArea area) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        boolean isSuccess = areaService.insert(area);
        modelMap.put("success", isSuccess);
        return modelMap;
    }

    /**
     * 修改
     * @param area
     * @return
     */
    @RequestMapping(value = "/modifyarea",method = RequestMethod.POST)
    private Map<String, Object> modifyArea(@RequestBody TbArea area) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        boolean b = areaService.updateByPrimaryKeySelective(area);
        modelMap.put("success", b);
        return modelMap;
    }

    /**
     * 删除area
     * @param areaId
     * @return
     */
    @RequestMapping(value = "/removearea",method = RequestMethod.GET)
    private Map<String, Object> removeArea(Integer areaId) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        boolean isSuccess = areaService.deleteByPrimaryKey(areaId);
        modelMap.put("success", isSuccess);
        return modelMap;
    }
}

好的,现在我们所有接口都有了,用 postman测试一下通过后,开始来写小程序。

迷你小程序

下载好微信开发者工具,扫码进入:
小程序的开发语法非常类似于 Vue,所以开发起来也很直观。
结构:
这里写图片描述
新建的2个page就是我们主要开发的地方(右键pages选择新建page,类似于建了一个组件)

  • list:列表页
  • operation:操作,添加、编辑、删除

list.js页面展示回调函数里面,调用我们刚才写好的后台列表接口:

/**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    var that=this;
    wx.request({
      url: 'http://127.0.0.1:8081/superadmin/listarea',
      method:'GET',
      data:{},
      success:function(res){
        var list=res.data.areaList;
        if(list==null){
          var toastText='获取数据失败'+res.data.errMsg;
          wx.showToast({
            title: toastText,
            icon:'',
            duration:2000 //弹出时间
          })
        }else{
          that.setData({
            list:list
          })
        }
      }
    })
  }

list.wxml 其实就是html,有一些小程序自己标签,具体看开发文档:

<!--pages/list/list.wxml-->
<view class="container">
  <view class='widget'>
    <text class='column'>编号</text>
    <text class='column'>校区名</text>
    <text class='column'>排名</text>
    <text class='link-column'>操作</text>
  </view>
  <scroll-view scroll-y="true">
    <view>
      <block wx:for='{{list}}'>
      <view class='widget'> 
        <text class='column'>{{item.areaId}}</text>
        <text class='column'>{{item.areaName}}</text>
        <text class='column'>{{item.priority}}</text>
        <view class='link-column'>
          <navigator class='link' url='../operation/operation?areaId={{item.areaId}}'>编辑</navigator> |
          <text class='link' bindtap='deleteArea' data-areaid='{{item.areaId}}' data-areaname='{{item.areaName}}' data-index='{{index}}'>删除</text>  
        </view>
        </view>      
      </block>
    </view>
  </scroll-view>
  <button type='primary' bindtap='addArea'>添加区域信息</button>
</view>

同理,list.wxss 就是css:

/* pages/list/list.wxss */
.container{
  height: 100%;
  display: table;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  padding-top: 10rpx;
  padding-bottom: 10rpx;
  text-align: center;
}

.widget{
  position: relative;
  margin-top: 5rpx;
  margin-bottom: 5rpx;
  padding-top: 10rpx;
  padding-bottom: 10rpx;
  padding-left: 40rpx;
  padding-right: 40rpx;
  border: #ddd 1px solid;
}

.column{
  width: 4rem;
  display: table-cell;
}

.link-column{
  width: 6rem;
  display: table-cell;
}

.link{
  color: blue;
  display: inline-table;

}

于是我们就有了这样一个页面,虽然简陋,但是好歹是从后台查到数据了啊(记得要先启动后台项目):
这里写图片描述

继续实现前台的添加,编辑,删除功能:
类似于vue组件的开发,贴上代码:(operation.js)

// pages/operation/operation.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    areaId:null,
    areaName:'',
    priority:'',
    addUrl:'http://127.0.0.1:8081/superadmin/addarea',
    modifyUrl:'http://127.0.0.1:8081/superadmin/modifyarea'
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var that=this;
    if(options.areaId==undefined){
      return;
    }
    that.setData({
      areaId: options.areaId,
    });
    wx.request({
      url: 'http://127.0.0.1:8081/superadmin/getareabyid',
      data:{"areaId":options.areaId},
      method:'GET',
      success:function(res){
        var area=res.data.area;
        if(area==undefined){
          var text='获取数据失败'+res.data.errMsg;
          wx.showToast({
            title: text,
            icon:'',
            duration:2000
          });
        }else{
          that.setData({
            areaName:area.areaName,
            priority:area.priority
          })
        }
      }
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
  
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  
  },

/**
 *  表单功能
 */
  formSubmit:function(e){
    var that=this;
    var formData=e.detail.value; //获取表数据
    var url=that.data.addUrl;  //默认url
    if(that.data.areaId!=undefined){
      formData.areaId=that.data.areaId;
      url = that.data.modifyUrl;
    }
    wx.request({
      url: url,
      data:JSON.stringify(formData),
      method:'POST',
      header:{
        'Content-Type':'application/json'
      },
      success:function(res){
        var result=res.data.success;
        var toastText="操作成功";
        if(result!=true){
          toastText="操作失败!"+res.data.errMsg;
        }
        wx.showToast({
          title: toastText,
          icon:'',
          duration:3000
        });
        
        wx.redirectTo({
          url: '../list/list',
        })
        // if(that.data.areaId=undefined){
        //   wx.redirectTo({
        //     url: '../list/list',
        //   })
        // }
      }
    })
  }
})

页面:

<!--pages/operation/operation.wxml-->
<view class='container'>
  <form bindsubmit='formSubmit' bindreset='formReset'>
    <view class='row'>
      <text>校区名:</text>
      <input type='text' name='areaName' placeholder='请输入校区名称' value='{{areaName}}'></input>
    </view>
    <view class='row'>
      <text>排名:</text>
      <input type='text' name='priority' placeholder='请输入排名' value='{{priority}}'></input>
    </view>
    <view class='row'>
      <button type='primary' form-type='submit'>提交</button>
      <button type='primary' form-type='reset'>重置</button>
    </view>
  </form>
</view>

样式:

/* pages/operation/operation.wxss */
.container {
  padding: 1rem;
  font-size: 0.9rem;
  line-height: 1.5rem;
}
.row {
  display: flex;
  align-items: center;
  margin-bottom: 0.8rem;
}
.row text {
  flex-grow: 1;
  text-align: right;
}
.row input {
  font-size: 0.7rem;
  flex-grow: 3;
  border: ipx solid #09c;
  display: inline-block;
  border-radius: 0.3rem;
  box-shadow: 0 0 0.15rem #aaa;
  padding: 0.3rem;
}
.row button {
  padding: 0.2rem;
  margin: 3rem 1rem;
}

迷你小程序开发完毕。

2018.5.16更新:
有同学需要源码,链接在这里:
https://github.com/LiuKay/wechat_springboot

2018.9.5更新:
慕课网视频学习地址:
《SpringBoot+MyBatis搭建迷你小程序》:https://www.imooc.com/learn/945

在使用IDEA开发微信小程序时,可以按照以下步骤进行操作: 1. 创建微信小程序项目。可以参考\[1\]中的链接,了解如何在IDEA中创建微信小程序项目。 2. 完成实体类的创建。在项目中,根据相关表的设计,创建对应的实体类。这些实体类将用于与数据库进行交互。\[2\] 3. 配置项目。在项目中,需要配置pom文件和MyBatis,以及Dao层的配置。这些配置将帮助项目正常运行。\[2\] 4. 实现接口和Mapper。根据项目需求,编写接口和对应的Mapper实现,用于实现增删改查等功能。\[2\] 5. 进行单元测试。对编写的接口进行单元测试,确保其功能正常。\[2\] 6. 连接数据库。使用SQLyog或其他数据库管理工具,创建一个名为demo的数据库,并在其中创建表。可以参考\[3\]中的链接,了解如何创建表。 以上是使用IDEA开发微信小程序的一般步骤。根据具体需求,可能还需要进行其他操作,如编写前端页面、实现登录功能等。希望以上信息对您有所帮助。 #### 引用[.reference_title] - *1* [前端(微信小程序)后端(IDEA-java)的交互通信——基于javaweb](https://blog.csdn.net/yilingpupu/article/details/122194182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [超详细、手把手使用IDEA+SpringBoot+MyBatis搭建微信迷你小程序](https://blog.csdn.net/weixin_42512266/article/details/100008493)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带着天使反上帝 - Kaybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值