安卓+SpringBoot短信验证

安卓+SpringBoot短信验证

原理

客户端进入登陆页面,输入手机号,点击"获取验证码",这时候客户端会先做一个判断,看手机号是不是符合规范,不是的话就弹出提示框提示"手机号不规范,请重新输入",如果是规范的手机号,客户端就带上手机号作为参数向服务端发送请求,服务端接收到这个请求就调用发送短信的业务层(官方有工具类,输入参数即可),随机生成四位数字,然后可以以这个手机号为key,验证码为value存在redis,设置一个过期时间(一般都是五分钟),然后这个业务层会向这个手机号发送这个随机生成的字符串。

客户端收到短信输入验证码,点击登录,客户端又带上手机号和验证码向服务端发送请求,服务端收到请求首先看redis是不是存在这样的"以客户端提交的这个手机号为key,验证码为value"的键值对,不存在的话那就是验证码过期了,或者手机号,验证填错了,返回验证错误的信息给客户端;如果存在的话,那就验证成功了,那么接下来还要做一个判断,要看看这个手机号注册过没有,在用户注册表中查询有没有这个手机号对应的用户,有的话就是注册过的,那就返回客户端登陆成功的标识,客户端成功登录跳转首页;如果用户注册表中没有对应的用户,可以返回客户端没有注册的信息,也可以顺便用这个手机号注册一个信息,现在一般都是这种流程,注册之后,同样返回客户端登录成功的信息,客户端登陆成功,跳转首页。

流程图:

在这里插入图片描述

步骤:

客户端

这是安卓端登录页的代码:

package com.yunyou.fragment.Login;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yunyou.R;
import com.yunyou.entity.Scenics.JsonRootBean;
import com.yunyou.fragment.PersonalFragment;
import com.yunyou.module.MainActivity;
import com.yunyou.utils.YyHttpRequestOrGetDataFromNet;
import com.yunyou.utils.YySharedPrefUtility;

import org.json.JSONObject;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Create by xie
 * Date: 2021/10/11
 * Time: 0:03
 **/
public class LoginByIdentityCodeFragment extends Fragment implements View.OnClickListener{

