store(商城项目)Springboot+springmvc+ajax+mybatis(一)

1. 项目分析

在开发整个项目之前,应该先分析所需要开发的项目!

建议:有时间的时候,学习一下《软件工程》。

首先,应该分析该项目中需要处理哪些类型的数据,例如,本项目中应该有:商品、商品类别、收藏、订单、购物车、用户、收货地址;

接下来,就需要确定一下以上数据的开发顺序,通常,应该先开发基础数据,先开发简单的或熟悉的数据!所以,以上数据的开发顺序应该是:用户 > 收货地址 > 商品类别 > 商品 > 收藏 > 购物车 > 订单。

如果数据之间存在1对多的关系,应该先处理“1”的数据,再处理“多”的数据。

然后,应该分析首个处理的数据的管理功能,也就是“用户”数据涉及哪些功能!包括:注册、登录、修改密码、修改资料、上传头像!

并规划以上功能的开发顺序,应该先开发基础功能,先开发简单的功能,通常还遵循增、查、删、改的顺序!所以,以上用户数据的管理功能的开发顺序应该是:注册 > 登录 > 修改密码 > 修改资料 > 上传头像。

最后,在处理每种数据之前,还应该先创建这种数据在数据库中的数据表,并在项目中创建这个数据对应的实体类!

并且,在处理每个功能时,应该遵循的开发顺序是:持久层 > 业务层 > 控制器层 > 前端页面。

2. 用户-创建数据表

首先,创建数据库:

CREATE DATABASE tedu_store;

并使用该数据库:

USE tedu_store;

然后创建数据表:

CREATE TABLE t_user (
    uid INT AUTO_INCREMENT COMMENT '用户id',
    username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',
    password CHAR(32) NOT NULL COMMENT '密码',
    salt CHAR(36) COMMENT '盐值',
    gender INT(1) COMMENT '性别:0-女,1-男',
    phone VARCHAR(20) COMMENT '手机',
    email VARCHAR(30) COMMENT '邮箱',
    avatar VARCHAR(100) COMMENT '头像',
    is_delete INT(1) COMMENT '是否删除,0-未删除,1-已删除',
    created_user VARCHAR(20) COMMENT '创建人',
    created_time DATETIME COMMENT '创建时间',
    modified_user VARCHAR(20) COMMENT '最后修改人',
    modified_time DATETIME COMMENT '最后修改时间',
    PRIMARY KEY (uid)
) DEFAULT CHARSET=utf8mb4;

如果当前数据库并不支持utf8mb4,就直接使用utf8

3. 用户-创建实体类

先在cn.tedu.store下创建子级entity包,并在这个包中先创建实体类的基类:

/**
 * 实体类的基类
 */
abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = -3122958702938259476L;

    private String createdUser;
    private Date createdTime;
    private String modifiedUser;
    private Date modifiedTime;

    // GET/SET/toString

}

然后,还是在entity包中,创建用户数据的实体类:

/**
 * 用户数据的实体类
 */
public class User extends BaseEntity {

    private static final long serialVersionUID = -3302907460554699349L;

    private Integer uid;
    private String username;
    private String password;
    private String salt;
    private Integer gender;
    private String phone;
    private String email;
    private String avatar;
    private Integer isDelete;

    // SET/GET/基于uid的equals()和hashCode()/toString()

}

设计原则:

  1. 尽量使用更加严格的访问权限;

  2. 如果某个类的作用就是被继承,这个类应该是抽象类;

  3. 只用于封装属性的类,应该实现Serializable接口;

  4. 实体类中都应该生成基于id(唯一标识)的hashCode()equals()方法。

4. 用户-注册-持久层

首先,应该在application.properties中配置数据库连接的信息:

spring.datasource.url=jdbc:mysql://localhost:3306/tedu_store?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

src/main/resources下创建mappers文件夹,用于存放配置SQL语句的XML文件。

并在application.properties中配置即将使用的XML文件的位置:

mybatis.mapper-locations=classpath:mappers/*.xml

然后,在启动类的声明之前配置@MapperScan("cn.tedu.store.mapper"),用于指令即将使用的MyBatis的接口文件的位置:

@SpringBootApplication
@MapperScan("cn.tedu.store.mapper")
public class StoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(StoreApplication.class, args);
    }

}

注意:如果没有正确的配置接口文件的位置,后续在自动装配接口对象(例如后续会使用到的userMapper对象)时失败!

在正式编写代码之前,应该测试当前环境是否正常,所以,先启动整个项目,观察是否可以正常启动!然后,打开自带的测试类StoreApplicationTests,执行其中的空测试方法contextLoads(),观察是否可以正常通过单元测试!最后,在这个测试类,尝试获取数据库连接:

@Autowired
private DataSource dataSource;

@Test
public void getConnection() throws SQLException {
    System.err.println(dataSource.getConnection());
}

接下来,应该完成“注册”时持久层的开发任务!首先,在cn.tedu.store.mapper(刚才配置在启动类的@MapperScan注解中的包名)包中创建UserMapper接口,并在这个接口中添加抽象方法:

/**
 * 处理用户数据的持久层接口
 */
