Java后端开发核心工具与技能全面解析

一 PageHelper

1. 介绍

PageHelper 是一个 MyBatis 分页插件,它通过拦截 MyBatis 的 SQL 执行过程,动态注入分页逻辑(如 LIMITOFFSET),从而自动实现物理分页。你无需手动编写分页 SQL 或额外的 count 查询

3. 核心工作原理

PageHelper 的实现基于 MyBatis 的拦截器机制Interceptor),主要流程如下:

  1. 设置分页参数
    调用 PageHelper.startPage() 会将分页参数(页码、每页条数)存储到 ThreadLocal 中34。
  2. 拦截 SQL 执行
    在 MyBatis 执行查询前,拦截器从 ThreadLocal 获取分页参数,并重写原 SQL:
    • 添加数据库特定的分页语句(如 MySQL 的 LIMIT offset, pageSize);
    • 自动生成并执行 COUNT(*) 查询获取总记录数46。
  3. 返回包装结果
    查询结果被封装为 Page 对象(本质是 ArrayList),同时可通过 PageInfo 获取完整分页信息4

4. 添加依赖

xml

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>最新版</version> <!-- 如 1.4.7 -->
</dependency>

5. 示例

package com.itheima.mapper;


import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface EmpMapper {


    @Select("select emp.*,dept.name deptName from emp  left join dept on emp.dept_id = dept.id" + " order by emp.update_time desc ")
    public List<Emp> list();
}

package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.PageResult;
import com.itheima.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;


    /*
    * 基于pageHelper分页查询
    * */
    public PageResult<Emp> page(Integer page, Integer pageSize){
        PageHelper.startPage(page,pageSize);

        List<Emp> empList = empMapper.list();

        Page<Emp> empPage = (Page<Emp>) empList;
        return new PageResult<Emp>(empPage.getTotal(), empPage.getResult());

    }
}

package com.itheima.controller;

import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.PageResult;
import com.itheima.pojo.Result;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;
    /*
    分页查询
    */
    @GetMapping
    public Result page(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer pageSize){
        log.info("分页查询,参数:{},{}",page,pageSize);
        PageResult<Emp> pageResult= empService.page(page,pageSize);
        return Result.success(pageResult);
    }
}

6. 注意事项

sql语句结尾不要加分号
PageHelper只会对紧跟在其后的第一条sql进行分页处理

二 @Transactional

1. 介绍

Spring 框架中用于声明式事务管理的核心注解。它极大地简化了在应用程序中使用事务的复杂度,避免了手动编写事务管理代码(如开始事务、提交事务、回滚事务等),让开发者可以专注于业务逻辑。

2. 核心作用:

  • 声明方法或类需要在一个事务的上下文中执行。

  • 定义该事务的属性,例如传播行为、隔离级别、超时时间、只读标志、回滚规则等。

3. 基本用法:

  1. 启用事务管理: 在 Spring 配置类(通常是 @Configuration 类)上添加 @EnableTransactionManagement 注解。
  2. 标注事务边界:
    • 在方法上: 最常用。表示该方法执行时需要一个事务。
    • 在类上: 表示该类的所有公共方法都默认使用事务(相当于给每个公共方法都加了 @Transactional)。方法上的注解会覆盖类上的注解定义。
    • 在接口上: 也可以,但不推荐(因为 Java 注解在接口上的继承规则可能导致问题)。推荐使用基于类的代理(CGLIB)或直接在实现类上标注。

java

@Service
public class MyService {

    @Autowired
    private MyRepository repository;

    // 在需要事务的方法上添加注解
    @Transactional
    public void performBusinessOperation() {
        // 业务逻辑,包含多个数据库操作
        repository.updateDataA();
        repository.updateDataB(); // 如果这里失败,updateDataA() 的更改也会回滚
    }

    // 可以指定特定属性
    @Transactional(propagation = Propagation.REQUIRES_NEW,
                   isolation = Isolation.READ_COMMITTED,
                   timeout = 30,
                   readOnly = false,
                   rollbackFor = {MyBusinessException.class},
                   noRollbackFor = {ValidationException.class})
    public void anotherTransactionalMethod() {
        // ...
    }
}

