查看原文
其他

三周学会小程序第六讲:登录优化和存储用户信息

码匠笔记 码匠笔记 2020-08-21

上一讲主要讲解了微信小程序登录的原理和实现《三周学会小程序第五讲:登录的原理和实现》,这一讲主要是对登录流程进行优化,同时登录成功后把用户信息存入服务器端数据库。这一讲涉及的服务端知识比较多,比如 Flyway、 H2、 MyBatis、 MyBatisGenerator等使用。

登录优化


1,把获取 code 的逻辑放到 app.js
app.js 的 onLaunch 方法是小程序的加载入口,这样可以全局的控制登录态和 code 的获取,首先判断当前用户是否已经有 token,如果有就不需要获取 code 和 登录逻辑。

  1. let token = wx.getStorageSync("token") || "";

  2.    this.globalData.token = token;

  3.    // 登录接口,获取到 code 存到 data 里面

  4.    // 用于获取到code传递给服务器端

  5.    if (!token){

  6.      wx.login({

  7.        success: codeInfo => {

  8.          console.log(codeInfo);

  9.          this.globalData.code = codeInfo.code;

  10.        }

  11.        });

  12.    }

可以通过微信的控制台查看 storage 的存储情况。

调用服务器端登录接口失败以后需要重新调用 app.login(); 方法,因为一个 code 只能使用一次。

H2


H2是一个超轻量级的数据库,引入一个 1.5M 的 jar 就可以运行使用,同时支持 JDBC,内嵌,内存和服务三种模式,这样引入 H2 以后我们就可以方便的在本地调试项目了。
第一步,直接在 
pom.xml 引入依赖

  1. <dependency>

  2.    <groupId>com.h2database</groupId>

  3.    <artifactId>h2</artifactId>

  4.    <version>1.4.196</version>

  5. </dependency>


第二步,直接在 application.yml 本地配置里面配置好,然后就可以在下文中的 MyBatis 里面使用配置连接池了

  1. db:

  2.  url: jdbc:h2:~/jiuask

  3.  username: sa

  4.  password: sa

  5.  driver: org.h2.Driver


当前采用的链接方式是内嵌连接,不需要启动服务,并且会保留数据,当然这种连接方式有一个问题,它只允许一个连接,所以每次你想通过其他工具读取数据的时候需要关掉程序的连接。

MyBatis


MyBatis 就不用详细讲解了,目前比较成熟的数据库框架,我们直接讲解配置,小编使用了 druid 连接池。
第一步,一如既往的引入 
pom.xml 文件

  1. <dependency>

  2.    <groupId>com.alibaba</groupId>

  3.    <artifactId>druid</artifactId>

  4.    <version>1.1.2</version>

  5. </dependency>

  6. <dependency>

  7.    <groupId>org.mybatis.spring.boot</groupId>

  8.    <artifactId>mybatis-spring-boot-starter</artifactId>

  9.    <version>1.3.0</version>

  10. </dependency>

直接在 applicationContext.xml 里面配置即可。

  1. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

  2.    <!-- 基本属性 url、user、password -->

  3.    <property name="url" value="${db.url}"/>

  4.    <property name="username" value="${db.username}"/>

  5.    <property name="password" value="${db.password}"/>

  6.    <!-- 配置初始化大小、最小、最大 -->

  7.    <property name="initialSize" value="1"/>

  8.    <property name="driverClassName" value="${db.driver}"/>

  9.    <property name="minIdle" value="1"/>

  10.    <property name="maxActive" value="1"/>

  11.    <!-- 配置获取连接等待超时的时间 -->

  12.    <property name="maxWait" value="60000"/>

  13.    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

  14.    <property name="timeBetweenEvictionRunsMillis" value="60000"/>

  15.    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

  16.    <property name="minEvictableIdleTimeMillis" value="300000"/>

  17.    <property name="validationQuery" value="SELECT 'x'"/>

  18.    <property name="testWhileIdle" value="true"/>

  19.    <property name="testOnBorrow" value="false"/>

  20.    <property name="testOnReturn" value="false"/>

  21.    <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->

  22.    <property name="poolPreparedStatements" value="false"/>

  23.    <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>

  24.    <!-- 配置监控统计拦截的filters -->

  25.    <property name="filters" value="stat"/>

  26. </bean>

  27. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

  28.    <property name="dataSource" ref="dataSource"/>

  29.    <!-- 自动扫描mapping.xml文件,**表示迭代查找,也可在sqlMapConfig.xml中单独指定xml文件-->

  30.    <property name="mapperLocations" value="classpath:mybatis/mapping/*.xml"/>

  31. </bean>

  32. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

  33.    <property name="basePackage" value="com.codedrinker.dao"/>

  34.    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>

  35. </bean>

