SSM框架项目【米米商城】18-25 登录业务逻辑的实现

开始时间:2022-03-02
课程链接:米米商城

mybatis逆向工程

mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java、mapper.xml、pojo…)

逆向工程代码源

网盘链接:https://pan.baidu.com/s/1ssifbwCDGgNbNCxFJhjuDg 提取码:ozwv
在这里插入图片描述
要将其放在纯英文路径下才行
然后导入到idea里面

配置generatorConfig
主体不要动,只把相应路径和数据库密码修改一下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mimissm?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true" userId="root"
			password="333">
		</jdbcConnection>
		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="BUPT.pojo"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="BUPT.mapper"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="BUPT.mapper"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 指定数据库表 -->
		<table schema="" tableName="admin"></table>
		<table schema="" tableName="product_info"></table>
		<table schema="" tableName="product_type"></table>

	</context>
</generatorConfiguration>

然后打开GeneratorSqlmap

package com.oracle.mybatis.tools;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

public class GeneratorSqlmap {

	public void generator() throws Exception{

		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		//指定 逆向工程配置文件
		File configFile = new File("generatorConfig.xml"); 
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
				callback, warnings);
		myBatisGenerator.generate(null);

	} 
	public static void main(String[] args) throws Exception {
		try {
			GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
			generatorSqlmap.generator();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

执行主方法
这里有几个注意点
一个是要在数据库中有对应的表,一个是数据库要处于链接状态
还需要注意,新导入的这个逆向工程,记得选中jdk,我因为没选jdk导致通篇爆红
执行完后得到以下代码
在这里插入图片描述

MD5加密算法的演示

我们为了安全,是不会将密码以明文形式显示的
注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对

先在我们的utils包里面添加MD5的执行类

    /**
     * 1.MD5(message-digest algorithm 5)信息摘要算法,
     *   它的长度一般是32位的16进制数字符串(如81dc9bdb52d04dc20036dbd8313ed055)
     * 2.由于系统密码明文存储容易被黑客盗取
     * 3.应用:注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
     *       登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对
     * 4.md5不可逆,即没有对应的算法,从产生的md5值逆向得到原始数据。
     *   但是可以使用暴力破解,这里的破解并非把摘要还原成原始数据,如暴力枚举法。
     *
     */
package BUPT.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

    public final static String getMD5(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("SHA");//创建具有指定算法名称的摘要
            md.update(str.getBytes());                    //使用指定的字节数组更新摘要
            byte mdBytes[] = md.digest();                 //进行哈希计算并返回一个字节数组

            String hash = "";
            for(int i= 0;i<mdBytes.length;i++){           //循环字节数组
                int temp;
                if(mdBytes[i]<0)                          //如果有小于0的字节,则转换为正数
                    temp =256+mdBytes[i];
                else
                    temp=mdBytes[i];
                if(temp<16)
                    hash+= "0";
                hash+=Integer.toString(temp,16);         //将字节转换为16进制后,转换为字符串
            }
            return hash;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

然后在test下进行一个小测试
在这里插入图片描述

package BUPT.Test;

import BUPT.utils.MD5Util;
import org.junit.Test;

public class MyTest {
    @Test
    public void testMD5() {
        String mi = MD5Util.getMD5("000000");
        System.out.println("加密后的密码为:" + mi);
    }
}

6个0的执行结果为

加密后的密码为:c984aed014aec7623a54f0591da07a85fd4b762d

这正好就是我们数据库开始存入的数据
在这里插入图片描述

登录的业务逻辑层实现

在service包下进行代码编写
接口类
直接返回一个对象,方便后续灵活调用

package BUPT.service;

import BUPT.pojo.Admin;

public interface AdminService {
    Admin login(String name, String pwd);
}

接口类的实现类

package BUPT.service;

import BUPT.mapper.AdminMapper;
import BUPT.pojo.Admin;
import BUPT.pojo.AdminExample;
import BUPT.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

//业务逻辑层的对象创建交给Spring
@Service
public class AdminServiceImpl implements AdminService {
    //在业务逻辑层中,一定会有数据访问层的对象,Spring来new出来
    @Autowired
    AdminMapper adminMapper;

    @Override
    public Admin login(String name, String pwd) {
        //判断登录就得拿传入的对象和数据库中相应对象进行对比
        //如果有条件需要SQL语句,则一定要创建AdminExample对象来封装条件
        //也就是说SQL语句我们也不会完整的写下来而是拼接条件生成语句

        //创建存放 封装条件的对象
        AdminExample example = new AdminExample();

        //例如这里我们需要的是 select * from admin where a_name='admin'
        //传进去就是我们要比对的条件 name
        //创造条件,添加条件
        example.createCriteria().andANameEqualTo(name);
//        查询返回结果是一个list
        List<Admin> list = adminMapper.selectByExample(example);

        if (list.size() > 0) {
            Admin admin = list.get(0);
            //能进入到这里面,就可以进行密码比对
            String miPwd = MD5Util.getMD5(pwd);
            if (miPwd.equals(admin.getaPass())) {
                return admin;
            }
        }
        return null;
    }
}

补充controller的AdminAction方法

package BUPT.controller;

import BUPT.pojo.Admin;
import BUPT.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/admin")
public class AdminAction {
    //切记:在所有的界面层,一定会有业务逻辑层的对象
    @Autowired
    AdminService adminService;

    //实现登录判断,并进行相应的跳转
    @RequestMapping("/login")
    //这里的login参数名称,是从前端 login.jsp页面中找到对应位置的参数名来写的
    public String login(String name, String pwd, HttpServletRequest request) {
        Admin admin = adminService.login(name, pwd);
        System.out.println("AdminAction中输出的admin是" + admin);

        if (admin != null) {
            //登录成功
            request.setAttribute("admin", admin);
            return "main";
        }
        //返回主界面
        else {
            request.setAttribute("errmsg", "用户名或密码不正确!");
            return "login";
        }
    }
}

这里的request也可以考虑改为视图来做

报错
在这里插入图片描述

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘adminAction’: Unsatisfied dependency expressed through field ‘adminService’; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘BUPT.service.AdminService’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

解读一下就是adminService和adminAction没配好
找到问题是
web.xml中监听器的配置,我 图快直接 alt+enter
导致导包出错
错误

        <listener-class>org.springframework.web.context.ContextLoader</listener-class>
    </listener>

正确

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

然而我又进行了测试
在这里插入图片描述

登录发现报错,进不去
在这里插入图片描述
查看输出日志

JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4c662a59] will be managed by Spring
==>  Preparing: select a_id, a_name, a_pass from admin WHERE ( a_name = ? ) 
==> Parameters: admin(String)
<==      Total: 0
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7328a4ea]
pwd输出为000000
[]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7328a4ea]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7328a4ea]
AdminAction中输出的admin是null

发现数据库是连接上的
也能拿到从登录界面上的账号
也能拿到登录界面上的密码

但是查询返回结果却是一个null,也就没办法正常登录到main里面了

暂时搁置一下

直接进入main里面学后面的

问题已解决
解决思路
我首先对比了我写的代码和教程里提供的代码,发现并没有什么区别
然后测试了

 example.createCriteria().andANameEqualTo(name);
 example.createCriteria().andAIdEqualTo(1);
 example.createCriteria().andAPassEqualTo(MD5Util.getMD5(pwd));

发现只有name的对不上,也就是说,我的SQL语句的组装是没问题的
那么我就查数据库本身的信息
我新建了一条字段,也叫admin,并把上面的admin删除
然后登录进去了
发现原来是建表的时候,我在admin前面加了一个空格,导致始终匹配不上。

结束时间:2022-03-02

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值