springboot mybatis项目遇到的问题

本文详述了在SpringBoot Mybatis项目中遇到的问题及解决方案,包括数据库设计、Mybatis Generator的使用技巧、Shiro保持登录状态的设计、ActiveMQ异步消息队列的实现以及@Transactional注解的理解。还探讨了ViewModel的重要性、Redis的使用注意事项、FastJSON的使用,以及在项目中遇到的算法问题。

讲自己项目的时候每个技术点讲设计的原因

一些小问题

  1. 数据库中Longint对应java中long类型
  2. Byte数据类型先转Integer,比较好处理,每次重新generator都要记得改
  3. mybatis generator多次使用容易重复创建,删掉xml文件重新generator即可
  4. controller层一般做不侵入业务逻辑的工作,一般是入口,不能相互调用。因此对于涉及到几张表操作的一个功能,例如用户注册要在user、role、relationship中添加数据,则统一在service层完成,service可用互相调用
  5. 在设计表格的时候,若mysql中数据类型为tinyint,长度为1,则generator生成model的类型是boolean的
  6. 返回给前端的时候不要直接返回数据库生成的model,最好拼接一个viewModel,因为直接返回model会是明文,很容易猜到语句,容易被SQL注入
  7. mybaits获取mysql的text类型返回null,原因是因为查询方法中selectByExample是不会带上有text类型的数据,要用selectByExampleWithBLOBs方法。原因是由于mapper以及xml文件这些都是用mybatis generator生成的,text类型的数据原来能够选择不查询。
  8. 给前端返回view model的时候,返回的东西前端应该不用再去做类似参数转换的东西,比如数据库里面存的是时间戳,那么返回给前端的时候,就转换成真正的时间,类型转换为String这样,前端拿到后就不用再做参数转换了。尽量避免前端做额外的事情
  9. 关于数据库索引的极左原则,项目中有select from where accountName = XXX and userPassword = xxx这样的查询,那么我应该为user表中accountName和userPassword者两个字段建立联合索引,而不是单独为accountName和userPassword分别建立索引。因为根据极左原则,如果对 A.a A.b 三个字段添加联合索引,则只要在where中出现了A.a,就会启动此索引。XXXX where A.b and A.c 这样会只用到A.b的索引,A.c的不会用到

Shiro保持用户登录状态的构想和设计

登录成功后返回一个token,下次登录时携带这个token就行了
在这里插入图片描述

关于ViewModel

可专门建立一个view model来建立一个用于展示和redis存储的model,方便后续操作
在这里插入图片描述

另一个理由是redis只存热点数据、所以拼接view层的操作提前放在了这里