上面注释很全,
dataSource 是数据源。
sqlSessionFactory 是 session 工厂,用户注入 mapper 使用。
MapperScannerConfigurer 是为了自动扫描对应包下面的 Mapper 装置到 Bean 里面。如果这个地方不明白可以看一下小编之前的一篇文章
《从 Spring 集成 MyBatis 浅析 Java动态代理》

值得注意的地方是 mapperLocations 配置的路径,是不是每次都需要我们手写 *.xml和 N 多对象啊?答案是不需要的,我们使用 MyBatisGenerator 自动生成。怎么生成?看下文。

Flyway

Flyway 是一个数据库 Migration 工具,为什么引入这个工具呢?举个例子,如果你有3个环境:开发、UAT和线上;你有4个开发人员,每个人有自己的一个开发环境,这些环境都有一个自己的数据库,那么你是不是每次有数据库变更都需要让他们去执行以下脚本?不仅麻烦而且出错率特别高。
那么 
Flyway 就应运而生,它可以帮你记录,执行你的 SQL 变更,只需要引入它的依赖,就可以帮你精准的维护数据库脚本的变更。使用 Flyway 方式有多种,命令行、Maven命令、Java API和Spring 配置,我们采用 Spring 配置的方式,这样不需要每一个部署环境安装命令行或者是 Maven 工具。具体操作如下
第一步还是添加依赖到 
pom.xml

  1. <dependency>

  2.    <groupId>org.flywaydb</groupId>

  3.    <artifactId>flyway-core</artifactId>

  4.    <version>5.2.3</version>

  5. </dependency>

第二步配置 applicationContext.xml,在刚才配置的地方追加如下配置

  1. <bean id="flywayConfig" class="org.flywaydb.core.api.configuration.ClassicConfiguration">

  2.        <property name="dataSource" ref="dataSource"/>

  3. </bean>

  4. <bean id="flyway" class="org.flywaydb.core.Flyway" init-method="migrate">

  5.    <constructor-arg ref="flywayConfig"/>

  6. </bean>

flywayConfig 是配置 dataSource 给 flyway,这样他们就可以共用数据源了。
flyway 是执行 migrate 的入口。
最后需要在 
sqlSessionFactory 添加一个 depends-on="flyway" 这样便可以在创建工厂的时候执行数据库脚本了。

第三步,配置数据库脚本, Flyway 命令运行的时候会默认找 resources/db/migration 文件下面的 *.sql 文件,因为数据库脚本执行是需要有顺序并且唯一,所以数据库脚本有一个命名规则,就是从 V1__**开始,依次是 V2__**。比如小编目前正要创建一个 user表,所以我的命名需要是 V1__Create_user_table.sql