    private String phone;
    private String vertify;
    private String jsonLoginningInfo;
    private JsonRootBean jsonRootBean;//自己写的实体类,格式化数据
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.activity_login_by_identitycode, container, false);
        Button vertify = view.findViewById(R.id.vertify);
        Button loginvertify = view.findViewById(R.id.loginvertify);
        vertify.setOnClickListener(this);
        loginvertify.setOnClickListener(this);


        return view;
    }
    //这是碎片的实例化
    public static LoginByIdentityCodeFragment newInstance() {
        Bundle bundle = new Bundle();
        LoginByIdentityCodeFragment fragment = new LoginByIdentityCodeFragment();
        fragment.setArguments(bundle);
        return fragment;
    }
    //这是登录的方法
    public void login(){
        EditText phoneEditView = getView().findViewById(R.id.phone_account);
        phone = phoneEditView.getText().toString();
        EditText vertifyEditView = getView().findViewById(R.id.edit_passwordvertify);
        vertify = vertifyEditView.getText().toString();
        //正确的手机号
        if(isTruePhone(phone)){
//            Toast.makeText(getActivity(),"验证码已发送至"+phone+"五分钟内有效,注意查收哦!",Toast.LENGTH_LONG).show();

            try{
                //后端验证登录的接口
                String loginurl = getString(R.string.url2) + "vertify/"+phone+"/"+vertify;;


                jsonLoginningInfo = YyHttpRequestOrGetDataFromNet.doGetJsonStringFromThread(loginurl, "");
                Gson gson = new Gson();
                jsonRootBean = gson.fromJson(jsonLoginningInfo,new TypeToken<JsonRootBean>(){}.getType());
//token 存储

                YySharedPrefUtility.setParam(getActivity(),YySharedPrefUtility.Token,
                        jsonRootBean.getContent().getToken());
                System.out.println("token:"+jsonRootBean.getContent().getToken());
                System.out.println("token:"+jsonRootBean.getMsg());


            }
            catch (Exception e){ e.printStackTrace();}

            //密码正确:服务端返回1
            if (jsonRootBean.getMsg().equals("registerSuccess")) {
                Toast.makeText(getActivity(), "登陆成功", Toast.LENGTH_SHORT).show();
                YySharedPrefUtility.setParam(getActivity(),
                        YySharedPrefUtility.ACCOUNTID, phone);//用户名存起来
                startActivity(new Intent(getActivity(), MainActivity.class));//登录成功跳转首页

            }
            //用户名不存在或密码错误:服务端返回-1
            else {
                Toast.makeText(getActivity(), "手机号不存在或验证码不正确", Toast.LENGTH_SHORT).show();
            }


        }//验证码为空
        else if(vertify.equals("")){
            Toast.makeText(getActivity(),"验证码不能为空",Toast.LENGTH_LONG).show();
        }//不是合格的手机号
        else{
            Toast.makeText(getActivity(),"不是合格的手机号",Toast.LENGTH_LONG).show();
        }
    }
    
    
    
    
    //发送验证码
    public void sendSms(){
        EditText phoneEditView = getView().findViewById(R.id.phone_account);
        phone = phoneEditView.getText().toString();
        if(!isTruePhone(phone)){
            Toast.makeText(getActivity(),"不是合格的手机号"+phone,Toast.LENGTH_LONG).show();
        }
        else{
            //这里请求url
            try{
                String loginByVertifyurl = getString(R.string.url2) + "send/"+phone;
                
                String result = YyHttpRequestOrGetDataFromNet.doGetJsonStringFromThread(loginByVertifyurl,"cdvdv");
                Toast.makeText(getActivity(),"验证码已发送至"+phone+"五分钟内有效,注意查收哦!",Toast.LENGTH_LONG).show();

            }
            catch (Exception e){ e.printStackTrace();}
        }
    }
    
    
    //验证是否为合格的手机号
    public Boolean isTruePhone(String phone){

//        ^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))d{8}$
//        String PHONE_PATTERN="^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17([0,1,6,7,]))|(18[0-2,5-9]))\d{8}$";
        String PHONE_PATTERN = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147)|(19[0-9]))\d{8}$";
        boolean isPhone = Pattern.compile(PHONE_PATTERN).matcher(phone).matches();
        if(isPhone)return true;
        else return false;
    }
    /**
     * 8-16个字符,不包含空格,必须包含数字,字母或字符至少两种
     * @param password
     * @return
     */
    public  boolean isPassword(String password){
        String pattern = "(?!.*\s)(?!^[\u4e00-\u9fa5]+$)(?!^[0-9]+$)(?!^[A-z]+$)(?!^[^A-z0-9]+$)^.{8,16}$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(password);
        return m.matches();
    }

    /**
     * 验证是否为邮箱
     * @param email
     * @return
     */
    public  boolean isEmail(String email){
        String pattern = "^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(email);
        return m.matches();
    }
    
    //点击事件
    @Override
    public void onClick(View v) {
        switch (v.getId()){
                //发送验证码
            case R.id.vertify:
                sendSms();
                break;
                //登录
            case R.id.loginvertify:
                login();
                break;
        }
    }
}

服务端

配置redis

服务端为了实现验证码过期的逻辑,要用到redis,那首先就要配置redis,我之前用ssm项目配置redis一直有问题,于是就叫别人帮忙把项目转成了SpringBoot开发

1.下载redis

最好在github,在官网现在只能下载压缩包,压缩文件用也是可以用,但是每次都要手动开启redis服务,重新设置redis密码买比较繁琐,最好在github下载二进制文件安装包,地址如下:

https://github.com/tporadowski/redis/releases

下载后进入redis安装目录进入redis.windows.conf

在这里插入图片描述

找到这一行,改成你的密码

在这里插入图片描述

然后可能要在redis安装目录下cmd输入redis-server.exe redis.windows.conf执行这个配置文件才会生效

反正最后在双击redis-cli 输入"auth 123456"(自己的密码)出现OK就是设置成功

2.添加依赖

<!--redis-Jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <!--spring-reids-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

3.写redis配置文件

applecation.properties

spring.redis.host=localhost
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=123456
#spring.redis.database=0
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000

RedisConfig配置类读取applecation.properties信息