public interface UserMapper {

    /**
     * 插入用户数据
     * @param user 用户数据
     * @return 受影响的行数,当插入成功时,可以从参数对象中获取自动递增的uid值
     */
    Integer insert(User user);

    /**
     * 根据用户名查询用户数据详情
     * @param username 用户名
     * @return 匹配的用户数据,如果没有匹配的数据,则返回null
     */
    User findByUsername(String username);

}

然后,在src/main/resources/mappers下复制粘贴得到UserMapper.xml文件,并在该文件中配置以上抽象方法对应的SQL语句:

<mapper namespace="cn.tedu.store.mapper.UserMapper">

    <resultMap id="UserEntityMap"
        type="cn.tedu.store.entity.User">
        <id column="uid" property="uid" />
        <result column="is_delete" property="isDelete" />
        <result column="created_user" property="createdUser" />
        <result column="created_time" property="createdTime" />
        <result column="modified_user" property="modifiedUser" />
        <result column="modified_time" property="modifiedTime" />
    </resultMap>

    <!-- 插入用户数据 -->
    <!-- Integer insert(User user) -->
    <insert id="insert"
        useGeneratedKeys="true"
        keyProperty="uid">
        INSERT INTO t_user (
            username, password,
            salt, gender,
            phone, email,
            avatar, is_delete,
            created_user, created_time,
            modified_user, modified_time
        ) VALUES (
            #{username}, #{password},
            #{salt}, #{gender},
            #{phone}, #{email},
            #{avatar}, #{isDelete},
            #{createdUser}, #{createdTime},
            #{modifiedUser}, #{modifiedTime}
        )
    </insert>

    <!-- 根据用户名查询用户数据详情 -->
    <!-- User findByUsername(String username) -->
    <select id="findByUsername"
        resultMap="UserEntityMap">
        SELECT 
            *
        FROM
            t_user
        WHERE
            username=#{username}
    </select>

</mapper>

5. 用户-注册-业务层

6. 用户-注册-控制器层

7. 用户-注册-前端页面

8. 用户-登录-持久层

9. 用户-登录-业务层

10. 用户-登录-控制器层

11. 用户-登录-前端页面

-----------------------------

附1:关于VARCHAR与CHAR类型

VARCHAR和CHAR都是用于存储字符串的字段类型!并且,在设计数据表时,都必须显式的指定长度!

VARCHAR是变长的,即存储的字符串的长度不是固定的,只要不超出设置值,都是正确的;而CHAR是定长的,存储的字符串的长度也不允许超出设置值,但是,如果长度小于设置值,则会自动补上空格,以达到设置值!

假设某个字段设计为VARCHAR(20),如果存入的是Hello,实际存储的也就是Hello,如果字段是CHAR(20),也存Hello,由于这个字符串只有5个字符,则会自动补上15个空格,以达到设计的20的长度!

在数据库中,处理VARCHAR时,默认会额外使用1个字节记录实际存入的字符数量!例如在VARCHAR(20)中存入了Hello,其实,数据库还另使用1个字节记录了5(字符的数量),由于默认只使用1个字节记录字符数量,所以,默认情况下,只能存入255个字符,如果使用VARCHAR时设计值及实际存入的字符串更长,数据库会自动改为使用2个字节来记录,则最多就可以表示65535,所以,最多存入的就是65535个字符!并且,不会使用更多的字节数来做记录,所以,最多也只能存65535个字符!

而使用CHAR(20)时,是不会使用额外的字节去记录实际存入的字符数量的,因为设计值就是这个字符串的长度!

 

src/test/java下中类内容:

package cn.tedu.store;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.DigestUtils;

import cn.tedu.store.entity.User;
import cn.tedu.store.mapper.UserMapper;

@RunWith(SpringRunner.class)
@SpringBootTest
public class StoreApplicationTests {

    @Test
    public void contextLoads() {
    }
    @Autowired
    private DataSource dataSource;

    @Autowired
    private  UserMapper     userMapper;
    @Test
    public void getConnection() throws SQLException {
        System.err.println(dataSource.getConnection());
    }
    
    @Test
    public void  insert() {
        User user=new User();
        user.setUsername("2j2");
        user.setPassword("123456");
user.setSalt("1151");
user.setGender(151);
user.setPhone("515151");
user.setEmail("151515@fbvt");
user.setAvatar("25615");
user.setIsDelete(115);
        Integer row=userMapper.insert(user);
        System.out.println(row);
    }
    @Test
    public void findByUsername() {
    String username="nlh";
        User users=userMapper.findByUsername(username);
        System.out.println(users);
    }
    @Test
    public void md5() {
        String password="1234";
        String md5Password=DigestUtils.md5DigestAsHex(password.getBytes());
    System.out.println(md5Password);
    }
}

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

饭九钦vlog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值