外贸在什么网站做购物网站策划案

张小明 2026/1/12 6:21:55
外贸在什么网站做,购物网站策划案,和各大网站做视频的工作总结,想建一个自己的网站概述在项目中#xff0c;我们使用不同的对象模型来处理不同场景的数据#xff0c;这是分层架构的重要体现。为什么需要多种对象#xff1f;#x1f510; 安全性#xff1a;防止敏感数据泄露#x1f3af; 职责分离#xff1a;每个对象只关注自己的职责#x1f504; 灵活…概述在项目中我们使用不同的对象模型来处理不同场景的数据这是分层架构的重要体现。为什么需要多种对象安全性防止敏感数据泄露职责分离每个对象只关注自己的职责灵活性不同层可以独立演化️解耦数据库变动不影响前端1️⃣ Entity实体类- 数据库映射定义Entity是与数据库表一一对应的 Java 对象也叫持久化对象。特点️ 对应数据库表结构 包含所有字段包括敏感字段 包含数据库注解如 Table、Column 只在 DAO/Mapper 层使用实战案例 - User 实体package com.MiniBlog.entity; import lombok.Data; import javax.persistence.*; import java.util.Date; /** * 用户实体类 - 对应数据库表 tb_user * * 【注解说明】 * EntityJPA注解表示这是一个实体类 * Table指定对应的数据库表名 * DataLombok注解自动生成getter/setter/toString等 */ Data Entity Table(name tb_user) public class User { // 【主键】 /** * Id主键标识 * GeneratedValue主键生成策略自增 */ Id GeneratedValue(strategy GenerationType.IDENTITY) private Integer id; // 【基本信息】 /** * 用户编号业务主键 */ Column(name no, length 50) private String no; /** * 真实姓名 */ Column(name realname, length 100) private String realname; /** * 手机号 */ Column(name mobile, length 20) private String mobile; /** * 邮箱 */ Column(name email, length 100) private String email; // 【敏感信息】⚠️ /** * 密码加密后的 * 【注意】这个字段不应该返回给前端 */ Column(name password, length 200) private String password; /** * 密码盐值 * 【注意】这个字段不应该返回给前端 */ Column(name salt, length 50) private String salt; /** * 身份证号 * 【注意】需要脱敏后才能返回给前端 */ Column(name cardno, length 50) private String cardno; // 【状态字段】 /** * 账号状态1-正常2-冻结3-注销 */ Column(name status) private Integer status; /** * 是否删除0-否1-是 */ Column(name deleted) private Integer deleted; // 【微信相关】 Column(name openid, length 100) private String openid; Column(name unionid, length 100) private String unionid; Column(name mp_openid, length 100) private String mpOpenid; // 【人脸识别】 Column(name faceid, length 100) private String faceid; // 【时间戳】 /** * 创建时间 */ Column(name create_time) Temporal(TemporalType.TIMESTAMP) private Date createTime; /** * 更新时间 */ Column(name update_time) Temporal(TemporalType.TIMESTAMP) private Date updateTime; /** * 创建人 */ Column(name create_user) private Integer createUser; /** * 更新人 */ Column(name update_user) private Integer updateUser; }数据库表结构对应CREATE TABLE tb_user ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID, no varchar(50) DEFAULT NULL COMMENT 用户编号, realname varchar(100) DEFAULT NULL COMMENT 真实姓名, mobile varchar(20) DEFAULT NULL COMMENT 手机号, email varchar(100) DEFAULT NULL COMMENT 邮箱, password varchar(200) DEFAULT NULL COMMENT 密码, salt varchar(50) DEFAULT NULL COMMENT 盐值, cardno varchar(50) DEFAULT NULL COMMENT 身份证号, status int(11) DEFAULT 1 COMMENT 状态, deleted int(11) DEFAULT 0 COMMENT 是否删除, openid varchar(100) DEFAULT NULL COMMENT 微信openid, unionid varchar(100) DEFAULT NULL COMMENT 微信unionid, mp_openid varchar(100) DEFAULT NULL COMMENT 公众号openid, faceid varchar(100) DEFAULT NULL COMMENT 人脸ID, create_time datetime DEFAULT NULL COMMENT 创建时间, update_time datetime DEFAULT NULL COMMENT 更新时间, create_user int(11) DEFAULT NULL COMMENT 创建人, update_user int(11) DEFAULT NULL COMMENT 更新人, PRIMARY KEY (id), UNIQUE KEY uk_mobile (mobile), KEY idx_no (no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;2️⃣ VOView Object- 视图对象定义VO是返回给前端的视图对象只包含前端需要展示的数据。特点️ 只包含前端需要的字段不包含敏感字段密码、盐值等 可能包含计算字段如年龄、格式化日期 只在 Controller 层返回给前端实战案例 - UserVopackage com.MiniBlog.vo.user; import lombok.Data; import com.payslip.entity.UserCard; import java.util.List; /** * 用户视图对象 - 返回给前端 * * 【设计原则】 * 1. 只包含前端需要的字段 * 2. 敏感字段不包含如password、salt * 3. 需要脱敏的字段已处理如cardno * 4. 可以包含关联对象如银行卡列表 */ Data public class UserVo { // 【基本信息】 private Integer id; private String no; private String realname; /** * 手机号脱敏 * 例如138****5678 */ private String mobile; /** * 邮箱可能脱敏 * 例如abc***qq.com */ private String email; /** * 身份证号脱敏 * 例如320***********1234 */ private String cardno; // 【注意】❌ 不包含这些字段 // private String password; // 密码不返回 // private String salt; // 盐值不返回 // 【状态】 private Integer status; /** * 状态文本前端显示用 * 计算属性根据 status 值生成 */ private String statusText; // 【头像】 private String avatar; // 【微信信息】 /** * 是否绑定微信 * 计算属性openid 不为空则已绑定 */ private Boolean hasWechat; /** * 是否绑定公众号 * 计算属性mpOpenid 不为空则已绑定 */ private Boolean hasMpWechat; // 【关联信息】 /** * 用户的银行卡列表 * 这是关联查询的结果Entity 中没有这个字段 */ private ListUserCard cards; // 【时间】 /** * 创建时间格式化后 * 例如2024-01-15 10:30:00 */ private String createTime; // 【计算字段】 /** * 账号年龄天数 * 根据创建时间计算Entity 中没有这个字段 */ private Integer accountAge; /** * 是否实名认证 * 根据 cardno 是否为空判断 */ private Boolean isRealAuth; }3️⃣ DTOData Transfer Object- 数据传输对象定义DTO是服务间传输数据的对象用于跨层或跨服务传递数据。特点 用于 Service 层之间传递数据 用于微服务之间传递数据 可能包含多个实体的数据 职责单一只负责数据传输实战案例 - UserTokenDTOpackage com.MiniBlog.dto.user; import lombok.Data; import lombok.Builder; /** * 用户登录成功后返回的数据传输对象 * * 【使用场景】 * - 用户注册成功 * - 用户登录成功 * - Token刷新成功 */ Data Builder public class UserTokenDTO { /** * 用户ID */ private Integer userId; /** * 用户编号 */ private String userNo; /** * 用户姓名 */ private String userName; /** * 访问令牌JWT Token * 前端需要保存每次请求携带 */ private String token; /** * Token过期时间秒 */ private Long expiresIn; /** * 刷新令牌 * 用于Token过期后刷新 */ private String refreshToken; /** * 是否首次登录 * 首次登录需要引导用户完善信息 */ private Boolean firstLogin; /** * 用户头像 */ private String avatar; }4️⃣ Form表单对象- 接收前端数据定义Form是接收前端提交数据的对象包含参数校验规则。特点 只在 Controller 层接收前端数据✅ 包含参数校验注解NotNull、Size等 一个接口一个Form职责明确 校验规则集中管理实战案例 - UserMobileRegisterDTOpackage com.MiniBlog.form.user; import lombok.Data; import javax.validation.constraints.*; /** * 用户手机号注册表单 * * 【使用场景】 * POST /user/mobile-register * * 【校验规则】 * - 手机号必填格式正确 * - 验证码必填6位数字 * - 密码必填6-20位 */ Data public class UserMobileRegisterDTO { /** * 手机号 * * NotBlank不能为空会自动trim * Pattern正则校验 */ NotBlank(message 手机号不能为空) Pattern( regexp ^1[3-9]\\d{9}$, message 手机号格式不正确 ) private String mobile; /** * 短信验证码 */ NotBlank(message 验证码不能为空) Size(min 4, max 6, message 验证码长度为4-6位) private String code; /** * 密码 */ NotBlank(message 密码不能为空) Size(min 6, max 20, message 密码长度为6-20位) private String password; /** * 邀请码可选 */ private String inviteCode; }5️⃣ 对象之间的转换流程完整数据流转图┌─────────────────────────────────────────────────────────────────┐ │ 前端浏览器/APP │ └────────────┬────────────────────────────────────────┬────────────┘ │ │ │ ① 发送请求 │ ⑥ 接收响应 │ JSON: {mobile, code, password} │ JSON: {userId, token, userName} ▼ ▲ ┌─────────────────────────────────────────────────────────────────┐ │ Controller 层控制器 │ │ PostMapping(/register) │ │ public ApiResponseUserTokenDTO register( │ │ Valid RequestBody UserMobileRegisterDTO form) { │ │ │ │ ② Form 接收参数 ⑤ VO 返回给前端 │ │ └─ 自动校验Valid └─ Entity 转 VO │ │ │ │ UserTokenDTO dto userService.register(form); │ │ return ApiResponse.ok(dto); │ │ } │ └────────────┬────────────────────────────────────────┬────────────┘ │ │ │ ③ Form 传给 Service │ ④ DTO 返回 ▼ ▲ ┌─────────────────────────────────────────────────────────────────┐ │ Service 层业务逻辑 │ │ public UserTokenDTO register(UserMobileRegisterDTO form) { │ │ │ │ // 1. 校验验证码 │ │ validateCode(form.getMobile(), form.getCode()); │ │ │ │ // 2. 创建 Entity 对象 │ │ User user new User(); │ │ user.setMobile(form.getMobile()); │ │ user.setPassword(encryptPassword(form.getPassword())); │ │ user.setCreateTime(new Date()); │ │ │ │ // 3. 保存到数据库 │ │ userDao.save(user); ────┐ │ │ │ │ │ // 4. 生成 Token │ │ String token generateToken(user.getId()); │ │ │ │ // 5. 构建 DTO 返回 │ │ return UserTokenDTO.builder() │ │ .userId(user.getId()) │ │ .token(token) │ │ .userName(user.getRealname()) │ │ .build(); │ │ } │ │ └───────────────────────────────┼─────────────────────────────────┘ │ │ Entity 保存/查询 ▼ ┌─────────────────────────────────────────────────────────────────┐ │ DAO/Mapper 层数据访问 │ │ │ │ public interface UserRepository { │ │ User save(User user); // 保存 │ │ User findById(Integer id); // 查询 │ │ } │ └────────────┬────────────────────────────────────────┬────────────┘ │ │ │ SQL 语句 │ 查询结果 ▼ ▲ ┌─────────────────────────────────────────────────────────────────┐ │ 数据库MySQL │ │ │ │ tb_user 表 │ │ ┌────┬──────┬──────────┬──────────┬──────────┐ │ │ │ id │ no │ mobile │ password │ salt │ │ │ ├────┼──────┼──────────┼──────────┼──────────┤ │ │ │ 1 │ U001 │ 13800000 │ ******* │ ******* │ │ │ └────┴──────┴──────────┴──────────┴──────────┘ │ └─────────────────────────────────────────────────────────────────┘6️⃣ 对象转换代码示例实际项目中的转换RestController RequestMapping(/user) Slf4j public class UserController extends BaseController { Autowired private UserService userService; Autowired private UserCardService userCardService; /** * 根据Token获取用户信息 * * 【数据流转】 * 1. 从数据库查询 Entity包含所有字段 * 2. Entity 转换为 VO只包含安全字段 * 3. 关联查询银行卡补充数据 * 4. 返回 VO 给前端 */ GetMapping(/findByToken) public ApiResponseUserVo findByToken() { // ① 查询 Entity Integer userId LoginContext.getUserId(); User user userService.findById(userId); // Entity 对象 // 校验用户存在 Asserts.notNull(user, -10001, 登录失效); // ② Entity 转 VO // 使用 BeanUtil 复制属性只复制同名字段 UserVo userVo BeanUtil.copyProperties(user, UserVo.class); // ③ 补充数据 // 查询关联的银行卡列表 ListUserCard cards userCardService.findByUserId(user.getId()); userVo.setCards(cards); // 设置计算字段 userVo.setHasWechat(user.getOpenid() ! null); userVo.setIsRealAuth(user.getCardno() ! null); // 脱敏处理 if (user.getMobile() ! null) { userVo.setMobile(desensitizeMobile(user.getMobile())); } if (user.getCardno() ! null) { userVo.setCardno(desensitizeCardNo(user.getCardno())); } // ④ 返回 VO return ApiResponse.ok(userVo); } /** * 手机号脱敏 * 13800138000 - 138****8000 */ private String desensitizeMobile(String mobile) { if (mobile null || mobile.length() ! 11) { return mobile; } return mobile.substring(0, 3) **** mobile.substring(7); } /** * 身份证号脱敏 * 320102199001011234 - 320***********1234 */ private String desensitizeCardNo(String cardNo) { if (cardNo null || cardNo.length() 8) { return cardNo; } return cardNo.substring(0, 3) *********** cardNo.substring(cardNo.length() - 4); } }使用工具类转换推荐import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; /** * 对象转换工具类 */ public class BeanConverter { /** * Entity 转 VO * 自动忽略 null 值 */ public static T T toVo(Object source, ClassT targetClass) { if (source null) { return null; } return BeanUtil.copyProperties(source, targetClass, CopyOptions.create().ignoreNullValue()); } /** * Entity List 转 VO List */ public static S, T ListT toVoList(ListS sourceList, ClassT targetClass) { if (sourceList null || sourceList.isEmpty()) { return Collections.emptyList(); } return sourceList.stream() .map(source - toVo(source, targetClass)) .collect(Collectors.toList()); } /** * Form 转 Entity */ public static T T toEntity(Object form, ClassT entityClass) { if (form null) { return null; } T entity BeanUtil.copyProperties(form, entityClass); // 设置创建时间等默认字段 if (entity instanceof BaseEntity) { ((BaseEntity) entity).setCreateTime(new Date()); } return entity; } } // 使用示例 Service public class UserServiceImpl implements UserService { Override public UserVo getUserInfo(Integer userId) { // 1. 查询 Entity User user userDao.findById(userId); // 2. 转换为 VO UserVo vo BeanConverter.toVo(user, UserVo.class); // 3. 补充额外数据 vo.setCards(userCardService.findByUserId(userId)); return vo; } Override public ListUserVo getUserList(ListInteger userIds) { // 1. 批量查询 Entity ListUser users userDao.findByIds(userIds); // 2. 批量转换为 VO return BeanConverter.toVoList(users, UserVo.class); } }7️⃣ 为什么要分这么多对象核心原因1. 安全性// ❌ 错误直接返回 Entity GetMapping(/user/{id}) public ApiResponseUser getUser(PathVariable Integer id) { User user userService.findById(id); return ApiResponse.success(user); // 密码、盐值都返回了 } // 前端收到的数据危险 { id: 123, mobile: 13800138000, password: e10adc3949ba59abbe56e057f20f883e, // MD5密码 salt: a1b2c3d4, // 盐值暴露 cardno: 320102199001011234 // 身份证明文 } // ✅ 正确返回 VO GetMapping(/user/{id}) public ApiResponseUserVo getUser(PathVariable Integer id) { User user userService.findById(id); UserVo vo BeanUtil.copyProperties(user, UserVo.class); // VO 中没有 password、salt 字段 return ApiResponse.success(vo); } // 前端收到的数据安全 { id: 123, mobile: 138****8000, // 脱敏 cardno: 320***********1234 // 脱敏 }2. 解耦// 数据库表结构变更不影响前端 // 数据库改了字段名user_name - real_name Entity public class User { Column(name real_name) // 数据库字段改了 private String realname; // Java字段不变 } // VO 不变前端不受影响 public class UserVo { private String realname; // 前端继续用原来的字段 }3. 灵活性// VO 可以包含 Entity 没有的计算字段 public class UserVo { private Integer id; private String realname; // 【计算字段】 // Entity 中没有这些字段 private Integer age; // 根据生日计算 private String statusText; // 根据status转换1-正常,2-冻结 private Boolean isVip; // 根据会员等级判断 private String createTimeText; // 格式化日期2024-01-15 // 【关联数据】 // Entity 中没有这些字段 private ListUserCard cards; // 关联的银行卡 private Integer orderCount; // 订单数量统计 private BigDecimal totalAmount; // 总消费金额统计 }4. 职责分离// 每个对象都有明确的职责 Entity 负责与数据库交互 ↓ DTO 负责在Service层传递数据 ↓ VO 负责返回给前端展示 Form 负责接收前端提交的数据 ↓ DTO 负责在Service层传递数据 ↓ Entity 负责保存到数据库8️⃣ 实战完整流程示例用户注册完整流程// ① 前端提交表单 // POST /user/register // Body: { mobile: 13800138000, code: 1234, password: abc123 } // ② Controller 接收 Form RestController RequestMapping(/user) public class UserController { Autowired private UserService userService; PostMapping(/register) public ApiResponseUserTokenDTO register( Valid RequestBody UserMobileRegisterDTO form) { // Form 对象 log.info(用户注册: mobile{}, form.getMobile()); // 调用 Service传递 Form接收 DTO UserTokenDTO dto userService.register(form); // 返回 DTO 给前端 return ApiResponse.ok(dto); } } // ③ Service 处理业务逻辑 Service Slf4j public class UserServiceImpl implements UserService { Autowired private UserRepository userDao; Autowired private SmsService smsService; Override Transactional(rollbackFor Exception.class) public UserTokenDTO register(UserMobileRegisterDTO form) { // 1. 校验验证码 boolean valid smsService.validateCode(form.getMobile(), form.getCode()); Asserts.isTrue(valid, 验证码错误); // 2. 检查手机号是否已注册 User existUser userDao.findByMobile(form.getMobile()); Asserts.isNull(existUser, 手机号已注册); // 3. Form 转 Entity User user new User(); user.setNo(generateUserNo()); // 生成用户编号 user.setMobile(form.getMobile()); // 手机号 user.setRealname(用户 user.getNo()); // 默认昵称 // 4. 密码加密 String salt UUID.randomUUID().toString(); String encryptedPwd Secure.encryptPassword(form.getPassword(), salt); user.setSalt(salt); user.setPassword(encryptedPwd); // 5. 设置默认值 user.setStatus(1); // 正常 user.setDeleted(0); // 未删除 user.setCreateTime(new Date()); user.setUpdateTime(new Date()); // 6. 保存到数据库Entity userDao.save(user); log.info(用户注册成功: userId{}, user.getId()); // 7. 生成 Token String token JwtUtil.generateToken(user.getId(), user.getNo()); // 8. 构建 DTO 返回 return UserTokenDTO.builder() .userId(user.getId()) .userNo(user.getNo()) .userName(user.getRealname()) .token(token) .expiresIn(7200L) // 2小时 .firstLogin(true) .build(); } private String generateUserNo() { return U System.currentTimeMillis(); } } // ④ DAO 保存 Entity Repository public interface UserRepository extends JpaRepositoryUser, Integer { /** * 根据手机号查询用户 */ User findByMobile(String mobile); /** * 根据用户编号查询 */ User findByNo(String no); } // ⑤ 数据库存储 // INSERT INTO tb_user // (no, mobile, realname, password, salt, status, deleted, create_time, update_time) // VALUES // (U1704528000123, 13800138000, 用户U1704528000123, // e10adc3949ba59abbe56e057f20f883e, a1b2c3d4, 1, 0, NOW(), NOW()); // ⑥ 返回给前端 // Response: { code: 0, message: 成功, data: { userId: 123, userNo: U1704528000123, userName: 用户U1704528000123, token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..., expiresIn: 7200, firstLogin: true } }9️⃣ 最佳实践与规范推荐做法1. Entity 使用规范✅ DO - 只在 DAO/Mapper 层使用 - 字段名与数据库列名对应 - 包含完整的数据库注解 - 不要有业务逻辑代码 ❌ DONT - 不要在 Controller 中直接返回 Entity - 不要在 Entity 中写复杂的方法 - 不要让前端知道 Entity 的结构2. VO 使用规范✅ DO - 只包含前端需要的字段 - 敏感字段要脱敏 - 可以包含计算字段 - 可以包含关联数据 - 只在 Controller 返回时使用 ❌ DONT - 不要包含密码、盐值等敏感字段 - 不要包含数据库注解 - 不要在 Service 层使用3. DTO 使用规范✅ DO - 在 Service 层之间传递数据 - 在微服务之间传递数据 - 可以包含多个 Entity 的数据 - 可以包含业务状态信息 ❌ DONT - 不要直接暴露给前端 - 不要包含数据库操作4. Form 使用规范✅ DO - 只在 Controller 接收前端数据 - 包含完整的校验注解 - 一个接口一个 Form - 字段命名清晰 ❌ DONT - 不要在 Service 层定义 Form - 不要在 Form 中写业务逻辑 对比总结表对象类型作用使用层级主要特点是否包含敏感字段Entity数据库映射DAO/Mapper与表一一对应包含数据库注解✅ 是VO返回给前端Controller只包含展示字段脱敏处理❌ 否DTO服务间传输Service跨层传输数据业务对象 视情况而定Form接收前端数据Controller包含校验注解参数验证 可能包含总结Entity、VO、DTO、Form 是项目分层架构的重要体现每个对象都有明确的职责。理解它们的区别和转换逻辑是掌握项目架构的关键
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