package com.yunyou.yunyoutest.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisConfig{

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWait;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisProvider() {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxIdle(maxIdle);
            config.setMaxWaitMillis(maxWait);
            config.setMaxTotal(maxActive);
            config.setMinIdle(minIdle);


            JedisPool jedisPool = new JedisPool(config, host, port, timeout, password);
            System.out.println("连接redis" + jedisPool.getResource().toString());
            return jedisPool;
        }catch (Exception e){
            System.out.println(e);
            System.out.println(host+port+timeout+ password);
            System.out.println("redis连接失败");
            return null;
        }
    }
}

还有一个redis的工具类

package com.yunyou.yunyoutest.util.Redis;




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

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

@Component
public class JedisUtils {
    @Autowired(required = false)
    private JedisPool jedisPool;

    /**
     * 获取JedisPool连接池实例
     *
     * @return JedisPool连接池实例(通过Spring生成)
     */
    public JedisPool getJedisPool() {
        return jedisPool;
    }

    /**
     * 获取Jedis实例
     *
     * @return Jedis实例
     */
    public Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * Redis设置键值对
     *
     * @param key   键
     * @param value 值
     * @return 值
     */
    public String set(String key, String value) {
        return action(jedis -> jedis.set(key, value));
    }

    /**
     * Redis获取键对应的值
     *
     * @param key 键
     * @return 值
     */
    public String get(String key) {
        return action(jedis -> jedis.get(key));
    }

    /**
     * Redis是否存在当前键
     *
     * @param key 查询的键
     * @return 是否存在
     */
    public Boolean exists(String key) {
        return action(jedis -> jedis.exists(key));
    }

    /**
     * 设置Key的过期时间,单位以秒计
     *
     * @param key     键
     * @param seconds 秒数
     * @return 1为设置成功,0为设置失败(Jedis返回的就是Long,不知道为嘛要用Long)
     */
    public Long expire(String key, int seconds) {
        return action(jedis -> jedis.expire(key, seconds));
    }

    /**
     * 返回key的过期时间
     *
     * @param key 键
     * @return 返回过期时长(以秒为单位) 若不存在该key或该key不存在过期时间则返回-1
     */
    public Long ttl(String key) {
        return action(jedis -> jedis.ttl(key));
    }

    /**
     * 将key对应的值+1
     * (由于在Redis中都是字符串,所以Redis会将字符串转换为最大64bit的有符号整数类型后再增加)
     * (如果key不存在,则会将key对应的值设置为0后再执行增加操作)
     * (如果value的类型错误,则会异常报错!)
     *
     * @param key 键
     * @return 返回增加的结果,
     */
    public Long incr(String key) {
        return action(jedis -> jedis.incr(key));
    }

    /**
     * Redis设置Hash
     *
     * @param key   键
     * @param value 值(一个Map)
     * @return 存在则更新并返回0,不存在则新建并返回1
     */
    public Long hSet(String key, Map<String, String> value) {
        return action(jedis -> jedis.hset(key,value));
    }

    /**
     * Redis获取Hash
     *
     * @param key 键
     * @return hashMap
     */
    public Map<String, String> hGet(String key) {
        return action(jedis -> jedis.hgetAll(key));
    }

    /**
     * Redis设置hashMap
     *
     * @param key   map对应的键
     * @param field map中键
     * @param value map中键对应的值
     * @return 如果存在此map且存在此field,则更新数据并返回0,否则创建数据并返回1
     */
    public Long hSet(String key, String field, String value) {
        return action(jedis -> jedis.hset(key, field, value));
    }

    /**
     * Redis获取Hash
     *
     * @param key   键
     * @param field map中的键
     * @return map中键对应的值
     */
    public String hGet(String key, String field) {
        return action(jedis -> jedis.hget(key, field));
    }

    /**
     * Redis删除Hash
     *
     * @param key   键
     * @param field map中可变数量的键
     * @return 如果field在map中存在则删除并返回1,否则不做任何操作返回0
     */
    public Long hDel(String key, String... field) {
        return action(jedis -> jedis.hdel(key, field));
    }

