Project(1)
2021/4/16 10:56:39
本文主要是介绍Project(1),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Project(1)
1、分析项目
当需要开发某个项目时,首先,应该分析这个项目中,需要处理哪些种类的数据!例如:用户、商品、商品类别、收藏、订单、购物车、收货地址…
然后,将以上这些种类的数据的处理排个顺序,即先处理哪种数据,后处理哪种数据!通常,应该先处理基础数据,再处理所相关的数据,例如需要先处理商品数据,才可以处理订单数据,如果多种数据之间没有明显的关联,则应该先处理简单的,再处理较难的!
则以上这些数据的处理顺序应该是:用户 > 收货地址 > 商品类别 > 商品 > 收藏 > 购物车 > 订单
当确定了数据处理顺序后,就应该分析某个用户对应的功能有哪些,以“用户”数据为例,相关功能有:注册、登录、修改密码、修改资料、上传头像…
然后,还是需要确定以上功能的开发顺序,通常,遵循“增 > 查 > 删 > 改”的顺序,则以上功能的开发顺序应该是:注册 > 登录 > 修改密码 > 修改资料 > 上传头像。
每个功能的开发都应该遵循“创建数据表 > 创建实体类 > 持久层 > 业务层 > 控制器层 > 前端页面”。
一次只解决一个问题
大问题拆成小问题
2、用户 - 注册 - 创建数据表
- 创建库:
CREATE DATABASE tedu_store; - 使用库:
USE tedu_store; - 创建数据表:
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个字节,表示为多少个字符,取决于使用的字符编码!
- 以UTF8为例,如果存储的内容是1个字节的,存储下来例如:
0110 0001
其规则是使用第1位0表示该字符只占1个字节,剩余的7位表示1个字符!
- 如果某个字符需要使用2个字节才可以表示,UTF8的规则表现例如:
110 01010 10 000111
即第1个字节使用110作为前缀,表示该字符需要2个字节,其中,这里的2个1就表示1个字节,后续的第2个字节中的10就表示它是跟随前序字节一起的,第2个字节中的剩余6位才是编码位。
- 在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)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升