4. 属性介绍

(1) rollbackFor / rollbackForClassName (回滚规则): 指定哪些检查型异常(checked exceptions)RuntimeException 发生时也应该触发事务回滚(默认只对 RuntimeExceptionError 回滚)。

  • rollbackFor = {Exception.class}

(2)propagation (传播行为 - Propagation): 定义了当前事务方法已存在事务上下文之间的关系。这是理解事务嵌套的关键。

  • REQUIRED (默认值):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。
  • REQUIRES_NEW:总是创建一个新事务。如果当前存在事务,则挂起(suspend)当前事务。新事务独立提交或回滚,不受外层事务影响。

三 全局异常处理器

全局异常处理器是实现统一错误处理的核心机制,尤其在使用Spring框架时,通过集中管理异常处理逻辑,能显著提升代码可维护性和用户体验

一 核心实现机制:基于Spring的全局异常处理

  1. 注解组合使用
    • @RestControllerAdvice:是@ControllerAdvice@ResponseBody的组合注解,适用于RESTful API,自动将返回值序列化为JSON/XML110。
    • @ExceptionHandler:标记处理特定异常的方法,可指定异常类型
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler
    public Result handleException(Exception e){
        log.error("全局异常信息:{}",e.getMessage());
        return Result.error("全局异常信息");
    }
}

四 SpringAOP

1.通知类型

1. 前置通知 @Before
  • 执行时机:在目标方法执行之前触发。

  • 特点

    • 无法阻止目标方法执行(除非抛出异常)。
    • 无法获取目标方法的返回值。
  • 典型场景:参数校验、权限检查、日志记录。

  • 示例

    java

    @Aspect
    @Component
    public class LoggingAspect {
        
        @Before("execution(* com.example.service.*.*(..))")
        public void beforeAdvice(JoinPoint joinPoint) {
            String methodName = joinPoint.getSignature().getName();
            System.out.println("【前置通知】准备执行方法: " + methodName);
        }
    }
    

2. 后置通知 @AfterReturning
  • 执行时机:在目标方法成功执行后触发(未抛出异常)。

  • 特点

    • 可以获取目标方法的返回值(通过 returning 属性)。
  • 典型场景:记录方法返回值、执行结果统计。

  • 示例

    java

    @Aspect
    @Component
    public class ResultAspect {
        
        @AfterReturning(
            pointcut = "execution(* com.example.service.*.*(..))",
            returning = "result"  // 绑定返回值到 result 参数
        )
        public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
            System.out.println("【后置通知】方法返回结果: " + result);
        }
    }
    

3. 异常通知 @AfterThrowing
  • 执行时机:在目标方法抛出异常后触发。

  • 特点

    • 可以捕获异常对象(通过 throwing 属性)。
  • 典型场景:异常日志记录、错误报警。

  • 示例

    java

    @Aspect
    @Component
    public class ExceptionAspect {
        
        @AfterThrowing(
            pointcut = "execution(* com.example.service.*.*(..))",
            throwing = "ex"  // 绑定异常对象到 ex 参数
        )
        public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
            System.out.println("【异常通知】方法抛出异常: " + ex.getMessage());
        }
    }
    

4. 最终通知 @After
  • 执行时机:在目标方法执行结束后触发(无论是否抛出异常)。

  • 特点

    • 类似 Java 中的 finally 代码块。
    • 无法获取返回值或异常对象。
  • 典型场景:资源清理(如关闭文件、数据库连接)。

  • 示例

    java

    @Aspect
    @Component
    public class CleanupAspect {
        
        @After("execution(* com.example.service.*.*(..))")
        public void afterAdvice(JoinPoint joinPoint) {
            System.out.println("【最终通知】方法执行完毕");
        }
    }
    

