java实操笔记

4 阅读9分钟

一、字符串常用方法(最最常用)

// 1. 判断字符串 空/非空(你项目天天用)
StrUtil.isEmpty(str);      // 为空(null、"")
StrUtil.isNotEmpty(str);  // 不为空

// 2. 切割字符串(批量删除 ID 切割)
String[] arr = str.split(",");
List<String> list = StrUtil.splitToList(str, ",");

// 3. 字符串拼接
String res = StrUtil.join(",", list);

// 4. 字符串替换
StrUtil.replace(str, "旧", "新");

// 5. 转大小写
str.toUpperCase();
str.toLowerCase();

  • 二、集合(List / Map)常用方法
// 1. 集合判空(必用!防止空指针报错)
CollectionUtil.isEmpty(list);
CollectionUtil.isNotEmpty(list);

// 2. 字符串 → List<Long>(批量删除神器)
List<Long> ids = Arrays.stream(str.split(","))
        .map(Long::valueOf)
        .toList();

// 3. 集合 → 逗号字符串
String idStr = CollUtil.join(list, ",");

// 4. 提取对象里的字段(神器)
List<Long> ids = list.stream().map(TrainDataBank::getId).toList();

// 5. 过滤集合
List<TrainDataBank> newList = list.stream()
        .filter(o -> "80".equals(o.getFlag()))
        .toList();

// 6. 集合去重
list.stream().distinct().toList();

  • 三、日期时间常用方法(你的项目必用)
// 1. 获取当前时间
new Date();
LocalDateTime.now();

// 2. 日期 → 字符串
DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");

// 3. 字符串 → 日期
Date date = DateUtil.parse("2024-01-01");

// 4. 判断日期是否在区间内
DateUtil.isIn(date, startDate, endDate);

// 5. 日期比较(前后)
date1.before(date2);
date1.after(date2);

  • 四、对象 / Bean 常用方法
// 1. 对象复制(你 Excel 导入、VO转Entity 必用)
BeanUtil.copyProperties(源对象, 目标对象);

// 2. 对象判空
ObjectUtil.isNotNull(obj);
ObjectUtil.isNull(obj);

  • 五、MyBatis-Plus 增删改查万能方法(你天天用)
// 1. 查单个
getById(id);
getOne(wrapper);

// 2. 查列表
list();
list(wrapper);

// 3. 分页查询(你接口核心)
page(page, wrapper);

// 4. 新增
save(entity);
saveBatch(list); // 批量新增

// 5. 修改
updateById(entity);
update(entity, wrapper);

// 6. 删除
removeById(id);
removeByIds(ids); // 批量删除
remove(wrapper);

// 7. 统计数量
count(wrapper);

  • 六、条件构造器 QueryWrapper 常用(查 / 删 / 改)
QueryWrapper<TrainDataBank> wrapper = new QueryWrapper<>();
wrapper.in('id',1,2,3)               // 在列表里
wrapper.notIn('id',1,2,3)            // 不在列表里
wrapper.eq("report_no", "123");      // =
wrapper.ne("report_no", "123");      // !=
wrapper.like("name", "测试");        // 模糊查询
wrapper.gt("date", "2024-01-01");    // >
wrapper.ge("date", "2024-01-01");    // >=
wrapper.lt("date", "2024-01-01");    // <
wrapper.le("date", "2024-01-01");    // <=
wrapper.between("date", a, b);       // 区间
wrapper.orderByDesc("create_time");  // 倒序
wrapper.isNull("id");                // 为空

  • 七、类型转换常用方法
// StringLong
Long.valueOf(str);

// StringInteger
Integer.valueOf(str);

// 对象 → String
String.valueOf(obj);

list.stream()流水线

你可以把:

  • 普通 List = 一筐杂乱的零件
  • stream() = 把这筐零件送上流水线
  • filter / map / distinct = 流水线上的筛选、加工、去重机器
  • toList() = 把加工好的零件重新装回筐里(变回 List)
  • . 告别手写 for 循环,代码巨简洁

以前处理数据,你必须写for 循环 + 临时集合 + if 判断,又臭又长:

流水线常用方法

筛选已完成数据 → 按时间倒序 → 提取 ID → 去重 → 取前 10 条

List<Long> resultIds = list.stream()
        .filter(item -> "80".equals(item.getFlag())) // 筛选
        .sorted(Comparator.comparing(TrainDataBank::getReportDate).reversed()) // 排序
        .map(TrainDataBank::getId) // 提取ID
        .distinct() // 去重
        .limit(10) // 取10条
        .toList(); // 装回集合
// 传统方式:筛选 flag=80 的数据,要写一堆
List<TrainDataBank> newList = new ArrayList<>();
for (TrainDataBank item : list) {
    if ("80".equals(item.getFlag())) {
        newList.add(item);
    }
}

用了 stream()一行搞定

List<TrainDataBank> newList = list.stream().filter(o -> "80".equals(o.getFlag())).toList();

2. 只有变成 “流”,才能用链式加工方法

filtermapdistinct 这些不是 List 自带的方法