网站除了wordpress外网页转微信小程序

R语言ggplot2可视化删除图例(legend)周围的灰色矩形(remove the gray rectangle around the legend) 目录 R语言ggplot2可视化删除图例(legend)周围的灰色矩形(remove the gray rectangle around the legend) #图例周围有灰色矩形 #删除图例(legend)周围的灰色矩形 #无…

张小明 2026/1/9 7:36:10 网站建设

阿里巴巴网站建设的态度虚心wordpress 多媒体显示

AI 能精准切换 “甜妹” 娇憨语气与 “御姐” 飒爽表达?阿里刚发布的 Qwen3-Omni-Flash 全模态大模型,把这种科幻场景变成了现实。2025 年 12 月 9 日,Qwen 团队官宣的这款升级模型,不仅实现了文本、图像、音视频的无缝交互&#…

张小明 2026/1/9 7:34:07 网站建设

分销系统网站建设网站图片上的分享怎么做

第一章:Agent服务的Docker数据卷挂载概述在构建基于容器的Agent服务时,持久化存储是保障服务状态和配置一致性的关键环节。Docker数据卷(Volume)提供了一种高效、安全的方式,用于在主机与容器之间或多个容器之间共享和…

张小明 2026/1/9 7:32:04 网站建设

hao爱做网站建设银行电子银行网站

最近有客户问我,上银RG滚柱导轨的承载能力比滚珠型大多少?作为海威机电的销售,我可以明确地说:上银RG滚柱导轨的承载能力是同规格滚珠型的2~3倍。这个数据来自上银官方的技术手册,是经过严格测试的。为什么滚柱导轨承载…

张小明 2026/1/9 7:30:03 网站建设

济南电子商务网站开发公司做公司网站宣传

突破动画创作边界:Wan2.2-Animate-14B开源模型实现角色动作高精度复刻 【免费下载链接】Wan2.2-Animate-14B 项目地址: https://ai.gitcode.com/hf_mirrors/Wan-AI/Wan2.2-Animate-14B 2025年9月19日,人工智能领域再度迎来技术突破——Wan团队正…

张小明 2026/1/10 12:18:29 网站建设

厦门快速建网站凡科网做网站好吗

文章目录系统截图项目简介大数据系统开发流程主要运用技术介绍爬虫核心代码展示结论源码文档获取定制开发/同行可拿货,招校园代理 :文章底部获取博主联系方式!系统截图 基于大数据的增强可视化的广州IT招聘系统_r9chjd79–论文-爬虫 可视化 项目简…

张小明 2026/1/10 20:02:17 网站建设