    /**
     * Redis判断是否存在
     *
     * @param key   键
     * @param field map中的键
     * @return 判断key对应的map中是否存在field的键
     */
    public Boolean hExists(String key, String field) {
        return action(jedis -> jedis.hexists(key, field));
    }

    /**
     * Redis获取hash对应的val
     *
     * @param key 键
     * @return val的列表
     */
    public List<String> hVals(String key) {
        return action(jedis -> jedis.hvals(key));
    }

    /**
     * Redis删除key对应的数据
     *
     * @param key 键
     * @return 存在就删除且返回1,不存在不做任何操作返回0
     */
    public Long del(String... key) {
        return action(jedis -> jedis.del(key));
    }

    /**
     * 封装一部分重复操作,使jedis操作更简便
     */
    public <T> T action(RedisAction<T> action) {
        Jedis jedis = jedisPool.getResource();
        T v = action.action(jedis);
        jedis.close();
        return v;
    }

    public interface RedisAction<T> {
        T action(Jedis jedis);
    }
}

到这里redis就配置好了

这是服务端发送短信的代码:

业务层

package com.yunyou.yunyoutest.service.impl;

import java.util.Map;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.yunyou.yunyoutest.service.SendSms;
//这里最好申请一个阿里云账号,会有对应的信息都填到这里面
@Service
public class SendSmsImpl implements SendSms{

   @Override
    public Boolean sendMessage(String phoneNum,Map<String, Object> map) {
        System.out.println(JSONObject.toJSONString(map));
        //连接阿里云
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
              "***********************", "**************************");
        IAcsClient client = new DefaultAcsClient(profile);

        //构建请求
        CommonRequest request = new CommonRequest();

        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");//不要动
        request.setSysVersion("2017-05-25");//不要动
        request.setSysAction("SendSms");//不要动

//        自定义参数(手机号,验证码。签名。模板!)
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phoneNum);
        request.putQueryParameter("SignName", "*********");
        request.putQueryParameter("TemplateCode", "***********");

        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(map));
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            return response.getHttpResponse().isSuccess();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return false;
    }

}

控制层

package com.yunyou.yunyoutest.controller;

import com.yunyou.yunyoutest.service.SendSms;

import com.yunyou.yunyoutest.util.Redis.JedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Controller

   public class SendSmsController {
       @Autowired
       private SendSms sendMessage;//业务调用
      @Autowired
      private JedisUtils jedisUtils;
       String code;

       @RequestMapping(value="send/{phone}",method=RequestMethod.GET)
       @ResponseBody
       public String send(@PathVariable("phone") String phone){

         //调用发送方法(模拟真是业务redis)

         //如果同样的手机号在规定时间内还申请了
         if (jedisUtils.exists("code"+phone)){
            System.out.println("这个手机号码一分钟之内申请了"+jedisUtils.get("code"+phone));
            return "This phone'code in useful time!";
           }

         //生成验证码并存储到redis中
//         code = UUID.randomUUID().toString().substring(0, 5);
           int code1 = (int)(Math.random()*9999)+100;
           code = Integer.toString(code1);

           HashMap<String,Object> map = new HashMap<>();

           map.put("code",code);
         //flag是为了判断业务层是否发送成功
         Boolean flag = sendMessage.sendMessage(phone,map);
           if (flag){
               //设置新的验证码存入Redis
            System.out.println("设置新的验证码存入Redis");
              jedisUtils.set("code"+phone,code);
              jedisUtils.expire("code"+phone,300);

            return "success to send "+phone+"!";
           }
           return "发送失败!";
       }
         
       
}

业务端处理登录的接口

控制层 接收手机号和验证码,看redis存不存在这样的键值对,存在就看数据库里这个手机号有没有注册,没有注册就注册一下,最后都给客户端返回登录成功的标识,redis不存在就返回验证码错误的消息给客户端

package com.yunyou.yunyoutest.controller;

import com.yunyou.yunyoutest.entity.JsonRootBean;
import com.yunyou.yunyoutest.entity.LoginToken;
import com.yunyou.yunyoutest.entity.userLoginningInfo.JsonUserBaseInfoPage;
import com.yunyou.yunyoutest.entity.userLoginningInfo.JsonUserLoginningPage;
import com.yunyou.yunyoutest.entity.v_U_userLoginning_info;
import com.yunyou.yunyoutest.service.UserLoginningInfoService;
import com.yunyou.yunyoutest.util.Redis.JedisUtils;
import com.yunyou.yunyoutest.util.jwt.JWTUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