@Override
    public List<CompetitionView> findByCompeTypeAndCompeSeason(Integer compeType, Integer season) {
   
   
        //先查redis
        String jsonKey = compeType+","+season+"_competitionsList";
        String jsonString = (String)redisUtils.get(jsonKey);
        List<CompetitionView> list = JSONObject.parseArray(jsonString,CompetitionView.class);
        if(list!=null){
   
   
            System.out.println("直接从人redis");
            return list;
        }
        //redis中没有,查数据库
        CompetitionExample competitionExample = new CompetitionExample();
        //int转byte
        competitionExample.createCriteria().andIsEnableEqualTo((byte)1).andCompeTypeEqualTo(compeType).andCompeSeasonEqualTo(season);
        List<Competition> competitionList = competitionMapper.selectByExample(competitionExample);
        //存redis
        List<CompetitionView> redisIn = new ArrayList<>();
        //存热点数据
        for(int i=0;i< competitionList.size();i++){
   
   
            CompetitionView competitionView = new CompetitionView();
            competitionView.setCompetitionId(competitionList.get(i).getCompeId()+"");//赛事主键 id
            competitionView.setCompetitonTime(competitionList.get(i).getCompeTime()+"");//赛事时间
            competitionView.setCompetitionStatus(competitionList.get(i).getCompeStatus()+"");//赛事状态
            competitionView.setCompetitionHtId(competitionList.get(i).getCompeHtId()+"");//主队 team id
            competitionView.setCompetitionGtId(competitionList.get(i).getCompeGtId()+"");//客队 team id
            competitionView.setCompetitionHtScore(competitionList.get(i).getCompeHostScore()+
<think>我们讨论的是在Spring BootMyBatis项目中,如果不使用Maven,该如何构建项目。通常,Maven(或Gradle)用于管理依赖和构建过程。如果不使用Maven,我们需要手动管理依赖和项目构建。但这在实际开发中并不常见,因为手动管理依赖非常繁琐且容易出错。不过,为了回答这个问题,我将描述一种可能的方式。 方案概述: 1. 手动下载所有需要的JAR文件(包括Spring BootMyBatis、数据库驱动等)并添加到项目的类路径中。 2. 手动配置项目结构(例如,创建src/main/java, src/main/resources等目录)。 3. 编写代码,包括主启动类、实体类、Mapper接口、MyBatis配置等。 4. 编译代码(使用javac命令),并指定类路径(classpath)为所有下载的JAR文件。 5. 运行项目(使用java命令),同样需要指定类路径。 然而,这种方法非常复杂,尤其是当项目依赖很多时。因此,强烈建议使用构建工具(Maven或Gradle)。但既然问题要求不使用Maven,我们将尝试给出一个示例步骤。 步骤: 1. 创建项目目录结构: project-root/ src/ main/ java/ com/example/demo/ DemoApplication.java # Spring Boot主类 entity/ User.java # 实体类 mapper/ UserMapper.java # Mapper接口 resources/ application.properties # Spring Boot配置文件 mybatis-config.xml # MyBatis配置文件(可选) mapper/ # Mapper XML文件 UserMapper.xml 2. 下载所有必需的JAR文件,放入一个目录,例如project-root/lib/。需要下载的JAR包括(以Spring Boot 2.5.0为例,具体版本根据需求): - Spring Boot相关的JAR(spring-boot, spring-core, spring-context等) - MyBatis相关的JAR(mybatis, mybatis-spring) - MyBatis-Spring-Boot-Starter(如果不使用Maven,可能需要单独下载其依赖的所有JAR,这非常繁琐) - 数据库驱动(如mysql-connector-java) - 其他如日志、Tomcat等依赖 3. 编写代码: - 主启动类:DemoApplication.java - 实体类:User.java - Mapper接口:UserMapper.java - Mapper XML:UserMapper.xml - 配置文件:application.properties 4. 编译代码(在project-root目录下): ```bash javac -d target/classes -cp "lib/*" src/main/java/com/example/demo/*.java src/main/java/com/example/demo/entity/*.java src/main/java/com/example/demo/mapper/*.java ``` 5. 将资源文件复制到target/classes目录: ```bash cp -r src/main/resources/* target/classes/ ``` 6. 运行项目: ```bash java -cp "target/classes:lib/*" com.example.demo.DemoApplication ``` 但是,以上步骤只是一个非常粗略的示例,实际上会遇到很多问题,例如: - 依赖的JAR文件可能不完全,因为Spring Boot有很多传递依赖。 - 没有构建工具,无法自动打包成可执行的JAR(Spring Boot的插件可以打包成fat jar)。 因此,为了简化,我们可以考虑使用Spring Boot的嵌入式Tomcat,但是需要确保所有的依赖都在类路径中。 另一种方法是使用Spring Boot的Maven插件来构建可执行JAR,但这又使用了Maven,与题目不符。 鉴于不使用Maven的复杂性,下面给出一个非常简单的示例,仅包含必要的步骤和代码,但请注意,这只是一个概念演示,实际项目不建议这样做。 示例代码: 1. DemoApplication.java ```java package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @GetMapping("/") public String home() { return "Hello, World!"; } } ``` 2. 在resources目录下的application.properties文件: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false spring.datasource.username=root spring.datasource.password=password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 3. 添加MyBatis支持: 我们需要创建实体类、Mapper接口和Mapper XML文件。 User.java: ```java package com.example.demo.entity; public class User { private Long id; private String name; // getters and setters } ``` UserMapper.java: ```java package com.example.demo.mapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface UserMapper { List<User> findAll(); } ``` UserMapper.xml (放在resources/mapper目录下): ```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"> <mapper namespace="com.example.demo.mapper.UserMapper"> <select id="findAll" resultType="com.example.demo.entity.User"> SELECT * FROM user </select> </mapper> ``` 4. 在application.properties中配置MyBatis: ```properties mybatis.mapper-locations=classpath:mapper/*.xml ``` 5. 编译和运行: 如前所述,需要手动编译和指定类路径。 由于手动管理依赖非常困难,我们可以考虑使用IDE(如IntelliJ IDEA)来创建非Maven项目,然后手动添加依赖的JAR。但即便如此,也不推荐。 结论:不使用Maven构建Spring BootMyBatis项目是极其困难的,尤其是管理依赖和构建过程。因此,在实际开发中,强烈建议使用Maven或Gradle。 但是,如果我们坚持不使用构建工具,那么必须手动处理所有依赖和构建步骤。 §§相关问题§§: 1. 在Spring Boot项目中,除了Maven,还有哪些常用的构建工具? 2. 如何在没有构建工具的情况下,手动创建一个可执行的Spring Boot JAR文件? 3. MyBatisSpring Boot项目中需要哪些最小依赖? 4. 如何解决在手动管理依赖时出现的版本冲突问题? </think>### 不使用 Maven 构建 Spring Boot + MyBatis 项目 不使用 Maven 时,需要手动管理所有依赖和项目结构。以下是具体步骤和代码示例: #### 解决方案步骤 1. **手动下载依赖 JAR 包** - 从 [Maven Central](https://repo.maven.apache.org) 下载: - Spring Boot 核心库(spring-boot-*.jar) - MyBatis 核心(mybatis-*.jar) - MyBatis-Spring 适配器(mybatis-spring-*.jar) - JDBC 驱动(如 mysql-connector-java-*.jar) - 其他必要依赖(spring-core, spring-context 等) 2. **项目目录结构** ```bash my-project/ ├── lib/ # 存放所有 JAR 依赖 ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/example/ │ │ │ ├── Application.java # 主启动类 │ │ │ ├── entity/User.java # 实体类 │ │ │ └── mapper/UserMapper.java # Mapper 接口 │ │ └── resources/ │ │ ├── application.properties # 配置文件 │ │ └── mapper/UserMapper.xml # SQL 映射文件 └── build.sh # 编译运行脚本 ``` 3. **核心代码实现** `Application.java` (主启动类): ```java package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan("com.example") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` `User.java` (实体类): ```java package com.example.entity; public class User { private Long id; private String name; // Getters and Setters } ``` `UserMapper.java` (Mapper 接口): ```java package com.example.mapper; import com.example.entity.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface UserMapper { List<User> findAll(); } ``` `UserMapper.xml` (SQL 映射): ```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"> <mapper namespace="com.example.mapper.UserMapper"> <select id="findAll" resultType="com.example.entity.User"> SELECT id, name FROM users </select> </mapper> ``` `application.properties` (配置文件): ```properties # 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/test_db spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # MyBatis 配置 mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.example.entity ``` 4. **编译与运行脚本** (`build.sh`) ```bash #!/bin/bash # 设置类路径 CLASSPATH="." for jar in lib/*.jar; do CLASSPATH="$CLASSPATH:$jar" done # 编译Java源码 find src/main/java -name "*.java" > sources.txt javac -d target/classes -cp "$CLASSPATH" @sources.txt # 复制资源文件 cp -r src/main/resources/* target/classes/ # 运行Spring Boot java -cp "target/classes:$CLASSPATH" com.example.Application ``` #### 关键说明 1. **依赖管理**: - 必须手工确保所有 JAR 版本兼容(如 Spring Boot 2.7.x + MyBatis 3.5.x) - 常见必要依赖: - Spring Boot Starter Web - MyBatis Spring Boot Starter - JDBC 驱动 - Lombok(可选) 2. **类路径配置**: - 编译和运行时需通过 `-cp` 指定所有 JAR - 资源文件需复制到类路径(`target/classes`) 3. **MyBatis 集成**: - `@Mapper` 注解启用接口扫描 - XML 映射文件路径需在配置中声明 - 实体类包路径需配置别名 4. **启动流程**: - 通过 `SpringApplication.run()` 启动嵌入式 Tomcat - 组件扫描 (`@ComponentScan`) 必须包含所有包 #### 手动构建的缺点 - **版本冲突**:依赖兼容性问题需人工解决 - **构建复杂**:每次添加依赖都需更新类路径 - **无自动化**:缺少 Maven 的生命周期管理 - **依赖传递**:需手动下载所有间接依赖 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值