5. 环绕通知 @Around(最强大)
  • 执行时机完全控制目标方法的执行(方法执行前后均可插入逻辑)。

  • 特点

    • 需通过 ProceedingJoinPoint.proceed() 显式调用目标方法。
    • 可以修改参数、返回值,甚至阻止方法执行。
  • 典型场景:性能监控、事务管理、缓存控制。

  • 示例

    java

    @Aspect
    @Component
    public class PerformanceAspect {
        
        @Around("execution(* com.example.service.*.*(..))")
        public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
            long startTime = System.currentTimeMillis();
            
            // 执行目标方法(可修改参数或跳过执行)
            Object result = joinPoint.proceed(); 
            
            long endTime = System.currentTimeMillis();
            System.out.println("【环绕通知】方法执行耗时: " + (endTime - startTime) + "ms");
            
            return result; // 可修改返回值
        }
    }
    

核心对比表
通知类型注解执行时机能否修改返回值能否阻止方法执行
前置通知@Before目标方法执行前❌(抛异常除外)
后置通知@AfterReturning目标方法成功返回后
异常通知@AfterThrowing目标方法抛出异常后
最终通知@After目标方法结束后(无论成败)
环绕通知@Around完全控制方法执行全过程

2. @Pointcut

主要作用是声明切点(Pointcut)表达式,让通知(Advice)可以引用这些表达式,实现切点定义的模块化复用
1. 定义可重用切点

java

@Aspect
@Component
public class LoggingAspect {
    
    // 定义可重用的切点表达式
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}  // 空方法体
    
    @Pointcut("@annotation(com.example.Loggable)")
    public void loggableMethod() {}
}
2. 在通知中引用切点

java

// 使用定义好的切点
@Before("serviceLayer()")
public void logBeforeService(JoinPoint joinPoint) {
    System.out.println("调用服务方法: " + joinPoint.getSignature());
}

// 组合多个切点
@After("serviceLayer() && loggableMethod()")
public void logAfterLoggableService() {
    System.out.println("记录日志完成");
}

3. 通知顺序

(1)不同切面类中,默认按照切面类的类字母排序
目标方法前的通知方法:字母排名靠前的先执行
目标方法后的通知方法:字母排名靠前的后执行
(2)用@order(数字)加在切面类上控制顺序
目标方法前的通知方法:数字小的先执行
@Aspect
@Order(1) // 数字越小优先级越高
@Component
public class SecurityAspect {
    // 安全相关通知
}

@Aspect
@Order(2)
@Component
public class LoggingAspect {
    // 日志相关通知
}
目标方法前的通知方法:数字小的后执行

五 linux

常用命令

一、核心文件和目录操作

这些命令是你与文件系统交互的基础。

命令全称/含义常用参数/示例说明
lsList-l (详情), -a (显示隐藏文件), -h (人性化文件大小)列出目录内容
ls -lah以详情模式列出所有文件(包括隐藏文件)
cdChange Directorycd /home cd .. cd ~ cd -切换目录 (.. 上级, ~ 家目录, - 返回上次目录)
pwdPrint Working Directorypwd显示当前所在目录的绝对路径
mkdirMake Directory-p (递归创建) mkdir new_dir mkdir -p a/b/c创建新目录
cpCopy-r (递归复制目录) -i (交互确认)复制文件或目录
cp file1.txt file2.txt cp -r dir1/ dir2/
mvMovemv file1.txt /tmp/ mv old.txt new.txt移动文件/目录 或 重命名
rmRemove-r (递归删除目录), -f (强制删除), -i (交互确认)删除文件或目录 (慎用!)
rm file.txt rm -rf somedir/ (极其危险!)
touchtouch new_file.txt创建空文件 或 更新文件时间戳
catConcatenatecat file.txt cat > new_file.txt (创建)查看文件内容、创建文件、合并文件
less / moreless long_file.log分页查看文件内容(less 更强大,支持上下翻)
head-n 10 (指定行数) head -20 file.log查看文件头部内容(默认10行)
tail-n 20 -f (实时追踪文件更新)查看文件尾部内容,-f 常用于看日志
tail -f /var/log/syslog
二 压缩
命令文件格式常用示例
tar.tar, .tar.gz, .tar.bz2打包压缩: tar -czvf archive.tar.gz /path/to/dir/ 解压: tar -xzvf archive.tar.gz

