Project(1)

2021/4/16 10:56:39

本文主要是介绍Project(1),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Project(1)

1、分析项目

当需要开发某个项目时,首先,应该分析这个项目中,需要处理哪些种类的数据!例如:用户、商品、商品类别、收藏、订单、购物车、收货地址…

然后,将以上这些种类的数据的处理排个顺序,即先处理哪种数据,后处理哪种数据!通常,应该先处理基础数据,再处理所相关的数据,例如需要先处理商品数据,才可以处理订单数据,如果多种数据之间没有明显的关联,则应该先处理简单的,再处理较难的!

则以上这些数据的处理顺序应该是:用户 > 收货地址 > 商品类别 > 商品 > 收藏 > 购物车 > 订单

当确定了数据处理顺序后,就应该分析某个用户对应的功能有哪些,以“用户”数据为例,相关功能有:注册、登录、修改密码、修改资料、上传头像…

然后,还是需要确定以上功能的开发顺序,通常,遵循“增 > 查 > 删 > 改”的顺序,则以上功能的开发顺序应该是:注册 > 登录 > 修改密码 > 修改资料 > 上传头像。

每个功能的开发都应该遵循“创建数据表 > 创建实体类 > 持久层 > 业务层 > 控制器层 > 前端页面”。

一次只解决一个问题
大问题拆成小问题

2、用户 - 注册 - 创建数据表

  1. 创建库:
    CREATE DATABASE tedu_store;
  2. 使用库:
    USE tedu_store;
  3. 创建数据表:
    CREATE TABLE t_user(
    uid INT PRIMARY KEY AUTO_INCREMENT COMMENT ‘用户id’,
    username VARCHAR(20) UNIQUE NOT NULL COMMENT ‘用户名’,
    password CHAR(32) NOT NULL COMMENT ‘密码’,
    salt CHAR(36) COMMENT ‘盐值’,
    gender INT COMMENT ‘性别:0-女性,1-男性’,
    phone VARCHAR(20) COMMENT ‘电话号码’,
    email VARCHAR(50) COMMENT ‘邮箱’,
    avatar VARCHAR(50) COMMENT ‘头像’,
    is_delete INT COMMENT ‘是否标记为删除:0-未删除,1-已删除’,
    created_user VARCHAR(20) COMMENT ‘创建人’,
    created_time DATETIME COMMENT ‘创建时间’,
    modified_user VARCHAR(20) COMMENT ‘修改人’,
    modified_time DATETIME COMMENT ‘修改时间’
    ) DEFAULT CHARSET=UTF8;

3、用户 - 注册 - 创建实体类