. controller(控制层)

    1. BaseMapper<T>(Mapper 层父接口)
public interface TrainDataBankMapper extends BaseMapper<TrainDataBank> {
}

✅ 作用:自带单条增删改查、根据 ID 操作

    1. IService<T>(Service 层父接口)
public interface TrainDataBankService extends IService<TrainDataBank> {
}

✅ 作用:自带批量操作、分页、列表查询(你用的 page() 就在这里)。

    1. ServiceImpl<M,T>(Service 实现类父类)
public class TrainDataBankServiceImpl extends ServiceImpl<TrainDataBankMapper, TrainDataBank> implements TrainDataBankService {
}

✅ 作用:自动实现所有增删改查方法,你直接调用就行。

最常用语法(背会这 8 个够用)

QueryWrapper<TrainDataBank> wrapper = new QueryWrapper<>();

wrapper.eq("report_no", "123");       // 等于 =
wrapper.ne("report_no", "123");       // 不等于 !=
wrapper.like("report_name", "事故");  // 模糊查询 LIKE %事故%
wrapper.gt("report_date", "2024-01-01"); // 大于 >
wrapper.between("report_date", "2024-01-01", "2024-12-31"); // 区间
wrapper.orderByDesc("report_date");  // 排序
wrapper.isNull("id");                 // 字段为空
**@Validated TrainDataBank trainDataBank

= 接收前端传过来的【所有查询条件】,自动装进一个对象里 **

HttpServletRequest req

它 = 前端请求的 “大管家”里面装着这次请求的所有东西

  • 所有参数

  • 请求头

  • Cookie

  • 客户端 IP

  • 等等...

  • 核心职责:接收前端 HTTP 请求,进行参数校验,调用对应的业务逻辑,并返回响应结果。

  • 典型内容@RestController@Controller 注解的类,如 UserController.java

  • 作用:作为项目的入口,负责请求路由和参数处理,不包含复杂业务逻辑。

2. entity(实体层)

- **核心职责**:定义与数据库表一一对应的实体类,包含属性、getter/setter 等。 - **典型内容**:`@Entity` 或普通 POJO 类,如 `User.java`、`Order.java`。 - **作用**:承载数据,在各层之间传递数据,是整个项目的数据模型基础。 - 这个类就像 “用户信息的纸质表单”,只记录 id、用户名、密码、年龄这些数据,没有任何 “做事” 的逻辑,所有层之间传递用户信息都靠它
@Data // 核心:Lombok注解,自动生成所有属性的getter/setter、toString、equals、hashCode、无参构造 
@EqualsAndHashCode(callSuper = false) // Lombok注解:生成equals/hashCode方法时,不调用父类(WorkFlowEntity)的方法 
@Accessors(chain = true) // Lombok注解:开启链式调用(比如 wellPractise.setBillCode("001").setFactory("一分厂")) 
@TableName("WELL_PRACTISE") // MyBatis-Plus注解:指定该实体对应数据库的表名是 WELL_PRACTISE(大写是数据库常见规范)

解释

  • equals():用来判断两个对象是否“相等”。
  • hashCode():返回一个整数(哈希码),可以理解为对象的“身份证号”或“分类编号”。
  • 链式调用 Java 中普通的 setter 方法返回值是 void,调用完一个方法后,没法直接调用下一个:
// 普通写法:每调一个setter都要单独写一行
WellPractise wp = new WellPractise();
wp.setBillCode("LSJC-2026-001");  // setBillCode返回void,没法接着调
wp.setFactory("一分厂");          // 只能重新用wp对象调用
wp.setFlag("1");
wp.setWriteName("张三");

2. 开启链式调用(@Accessors (chain = true))

加了 @Accessors(chain = true) 后,setter 方法会返回当前对象本身(this) ,就能 “链式” 调用:

// 链式调用写法:一行搞定所有set操作
WellPractise wp = new WellPractise()
    .setBillCode("LSJC-2026-001")  // 返回wp对象,可接着调下一个方法
    .setFactory("一分厂")          // 继续返回wp对象
    .setFlag("1")
    .setWriteName("张三");
  • @TableField(exist = false) MyBatis-Plus注解:标记该字段不是数据库表中的字段,查询/插入时会忽略

3. mapper(数据访问层 / DAO 层)

  • 核心职责:负责与数据库交互,执行 CRUD 操作。

  • 典型内容:使用 MyBatis 等框架的 Mapper 接口,如 UserMapper.java,以及对应的 XML 映射文件。

  • 作用:封装数据库操作,为上层提供数据访问接口,解耦业务逻辑与数据库细节。 项目里的 Java 代码说的是 “面向对象的语言”,数据库说的是 “SQL 语言”,两者没法直接沟通,Mapper 层就负责在中间做翻译:

  • 你在 Service 层说 “查 ID 为 1 的 WellPractise 数据”,Mapper 层就翻译成SELECT * FROM well_practise WHERE id = 1发给数据库;

  • 数据库返回一堆原始数据,Mapper 层再翻译成 Java 的WellPractise对象,交给 Service 层用。