@Controller
public class UserLoginningInfoController {
    @Autowired
    private UserLoginningInfoService uService;
    @Autowired
    private JedisUtils jedisUtils;

    @RequestMapping(value="vertify/{phone}/{vertifycode}",method=RequestMethod.GET)
    @ResponseBody
    public JsonRootBean send(@PathVariable String phone,@PathVariable String vertifycode) {
        JsonRootBean uJsonBaseObject;
        //手机号,验证码正确,看在不在缓存里
        if (jedisUtils.exists("code" + phone) && vertifycode.equals(jedisUtils.get("code" + phone))) {
            //判断一下这是新用户还是注册了的用户
            HashMap<String, Object> paramsMap = new HashMap<String, Object>();
            paramsMap.put("accountid", phone);
            uJsonBaseObject = new JsonRootBean();
            JsonUserBaseInfoPage jsonUserBaseInfoPage = uService.getUserBaseInfo(paramsMap);
            System.out.println(jsonUserBaseInfoPage.getUserBaseInfo() + "穷叉叉");
//            return uJsonBaseObject;
//            没有注册过的,这里进行注册

            if(jsonUserBaseInfoPage.getUserBaseInfo().isEmpty()) {
                System.out.println("没有注册过的");
                //明天的任务,怎么注册呢,调用注册的业务层,sql语句写好,多表增添数据
                //像一般的,userbaseinfo,userlogininginfo,registerinfo
                HashMap<String, Object> registerMap = new HashMap<String, Object>();
                registerMap.put("accountid", phone);
                registerMap.put("credential", "123456");
                registerMap.put("typename", "手机号");
                registerMap.put("rolename", "学员");
                uService.registerByPhone(registerMap);
                uJsonBaseObject.setMsg("registerSuccess");
            }//注册过的,直接登录
            else {
                System.out.println("已将注册的");
                uJsonBaseObject.setMsg("loginSuccess");
            }


            HashMap<String, String> payload = new HashMap<String, String>();
            payload.put("accountid", phone);
            String token = JWTUtils.getToken(payload);
            LoginToken loginToken = new LoginToken();
            loginToken.setToken(token);
            uJsonBaseObject.setContent(loginToken);
            return uJsonBaseObject;


        } else {


            uJsonBaseObject = new JsonRootBean();
            uJsonBaseObject.setMsg("loginError");
            uJsonBaseObject.setStatus(-1);
            return uJsonBaseObject;

        }

    }


}

业务层

package com.yunyou.yunyoutest.service.impl;

import com.yunyou.yunyoutest.dao.v_U_userLoginning_infoMapper;
import com.yunyou.yunyoutest.entity.userLoginningInfo.JsonUserBaseInfoPage;
import com.yunyou.yunyoutest.entity.userLoginningInfo.JsonUserLoginningPage;
import com.yunyou.yunyoutest.entity.v_U_userLoginning_info;
import com.yunyou.yunyoutest.service.UserLoginningInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class UserLoginningInfoServiceImpl implements UserLoginningInfoService{

    @Autowired
    private v_U_userLoginning_infoMapper uMapper;

    

    @Override
    public Boolean registerByPhone(HashMap<String, Object> paramsMap) {
        int isinsertsuccess = uMapper.registerByPhone(paramsMap);
        System.out.println(isinsertsuccess);
        return true;
    }

}

mapper层,这里是用了存储过程,因为设计多张用户表的操作,就用存储过程

<select id="registerByPhone" parameterType="java.util.Map" resultType="int">
    declare @accountid varchar(20) = #{accountid}
    declare @credential varchar(20) = #{credential}
    declare @typename varchar(10) = #{typename}
    declare @rolename varchar(30) = #{rolename}
    exec dbo.RegisterByPhone @accountid,@credential,@typename,@rolename
</select>

最后不满足的就是页面太不好看了,我对页面设计真是不行,有问题欢迎在评论区!

在这里插入图片描述

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>