首先,从FTP服务器(https://start.spring.io/)下载项目的压缩包,通过Import > Existing MaveProjects导入项目。

由于项目中添加了数据库相关依赖,在启动时,SpringBoot就会读取相关配置。如果没有,则报错,所以,就需要将此前项目中的配置复制到此项目中,注意修改数据库的名称为tedu_store

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
mybatis.mapper-locations=classpath:mappers/*.xml

然后,在单元测试类中,先测试运行默认存在的空方法,测试通过后,自行编写并测试数据库连接是否正确:

    @Autowired
	private DataSource ds;
	
	@Test
	public void testGetConnection() throws Exception {
		Connection conn = ds.getConnection();
		System.err.println(conn);
	}

接下来,应该创建实体类,在项目中,后续还会出现更多的数据表,而每张表中都会有created_user、created_time、modified_user等日志字段,对应的每个实体类中也需要有这些属性,为了避免重复声明这些属性,可以先创建cn.tedu.store.entity.BaseEntity实体类的基类:

abstract class BaseEntity implements Serializable {

	private String createdUser;
	private Date createdTime; //util包下的Date
	private String modifiedUser;
	private Date modifiedTime;
	
	// Get、Set
}

cn.tedu.store.entity.User实体类:

public class User extends BaseEntity {

	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;
	
	// Get、Set、toString、hashCode、equals
}	

4、用户 - 注册 - 持久层

4.1.规划SQL语句

注册的本质是向数据表中插入新的数据,则执行的SQL语句应该是:

INSERT INTO t_user (出了uid以外的字段列表) VALUES (匹配的User类中属性名的占位符)

通常,用户注册时,不允许使用已经存在的用户名,即用户名都是唯一的,这一点应该在Java程序中进行检查,而不应该直接将数据送到数据库服务器尝试执行插入!所以,可以根据用户尝试注册的用户名查询用户数据,如果查询结果为null,则表示用户名没有被占用,可以正常注册,如果查询到了结果,则表示用户名已经被占用,则不会执行插入数据!此次查询时需要执行的SQL语句大致是:

SELECT uid FROM t_user WHERE username=?

4.2.接口与抽象方法

首先,应该在启动类之前添加@MapperScan("cn.tedu.store.mapper")以配置持久层接口所在的包。

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

创建cn.tedu.store.mapper.UserMapper持久层接口,并在接口中添加抽象方法:

/**
 * 处理用户数据的持久层接口
 * @author DELL
 *
 */
public interface UserMapper {
	
	/**
	 * 插入用户数据
	 * @param user 用户数据对象
	 * @return 受影响的行数
	 */
	Integer insert(User user);
	
	/**
	 * 根据用户名查询用户数据
	 * @param username 用户名
	 * @return 匹配的用户数据,如果没有匹配的数据,则返回null
	 */
	User findByUsername(String username);
	
}

4.3.配置映射

检查在application.properties中是否配置了映射文件的位置:
mybatis.mapper-locations=classpath:mappers/*.xml

然后,在src/main/resources下创建名为分mappers的文件夹,在该文件夹中添加UserMapper. xml文件(从前序项目中复制即可),并配置该文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:xml文件对应哪个接口 -->
<mapper namespace="cn.tedu.store.mapper.UserMapper">
    
    <!-- 插入用户数据 -->
    <!-- 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" resultType="cn.tedu.store.entity.User">
        SELECT
            uid
        FROM
            t_user
        WHERE
            username=#{username}
    </select>
    
</mapper>

完成后,在src/test/java下创建cn.tedu.store.mapper.UserMapperTests用户数据持久层的测试类(与默认的测试类一样,类前要加上@SpringBootTest注解),并在类中编写并执行单元测试:

@SpringBootTest
public class UserMapperTests {
	
	@Autowired
	private UserMapper userMapper;
	
	@Test
	public void insert() {
		User user = new User();
		user.setUsername("Tom1");
		user.setPassword("123");
		Integer rows = userMapper.insert(user);
		System.err.println("rows="+rows);
	}
	
	@Test
	public void findByUsername() {
		String username = "Tom0";
		User user = userMapper.findByUsername(username);
		System.err.println(user.getUid());
	}
	
}

5、用户 - 注册 - 业务层

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

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

8、用户 - 登录 - 持久层

9、用户 - 登录 - 业务层

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

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

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

附1、关于VARCHAR的设置

在MySQL数据库中,如果某字段的类型设置为VARCHAR(30),表示该字段最多存储30个字节长度的数据,如果尝试存入的数据超出30字节,多余的部分将不会被存储!

30个字节,表示为多少个字符,取决于使用的字符编码!

  1. 以UTF8为例,如果存储的内容是1个字节的,存储下来例如:
0110  0001

其规则是使用第1位0表示该字符只占1个字节,剩余的7位表示1个字符!

  1. 如果某个字符需要使用2个字节才可以表示,UTF8的规则表现例如:
110 01010        10 000111

即第1个字节使用110作为前缀,表示该字符需要2个字节,其中,这里的2个1就表示1个字节,后续的第2个字节中的10就表示它是跟随前序字节一起的,第2个字节中的剩余6位才是编码位。

  1. 在2个字节中,只有5+6=11个编码位,只能表示2048种不同的组合,所以,在UTF8编码中,2个字节是不可以表示中文的,因为中文里的汉字数量及相关符号远超2048个!所以,中文需要3个字节来表示,在UTF8中,3字节的编码例如:
1110 0101     10 101010     10 010101

在UTF8中,还有需要4字节才可以表示的编码…

所以,如果设计的是VARCHAR(30),并使用UTF8编码,到底可以存入多少字符,也是不确定的,如果存的是ASCII字符,最多可以存30个,如果存的是汉字,只能计划为10个,如果是混合的,可以计划为例如15个英文加上5个汉字…所以,通常,在设置时,只能根据最大需求来进行设计!

另外,请还注意一个问题:设置的字节值,并不代码存储占用空间!例如VARCHAR(30)存满,还另外会占用1个字节存储长度,表示存了多少字节的数据,(即最占用31个字节),在存储长度时,数据类型的字节数在255个时是分隔线,如果使用VARCHAR设置的字节数超过255,则另外需要占用2个字节存储长度!例如设置VARCHAR(300),则额外的存储长度时使用字节数就是2个字节!(总共占用302个字节)



这篇关于Project(1)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程