tar 参数解释:

  • -c:创建归档
  • -x:提取归档
  • -z:使用 gzip 压缩/解压
  • -j:使用 bzip2 压缩/解压
  • -v:显示详细过程
  • -f:指定文件名
三 文本编辑

启动

vim filename.txt  # 编辑或创建文件
关闭:
  • :w:保存 (Write)

  • :wq:x:保存并退出

  • :q!强制退出,不保存修改!

  • 进入插入模式

    • i:在光标插入
    • a:在光标插入 (Append)
    • o:在当前行下方新建一行并插入
    • I:在行首插入
    • A:在行尾插入
  • 移动光标(替代方向键):

    • h (左), j (下), k (上), l (右)
    • gg:跳到文件第一行
    • G:跳到文件最后一行
    • :n:跳到第 n 行(在命令行模式下,例如 :50 跳转到第50行)
  • 复制、粘贴、删除

    • yy:复制当前行 (Yank)
    • dd:删除(剪切)当前行
    • p:在光标后粘贴
    • u:撤销 (Undo)
    • Ctrl + r:重做 (Redo)
四 查找命令
find

基本语法: find [路径] [选项] [操作]

  • 按名称查找 (-name, -iname):

    find /home -name "report.txt"      # 在 /home 下精确查找名为 report.txt 的文件(区分大小写)
    find . -name "*.log"               # 在当前目录及子目录中查找所有 .log 结尾的文件
    find /var -iname "*.JPG"           # -iname 不区分大小写,会找到 .jpg, .JPG, .Jpg 等
    
  • 按类型查找 (-type):

    find /tmp -type f                  # 查找所有普通文件 (f=file)
    find . -type d                     # 查找所有目录 (d=directory)
    find /dev -type l                  # 查找所有符号链接 (l=link)
    
grep
  • 基本搜索:

    grep "error" /var/log/syslog      # 在 syslog 文件中搜索包含 "error" 的行
    grep "TODO" *.py                  # 在所有 .py 文件中搜索 "TODO"
    
  • 常用选项:

    grep -i "warning" file.log        # -i 忽略大小写
    grep -r "function" /my/code/      # -r 递归搜索目录下的所有文件
    grep -n "pattern" file.txt        # -n 显示匹配行所在的行号
    

六 GIT

一 初始化和配置

命令说明
git init在当前目录初始化一个新的 Git 仓库
git clone <url>克隆一个远程仓库到本地(如 git clone https://github.com/user/repo.git
git config --global user.name "Your Name"设置全局用户名
git config --global user.email "email@example.com"设置全局邮箱地址
git config --list查看当前的所有配置

说明--global 选项表示该配置对当前用户的所有仓库生效。如果只想对单个仓库生效,去掉 --global 即可。


二 基本工作流程(最常用)

这些命令构成了日常开发中最基本的代码管理流程。

命令说明
git status查看仓库当前的状态(哪些文件被修改、已暂存等),这是最常用的命令之一
git add <file>工作区的指定文件添加到暂存区(Stage)
git add .将当前目录下所有变更加入暂存区(新增、修改,不包括删除

三 分支管理

命令说明
git branch查看所有本地分支(当前分支前有 * 号)
git branch -a查看所有分支(包括远程分支)
git branch <branch-name>创建一个新分支
git checkout <branch-name>切换到指定分支
git switch <branch-name>(Git 2.23+) 切换到指定分支(更推荐的命令)
git checkout -b <new-branch>创建并切换到新分支(旧式)
git switch -c <new-branch>(Git 2.23+) 创建并切换到新分支(新式)
git merge <branch-name>合并指定分支到当前分支

四 远程仓库操作

命令说明
git remote -v查看关联的远程仓库地址(verbose)
git remote add origin <url>关联一个远程仓库,并起别名为 origin
git push -u origin main首次推送本地 main 分支到远程 origin,并建立追踪关系(-u
git push将当前分支的提交推送到远程关联分支
git pull拉取远程关联分支的更新并合并到当前分支(= git fetch + git merge
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值