4. service(业务逻辑层)

  • 核心职责:处理核心业务逻辑,调用 Mapper 层完成数据操作,实现事务控制。
  • 典型内容@Service 注解的类,如 UserService.javaOrderService.java
  • 作用:是项目的核心,负责业务规则、数据处理和流程编排,是 Controller 和 Mapper 之间的桥梁。

impl

查询参数
.eq( 
// 第一个参数:判断 flag 是不是有值(有值才生效)
experiencePoorPerformanceRptVo.getFlag() != null, 
// 第二个参数:对应数据库字段 
flag ExperiencePoorPerformanceRpt::getFlag, 
// 第三个参数:前端传过来的 flag 值
experiencePoorPerformanceRptVo.getFlag() )
其他常用参数
一、等值查询
  • eq → equal → 等于(=)
  • ne → not equal → 不等于(!=)
二、大小比较
  • gt → greater than → 大于(>)
  • ge → greater than or equal → 大于等于(>=)
  • lt → less than → 小于(<)
  • le → less than or equal → 小于等于(<=)
三、模糊查询
  • like → 全模糊匹配(% 值 %)
  • likeLeft → 左模糊(% 值)
  • likeRight → 右模糊(值 %)
四、包含 / 不包含
  • in → 在集合内(IN)
  • notIn → 不在集合内(NOT IN)
排序

// 倒序(desc) .orderByDesc(实体::getCreateTime); // 正序(asc) .orderByAsc(实体::getCreateTime);

lambda

wrapper.lambda() = 让你写查询条件时****不用写数据库字段名(字符串),直接用实体类的属性,安全、不写错、不报错!


    1. 先看对比:有 lambda 和 没有 lambda 的区别

-不使用 lambda(老式写法,容易出错)

wrapper.eq("unit_code", vo.getUnitCode()); // 手写数据库字段名
wrapper.like("project_name", vo.getProjectName());
  • 字段名是字符串,写错了运行才报错
  • 没有代码提示,全靠记忆
  • 容易写错:unit_codprojectName 都会崩

使用 lambda(你现在的写法,安全、优雅)

wrapper.lambda()
       .eq(ExperiencePoorPerformanceRpt::getUnitCode, vo.getUnitCode())
       .like(ExperiencePoorPerformanceRpt::getProjectName, vo.getProjectName());
  • 不用写字段名
  • 直接用实体类的方法引用
  • IDEA 会自动提示
  • 写错编译就报错,不会跑到线上才崩
ueryWrapper
ueryWrapper<ExperiencePoorPerformanceRpt> wrapper = new QueryWrapper<>();
  1. QueryWrapper

    • MyBatis-Plus 提供的条件构造器
    • 作用:帮你拼 WHERE 后面的所有查询条件
  2. <ExperiencePoorPerformanceRpt>

    • 泛型:告诉它要查哪张表
    • 对应你的实体类 → 对应数据库表
  3. wrapper

    • 变量名,意思是包装器、条件包裹器
    • 你可以理解成:查询条件集合
  4. new QueryWrapper<>()

    • 新建一个空的查询条件对象
    • 刚开始里面什么条件都没有

    1. 它到底是干嘛的?(最核心)

你要查数据库,肯定要写条件:

SELECT * FROMWHERE unit_code = 'xxx'
  AND project_name LIKE '%xxx%'
  AND create_time > '2025-01-01'

这些 WHERE 条件,不用你手写 SQL全部用 wrapper 对象一行一行拼进去!


    1. 整个流程长这样(一看就懂)
// 1. 新建一个空的查询条件盒子
QueryWrapper<ExperiencePoorPerformanceRpt> wrapper = new QueryWrapper<>();

// 2. 往盒子里装条件(eq = 等于,like = 模糊查询...)
wrapper.eq("unit_code", "1001");
wrapper.like("project_name", "测试");

// 3. 把盒子丢给数据库去查
this.list(wrapper);

它就像一个:装查询条件的快递盒子

  • 先创建盒子
  • 再把条件装进去
  • 最后发给数据库

和你上面那行连起来理解

// 1. 创建空查询条件
QueryWrapper<ExperiencePoorPerformanceRpt> wrapper=new QueryWrapper<>();

// 2. 开启 Lambda 安全模式
wrapper.lambda()
       .eq(...)
       .like(...)

  • new QueryWrapper<>() = 拿一个空表单
  • wrapper.lambda () = 开始安全填写条件

5. workflow(工作流层)

  • 核心职责:处理复杂的业务流程,如审批流、任务调度、状态流转等。
  • 典型内容:集成 Activiti、Flowable 等工作流引擎的代码,或自定义的流程控制逻辑。
  • 作用:将复杂的业务流程抽象化、配置化,提高系统的灵活性和可维护性。

6. OeApplication

  • 核心职责:Spring Boot 项目的启动类。
  • 典型内容:包含 main 方法,使用 @SpringBootApplication 注解。
  • 作用:作为项目的入口点,启动 Spring 容器,自动配置和扫描组件。