第四步,直接运行项目 Application.java 文件,我们会在控制台看到如下打印信息,说明成功执行了脚本。

  1. Flyway 5.2.3 by Boxfuse

  2. Database: jdbc:h2:~/jiuask (H2 1.4)

  3. Validated 1 migration (execution time 00:00.029s)

  4. Creating Metadata table: "PUBLIC"."schema_version"

  5. Current version of schema "PUBLIC": << Empty Schema >>

  6. Migrating schema "PUBLIC" to version 1 - Create user table

  7. Successfully applied 1 migration to schema "PUBLIC" (execution time

那么怎么验证一下呢?我们可以通过 Idea 自带的数据库连接工具按照如下方式连接一下(记得关闭项目)

便可以看到我们刚才创建的user表,同时会有一个 schema_version表,这个表就是 flyway 用于存储数据库脚本是否已经执行过的依据,避免重复执行和错误的修改。所以后面你需要修改数据库,必须添加新的脚本,不能修改原有的。

MyBatis-Generator

MyBatis-Generator 的目的就是通过创建好的数据库,逆向生成 model、 mapper 和 xml 的工具,这样可以大大减少我们的工作量。
第一步,添加 
Maven 的插件,用于运行 generator

  1. <plugin>

  2.    <groupId>org.mybatis.generator</groupId>

  3.    <artifactId>mybatis-generator-maven-plugin</artifactId>

  4.    <version>1.3.7</version>

  5.    <configuration>

  6.        <configurationFile>${project.basedir}/src/main/resources/generatorConfig.xml</configurationFile>

  7.        <verbose>true</verbose>

  8.        <overwrite>true</overwrite>

  9.    </configuration>

  10. </plugin>

第二步,配置 generatorConfig.xml 文件,该文件主要是用于指定 model、 mapper和 xml 等文件的生成路径和规则,详细信息就不罗列了,可以直接参照源码。重点讲解一下 classPathEntry 需要指定一下你当前使用的 h2.jar 的存放位置。 jdbcConnection 和上文中我们配置的 h2 的地址一致。后面如果有多个数据库表,直接添加 table 标签即可。
第三步,运行如下命令,就会自动生成对应的文件。

  1. mvn mybatis-generator:generate

服务端存储 Token 和 用户信息

截止到上面基础工作已经全部搞定,下面我们实现登录成功存储数据库的逻辑,这便是非常简单的事情。

  1. @Service

  2. public class UserService {

  3.    @Autowired

  4.    private UserMapper userMapper;

  5.    public void saveOrUpdate(User user) {

  6.        UserExample example = new UserExample();

  7.        example.createCriteria().andOpenidEqualTo(user.getOpenid());

  8.        List<User> users = userMapper.selectByExample(example);

  9.        if (users != null && users.size() != 0) {

  10.            user.setGmtModified(System.currentTimeMillis());

  11.            userMapper.updateByExampleSelective(user, example);

  12.        } else {

  13.            user.setGmtCreate(System.currentTimeMillis());

  14.            user.setGmtModified(System.currentTimeMillis());

  15.            userMapper.insert(user);

  16.        }

  17.    }

  18. }

一段代码就搞定了这件事情。 UserExample.createCriteria 的方法是 generator 提供的可以组装 sql 的工具,上面的逻辑是先通过 openid 查询数据库中是否已经存在,如果存在就更新,否则创建。
这样以后重启服务器,再次点击小程序的登录按钮,你会看到神奇的一幕,提示“登录成功”,这样你的第一个前后端交互小程序就搞定了。

作业

好久没有留作业了,这次的作业就是如果你使用的是 MySQL 数据库,那么尝试使用 MySQL 把项目运行起来。

源码

小程序源码地址,Tag V6
https://github.com/codedrinker/jiuask
服务端源码地址,Tag V6
https://github.com/codedrinker/jiuask-server


我是浪漫的分割线


问答

如果您对本系列文章有兴趣,欢迎置顶本订阅号,第一时间获取更新。

如果有任何问题,欢迎留言,小编很热衷和大家一起讨论技术问题。

另外小编创建了一个技术交流群,请添加小编微信,切记备注“小程序”,小编拉你进去。【只讨论技术,非诚勿扰】

最好的赞赏是关注和分享

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存