目录： 1、下载安装MySQL 2、在安装目录新建配置 3、添加环境变量 4、安装 5、启动服务 6、卸载 现在 Windows 下安装 MySQL 的时候需要首先下载 MySQL Installer，通过这个软件来联网安装管理不同版本的 MySQL，但是这个软件默认是将 MySQL 安装在 C 盘的，修改安装路径的地方也藏的很隐蔽，并且由于安装时 MySQL Installer 需要联网下载安装包，这对于内网里的机器无疑就是很不友好的。但是从 Oracle 官网下载到的 MSI Installer 程序只是解压出了 MySQL 程序，并没有进行任何的环境变量配置、服务配置，那么就需要通过手动配置程序信息。 1、下载安装MySQL 最新版本下载链接：MySQL :: Download MySQL Community Server 旧版本下载链接：MySQL :: Download MySQL Community Server (Archived Versions) 选择下载某一个版本的 MSI 安装程序或者 ZIP 压缩包，下载完成之后进行安装或解压。 2、在安装目录新建配置 下文中的 MySQL 安装目录以 D:\Program\Environment\MySQL\MySQL Server 5.7 为例： 安装目录下创建一个 “data” 文件夹 安装目录下创建一个 “my.ini” 文本文件，向其中写入以下内容（文件路径根据实际修改）： [mysqld] # mysql 安装目录 basedir="D:\Program\Environment\MySQL\MySQL Server 5.7" # mysql 数据库的数据存放目录 datadir="D:\Program\Environment\MySQL\MySQL Server 5.7\data" sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # MySQL服务器监听的端口 port=3306 # 服务端编码方式 character-set-server=utf8mb4 [clinet] # 客户端编码方式 loose-default-character-set=utf8mb4 # 端口号设置 port=3306 [WinMySQLadmin] Server="D:\Program\Environment\MySQL\MySQL Server 5.7\bin\mysqld.exe" 3、添加环境变量 右键 “开始菜单” -> “系统” -> “高级系统设置” -> “环境变量” 向 Path 中添加环境变量，值为 MySQL 安装目录下的 bin 文件夹： D:\Program\Environment\MySQL\MySQL Server 5.7\bin 4、安装 上面环境变量配置没有问题的话，就可以在 cmd 窗口中使用 mysqld 命令了。 此时以管理员身份运行 cmd 窗口，执行命令来初始化相关 data 文件： # 在前面配置好的 data 文件夹下会生成初始化的文件 mysqld --initialize-insecure --user=mysql 安装 MySQL 服务： mysqld -install 5、启动服务 可以通过以下命令启动 MySQL 服务： net start mysql 或者在 ”服务“ 窗口中找到 ”MySQL“ 这项服务，右键启动即可： 服务窗口可通过在“运行”窗口输入 “services.msc” 来启动，或者右键 开始菜单 -> 计算机管理 -> 服务和应用程序 -> 服务 找到。 在启动过程中有可能会出现报错： 在 MySQL 的服务属性中可以看到这项服务可执行文件的程序路径是不正确的： 这个窗口里面没有提供可以改这个路径的地方，查了一下，得需要到注册表中改，在注册表中（Win + R 运行窗口中输入“regedit”回车打开）找到 “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\MySQL” 这个路径，修改其中 ImagePath 的值，将引号里的路径替换为本地 MySQL 安装文件的实际路径（就只替换前面的路径，其他的不用改）： 保存退出之后，再到 “服务” 窗口中刷新一下，可执行文件的路径变成了新的路径之后再次启动即可成功启动 MySQL 服务。 目前本地运行的 MySQL 服务用 root 用户就可以登录，密码为空 MySQL 修改密码： 连接到数据库之后用 SQL 语句为 root 用户更改密码： alter user '用户名'@'localhost' identified by '新密码'; 修改完之后，刷新权限信息： flush privileges; 也可以在 MySQL 控制台中使用 mysqladmin 命令修改用户密码： # 新密码不需要加引号，否则会报错 mysqladmin -u [用户名] -p password [新密码]; 6、卸载 以管理员身份执行命令： mysqld -remove 删除服务： sc delete mysql 删除注册表文件： HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\MySQL HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\MySQL HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\eventlog\Application\MySQL 参考资料： MySQL8.0绿色版本——最纯净的安装体验(免去卸载不掉只能重做系统的‘囧‘境)_mysql8.0 绿色安装-CSDN博客 mysql 启动提示：错误2系统找不到指定文件；（本地计算机上的mysql服务启动后停止，某些服务在未由其他服务或程序使用时将自动停止）_无法编辑imagepath-CSDN博客
目录： 一、编译无线网卡驱动 1.1、clone 项目 1.2、安装环境 1.3、编译并加载驱动 二、更换Grub主题 2.1、下载主题文件 2.2、安装主题 2.3、修改启动顺序 三、修复启动项 四、安装搜狗输入法 4.1、添加中文语言支持 4.2、安装搜狗输入法 环境：ubuntu 22.04 一、编译无线网卡驱动 由于 Thinkbook16+ 原装的无线网卡是瑞昱的 RTL8852，装上 ubuntu 22.04 之后会因为没有驱动而无法使用 wifi 功能，这个问题一度困扰了我好长时间，由于没有网线，在此期间只能用手机的 USB 热点共享功能把手机当成 ubuntu 的无线网卡来用。 后来在网上查到一篇关于自己编译 RTL8852 无线网卡驱动的博客：thinkbook14+16+ 安装ubuntu22.04 解决wifi6驱动问题 + 加装完善让笔记本化身完全体，一劳永逸思路_ubuntu wifi6驱动_久日与至的博客-CSDN博客，于是才得以解决此问题。 1.1、clone 项目 驱动项目链接：GitHub - HRex39/rtl8852be: Realtek Linux WLAN Driver for RTL8852BE 根据系统 kernel 的版本选择不同的分支： # kernel < 5.18 选择默认主分支 git clone https://github.com/HRex39/rtl8852be.git # kernel >= 5.18 选择 dev 分支 git clone https://github.com/HRex39/rtl8852be.git -b dev 查看当前 ubuntu 系统内核的方法： uname -srm # 或者 uname -a 1.2、安装环境 进行编译之前需要安装环境： sudo apt update sudo apt install make gcc linux-headers-$(uname -r) build-essential 1.3、编译并加载驱动 编译： cd rtl8852be make -j8 sudo make install 加载驱动： sudo modprobe rtw89pci # 加载驱动 sudo modprobe -r rtw89pci # 卸载驱动 二、更换Grub主题 2.1、下载主题文件 主题文件可以在这里下载： GRUB Themes - Gnome-look.org GRUB Themes - Gnome-look.org (opendesktop.org) 以我下载到的 ubuntu.tar 为例，将其解压到 /boot/grub/themes/ubuntu (或者选择其他目录也行)： # 创建目录 mkdir /boot/grub/themes mkdir /boot/grub/themes/ubuntu # 将文件到解压到创建好的目录中 sudo tar -xf ubuntu.tar -C /boot/grub/themes/ubuntu 2.2、安装主题 修改配置文件，编辑 /etc/default/grub 文件 sudo nano /etc/default/grub 找到以 "#GRUB_THEME" 开头的一行，该行用来配置主题文件路径，将其改为 "主题文件路径/theme.txt” ： # 没有这一行的话直接新增即可 GRUB_THEME="/boot/grub/themes/ubuntu/theme.txt" 然后更新一下 grub 配置： sudo update-grub 最后重启，开机的时候就能看到效果了。 2.3、修改启动顺序 在 Windows + Linux 双系统的启动项中，如果在 BIOS 中选择的是 ubuntu 的话，开机进入的 grub 启动项选择中 ubuntu 系统是排在第一位的。但在双系统中一般来说都是 windows 用的比较多，所以每次启动都来选择 Windows 启动项的话也是一件挺麻烦的事情，那么可以将 windows 的系统启动项放到第一位，只有需要用到 ubuntu 的时候再去手动选择启动。 需要用到的是 Grub Customizer 这个软件，安装命令： sudo add-apt-repository ppa:danielrichter2007/grub-customizer sudo apt update sudo apt install grub-customizer 安装完成后，在 ubuntu 的应用列表中找到这个软件并启动，软件中会显示出当前所有的启动项。 修改启动顺序的话也很简单，点击选中 windows 启动项，用菜单栏上的箭头给移动上去就可以了。 PS：其实这个软件也可以用来替换主题 Grub 主题 三、修复启动项 这一项希望你用不到 ::(狂汗) 如果在修改启动项的时候，不小心操作失误把启动项修改坏了，造成 ubuntu 系统无法启动的话（我之前就是....），可以安装 boot-repaire 来进行修复： sudo apt-get install boot-repair boot-repaire 使用方法：使用 boot-repair 对 Windows + Ubuntu 双系统引导修复 - schips - 博客园 (cnblogs.com) 四、安装搜狗输入法 4.1、添加中文语言支持 打开 系统设置 -> 区域和语言 -> 管理已安装的语言，在 “语言” tab下点击“添加或删除语言” 弹出“已安装语言”窗口，勾选中文（简体），点击应用 回到“语言支持”窗口，在键盘输入法系统中，选择“fcitx” 注：如果在键盘输入法系统中，没有“fcitx”选项时，需要打开终端手动安装fcitx： sudo apt install fcitx 等安装成功之后再执行上述步骤 最后点击“应用到整个系统”，关闭窗口，重启电脑 4.2、安装搜狗输入法 从 搜狗输入法linux-首页 (sogou.com) 下载适用于 ubuntu 的 deb 安装包，然后用命令行安装（双击也可以安装，但就是少点 Linux 的灵魂）： sudo dpkg -i 路径/安装包名 然后安装依赖： sudo apt install libqt5qml5 libqt5quick5 libqt5quickwidgets5 qml-module-qtquick2 sudo apt install libgsettings-qt1 这些依赖非常重要，不安装的话就会出现只能输英文而输不了中文汉字的问题。 以上步骤进行完之后，重启电脑，就可以在 ubuntu 上使用搜狗输入法了。 参考资料： thinkbook14+16+ 安装ubuntu22.04 解决wifi6驱动问题 + 加装完善让笔记本化身完全体，一劳永逸思路_久日与至的博客-CSDN博客 搜狗输入法linux-安装指导 (sogou.com) Grub Customizer首页、文档和下载 - GRUB2 管理器 - OSCHINA - 中文开源技术交流社区
记录一下写论文过程中新学会的一些Word使用技巧
目录： 一、设置子标题 二、在不同的页设置不同的页眉/页码/页脚 三、添加的图片只占一行位置，无法完全显示出来 四、将文章中的英文、数字的字体格式一键设置为Times New Roman 五、在文档任意一个位置上开始之前的编号 六、快捷键： 七、绘制三线表 一、设置子标题 选中要设置为标题的行 开始 -> 段落上面找到多级标题的图标： 选择一个设置的多级标题样式： 就出现了标题，然后更改标题级别使其成为子标题： 此时标题编号可能不是我们想要的，所以还需要调整一下标题编号： 标题更改成功： 二、在不同的页设置不同的页眉/页码/页脚 在需要页眉/页码/页脚页码的页上第一行文字前（或是上一页的最后一行）添加分页符（布局-> 分隔符 -> 下一页）： 插入页眉/页码/页脚，此时插入的页眉/页码/页脚将以这个分页符为分界被分成了两部分，选中前面不用的页眉/页码/页脚，取消这个选项（引用 -> 链接到前一条页眉/页脚）： 接下来删除不用的页眉/页码/页脚即可，还有多出来的分页符 三、添加的图片只占一行位置，无法完全显示出来 就像这样： 方框为图片实际占的位置，但显示效果上只占了一行，图片不能全部显示出来 原因：图片的段落格式中设置了行距为“固定值” 解决办法：选中图片，在段落格式设置中把行距设置为单倍行距就可以解决问题 四、将文章中的英文、数字的字体格式一键设置为Times New Roman ctrl + A 选中全文，在字体设置中分别设置中文字体与英文字体的格式即可 还有个简单粗暴的方法，选中全文将全部字体设置为Times New Roman即可，中文不会受到影响。 五、在文档任意一个位置上开始之前的编号 先将这个编号的样式设置成与上一个编号相同的样式与级别 右键 -> 设置编号值（光标要放在标题一行或者选中标题），选择“继续上一列表”，填写需要开始的编号 六、快捷键： 格式刷： ctrl + Shift + C 复制格式 ctrl + Shift + V 粘贴格式 重复上一次操作：F4 七、绘制三线表 选中整个表格，右键 -> 表格属性 -> 边框和底纹 只保留表格的上下框线，并设置其宽度为 0.75 磅 再选中表格的第一行，右键设置其下框线即可：
目录： 1、监听端口 2、日志功能 2.1、访问日志 2.2、错误日志 3、配置域名 4、静态资源 5、重定向 5.1、网站根目录重定向 5.2、特定目录重定向 6、反向代理 7、负载均衡 8、SSL配置 1、监听端口 server { # 用于HTTP协议 listen 80; # 用于HTTPS协议 listen 443 ssl; # 用于HTTP2 listen 443 ssl http2; # 使用IPv6监听80端口 listen [::]:80; # 仅使用IPv6 listen [::]:80 ipv6only=on; } 2、日志功能 Nginx的日志分为两种：access_log （访问日志）和 error_log（错误日志）。 对于日志的格式，Nginx提供了一种名为 combine 的格式，如果没有明确指定日志格式则默认使用该格式。 如果不使用 combine 格式的话，可以使用 log_format 指令来自定义，其具体用法参考Nginx日志配置详解或者官方文档：HttpLog模块-Nginx中文文档。 2.1、访问日志 访问日志主要记录客户端的请求，客户端向Nginx服务器发起的每一次请求都记录在这里。客户端IP，浏览器信息，referer，请求处理时间，请求URL等都可以在访问日志中得到。 server { # 访问日志文件的写入位置，相对或绝对路径 access_log /path/to/file.log; # 选择访问日志功能的开启(on)或关闭(off) access_log on; } 2.2、错误日志 错误日志记录服务器和请求处理过程中的错误信息。 server{ # 错误日志的写入位置 error_log logs/error.log error; # 错误日志的级别，分为 debug, info, notice, warn, error, crit, alert,emerg，其取值范围是按紧急程度从低到高排列 # 只有日志的错误级别等于或高于level指定的值才会写入错误日志中。默认值是error error_log file [level]; } 3、配置域名 server { # 监听domain.com server_name domain.com; # 监听多个域名 server_name domain.com www.domain.com; # 监听所有域名 server_name *.domain.com; # 监听所有顶级域名 server_name domain.*; # 监听未指定的主机名（比如侦听IP地址本身） server_name ""; } 4、静态资源 server { listen 80; server_name domain.com; location / { # 设置网站的根目录 root /path/to/website; } } 5、重定向 5.1、网站根目录重定向 server { listen 80; server_name www.domain.com; # 将 www.domain.com 进行301重定向，跳转至 http://domain.com$request_uri return 301 http://domain.com$request_uri; } 5.2、特定目录重定向 server { listen 80; server_name www.domain.com; # 将链接 http://www.domain.com/redirect-url 进行301重定向，跳转到http://otherdomain.com location /redirect-url { return 301 http://otherdomain.com; } } 如将 domain.com 永久重定向到 www.domain.com： server { listen 80; server_name domain.com; return 301 http://www.$host$request_uri; } 6、反向代理 反向代理 - 维基百科，自由的百科全书 (wikipedia.org) Reverse proxy - Wikipedia server { listen 80; server_name domain.com; # 对特定主机的3000端口进行反向代理 location / { proxy_pass http://0.0.0.0:3000; } } 7、负载均衡 负载均衡 - 维基百科，自由的百科全书 (wikipedia.org) Load balancing (computing) - Wikipedia upstream node_js { server 0.0.0.0:3000; server 0.0.0.0:4000; server 123.131.121.122; } server { listen 80; server_name domain.com; location / { proxy_pass http://node_js; } } 8、SSL配置 server { listen 443 ssl; server_name domain.com; ssl on; # 证书文件，格式不一定都是pem，还可能是其他格式 ssl_certificate /path/to/cert.pem; # 秘钥文件，格式不一定都是pem，还可能是其他格式 ssl_certificate_key /path/to/privatekey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_timeout 1h; ssl_session_cache shared:SSL:50m; add_header Strict-Transport-Security max-age=15768000; } # 将HTTP永久重定向到HTTPS server { listen 80; server_name domain.com; return 301 https://$host$request_uri; } 部分内容转载修改自： Nginx Cheatsheet (hashnode.dev) Nginx日志配置详解_biubiuli的博客-CSDN博客_nginx 日志配置
【踩坑实录】Github提交时出现错误：remote：Permission to xxx/test.git denied to xxx
目录： 问题再现 错误原因 解决方法 问题再现 Github 提交时出现错误，报错信息如下： remote: Permission to xxx/test.git denied to xxx. fatal: unable to access 'https://github.com/xxx/test.git/': The requested URL returned error: 403 如果再试一次，可能还会有如下报错： fatal: unable to access 'https://github.com/xxx/xxx.git/': OpenSSL SSL_read: Connection was reset, errno 10054 或者： fatal: unable to access 'https://github.com/xxx/xxx.git/': Failed to connect to github.com port 443: Timed out 错误原因 这个是由于在同一台计算机上先后使用了两个Github账号。 第一个账号进行了提交之后，这个账号的凭据信息就被保存了下来，然后切换到第二个账号进行提交时，系统依然会使用第一个账号的凭据信息进行提交，因此便会报错。 解决方法 进入控制面板，找到凭据管理器选项，选择其中的 Windows 凭据，删除已经保存的 Github 凭据： 然后再重新进行提交操作，此时会弹出Github登录窗口，重新登录之后就能成功提交了。
目录 一、SpringMVC介绍 二、映射请求路径 2.1、使用@ResquestMapping进行路径映射 2.2、@ResquestMapping的属性 2.2.1、value或path 2.2.2、method 2.2.3、params 2.2.4、headers 2.2.5、consumes 2.2.6、produces 2.3、@ResquestMapping的衍生注解 三、请求参数传递 3.1、GET/POST请求传递基础参数 3.2、传递复杂参数 3.2.1、日期类型 3.2.2、引用类型 3.2.3、数组 3.2.4、集合（List/Set/Map） 3.3、传递Json数据 四、响应 4.1、返回Json数据 4.2、封装返回结果 五、REST风格 5.1、简介 5.2、规则 5.3、相关注解 5.3.1、@RestController 5.3.2、@PathVariable 5.3.3、@RequestParam 5.3.4、@RequestBody 5.4、Rest风格开发示例 5.3.1、查询 5.3.2、新增 5.3.3、修改（更新） 5.3.4、删除 六、异常处理 6.1、自定义异常 6.2、处理异常的方式 6.2.1、使用@ControllerAdvice和@ExceptionHandler 6.2.2、实现HandlerExceptionResolver接口 七、拦截器 7.1、创建拦截器 7.2、注册和配置拦截器 7.3、执行流程和顺序 一、SpringMVC介绍 Spring MVC 是 Spring 框架中的一个模块，专门用于构建基于模型-视图-控制器（Model-View-Controller，MVC）设计模式的 Web 应用程序。 相关依赖坐标： <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 在 config 包里面新建初始化 Servlet 的配置类： public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } } 再新建 SpringMVC 配置类： @Configuration @ComponentScan("com.wlplove.controller") public class SpringMvcConfig { } 二、映射请求路径 2.1、使用@ResquestMapping进行路径映射 @RequestMapping 是 Spring MVC 中将 HTTP 请求映射到控制器方法的注解，它用于类级别或方法级别，可以根据请求的 URL、HTTP 请求方法（GET、POST 等）、请求参数、请求头等信息来匹配对应的处理逻辑。 @RequestMapping 注解应用在方法上，可以为该方法映射 URL 请求路径： public class UserController { @RequestMapping("/save") public String save() { // ... } } 也可以应用在类上，为该类中的所有方法设置基础的 URL 请求路径： @RequestMapping("/user") public class UserController { @RequestMapping("/save") public void save() { // ... } @RequestMapping("/delete") public void delete() { // ... } } 2.2、@ResquestMapping的属性 2.2.1、value或path 这两个属性作用相同，用于指定 URL 请求路径。用一个字符串映射一个路径，也可以用一个字符串数组映射多个路径。 @RequestMapping(value = "/save") @RequestMapping(path = "/save") // 映射多个路径 @RequestMapping(value = {"/save", "/saveUser"}) @RequestMapping(path = {"/save", "/saveUser"}) 一般也可以简写： @RequestMapping("/save") // 映射多个路径 @RequestMapping({"/save", "/saveUser"}) 2.2.2、method method 属性用于指定处理的 HTTP 方法。可以是一个 RequestMethod 枚举值或枚举值数组，常见的请求方法有 GET、POST、PUT、DELETE 等。 public class UserController { // save方法只处理POST和GET请求，路径为/save @RequestMapping(value = "/save", method = {RequestMethod.POST, RequestMethod.GET}) @ResponseBody public String save() { // ... } } 2.2.3、params 用于指定请求中必须包含的请求参数和值。可以使用一些特殊的表达式，如 paramName 表示请求中必须包含 paramName 参数；!paramName 表示请求中不能包含 paramName 参数，paramName=value 表示请求中 paramName 参数的值必须为 value。 // 请求中必须包含name参数 @RequestMapping(value = "/save", params = "name") // 请求中不能包含name参数 @RequestMapping(value = "/save", params = "!name") // 请求中name参数的值必须是123 @RequestMapping(value = "/save", params = "name=123") // 请求中name参数的值不能是123 @RequestMapping(value = "/save", params = "name!=123") 2.2.4、headers 用于指定请求中必须包含的请求头及其值，用法与 params 类似。 // 只有当请求/download路径的Accept头的值为application/pdf时，downloadPdf方法才会被调用 @RequestMapping(value = "/download", headers = "Accept=application/pdf") @ResponseBody public String downloadPdf() { // ... } 2.2.5、consumes 用于指定请求的内容类型（Content-Type），即客户端发送给服务器的数据的格式。 // uploadJson方法只处理Content-Type为application/json的请求 @RequestMapping(value = "/upload", consumes = "application/json") @ResponseBody public String uploadJson() { // ... } 2.2.6、produces 用于指定响应的内容类型（Accept），即服务器返回给客户端的数据的格式。 // getHtml方法返回的响应内容类型为text/html @RequestMapping(value = "/get", produces = "text/html") @ResponseBody public String getHtml() { return " Hello "; } 2.3、@ResquestMapping的衍生注解 为了简化代码，Spring 还提供了一些 @RequestMapping 的衍生注解，它们实际上是 @RequestMapping(method = xxx) 的特定形式： @GetMapping：等同于 @RequestMapping(method = RequestMethod.GET)，用于处理 HTTP Get 请求 @PostMapping：等同于 @RequestMapping(method = RequestMethod.POST)，用于处理 HTTP Post 请求 @PutMapping：等同于 @RequestMapping(method = RequestMethod.PUT)，用于处理 HTTP Put 请求 @DeleteMapping：等同于 @RequestMapping(method = RequestMethod.DELETE)，用于处理 HTTP Delet 请求 @PatchMapping：等同于 @RequestMapping(method = RequestMethod.PATCH)，用于处理 HTTP Patch 请求 三、请求参数传递 3.1、GET/POST请求传递基础参数 GET 请求的参数通过 URL 传递，附加在 URL 后面，形式为查询字符串（Query String），例如： http://localhost:8080/save?name=Jerry&age=13 POST 请求数据通过请求体（Request Body）传递，不会显示在 URL 中，在 Postman 中使用传递参数： 在 Java 的控制器方法中使用相同名称的形参，SpringMVC 可以自动将请求参数绑定到控制器方法中同名的形参上： @Controller public class UserController { // 如果要限制使用特定请求方法（POST/GET），将RequestMapping换成PostMapping或者GetMapping即可 @RequestMapping("/save") @ResponseBody public String save(String name, int age) { // ... } } 除此之外，SpringMVC 也支持将请求参数映射到不同名称的形参上，需要用 @RequestParam 注解指定请求参数绑定到控制器方法的哪个形参上： @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(@RequestParam("name")String userName, @RequestParam("age")int userAge) { // ... } } @RquestParam 注解的属性： value 或 name：指定请求参数的名称。如果省略，默认使用控制器方法的形参名作为参数名称。 required：指定参数是否为必填项。默认值为 true，表示请求中必须包含该参数，如果请求中缺少该参数，Spring 会抛出 MissingServletRequestParameterException。如果设置为 false，则参数可以为空。 defaultValue：指定参数的默认值。如果请求中未提供该参数，则使用该默认值。 3.2、传递复杂参数 3.2.1、日期类型 在请求中传递特定格式的日期： http://localhost:8080/save?date=2023-10-12 在控制层方法的形参前面加上 @DateTimeFormat 注解并指定日期格式，SpringMVC 就可以将同名请求参数转换为日期格式： @RequestMapping("/dateParse") @ResponseBody public String dateParse(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date) { // ... } 3.2.2、引用类型 例如存在一个 User 对象，其中包含一个引用类型的成员 address： public class Address { // 省 private String province; // 市 private String city; } public class User { // 姓名 private String name; // 年龄 private String age; // 地址——引用对象 private Address address; } 控制器方法中使用 User 对象接收参数： @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(User user) { // ... } } 那么在请求中传递参数时保持参数名与控制器方法形参名相同即可（不相同时使用 @RequestParam 绑定）： GET： http://localhost:8080/save?name=Jerry&age=13&address.province=河南&address.city=开封 POST： 3.2.3、数组 控制器方法中使用数组接收参数： @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(String[] nameArray) { // ... } } 那么在请求中传递参数时都使用相同名称的参数即可： GET： http://localhost:8080/save?nameArray=Jerry&nameArray=Tom&nameArray=Mike POST： 3.2.4、集合（List/Set/Map） 控制器方法中使用集合接收参数（形参前需要加 @RequestParam 注解）： @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save(@RequestParam List<String> nameList) { // ... } } 在请求中传递参数的方式与数组相同： GET： http://localhost:8080/save?nameArray=Jerry&nameArray=Tom&nameArray=Mike POST： 3.3、传递Json数据 添加处理 Java 对象与 JSON 数据相互转换的依赖坐标： <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.18.2</version> </dependency> 在 SpringMVC 配置上添加 @EnableWebMvc 注解开启 Spring MVC 的默认配置（其中包括 Java 对象与 JSON 数据的相互转换）： @Configuration @ComponentScan("com.wlplove.controller") @EnableWebMvc public class SpringMvcConfig { // ... } 发送的 JSON 数据： { "name": "Tom", "age": 12 } 控制器方法中用集合或者对象接收时形参前加上 @RequestBody 注解将请求体中的数据绑定到控制器方法的参数上： @RequestMapping("/json") @ResponseBody public String json2Dto(@RequestBody User user) { // ... } 四、响应 4.1、返回Json数据 需要添加 Jackson 的依赖： <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.18.2</version> </dependency> 在控制器方法上使用 @ResponseBody 注解，告知 SpringMVC 将控制层方法的返回值直接写进 HTTP 响应体，而不是解析为视图。最后 SpringMVC 通过 HttpMessageConverter 接口将返回值转换为适当的格式（如 JSON、XML等）。 @RequestMapping("/returnJson") @ResponseBody public User returnJson() { User user = new User(); user.setAge(20); user.setName("QWERT"); return user; } @ResponseBody 支持的返回值类型： 基本类型（String、int、boolean 等）。 自定义对象（User、Product 等）。 集合或数组（List<User>、String[] 等）。 4.2、封装返回结果 新建一个返回结果对象： public class Result { /** 状态码 */ private Integer code; /** 返回内容 */ private String msg; /** 数据对象 */ private Object data; public Result(Integer code, Object data) { this.code = code; this.data = data; } public Result(Integer code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } // get和set方法 } 自定义返回编码： public class Code { public static final Integer OK = 000000; public static final Integer ERR =999999; // 其他编码 } 对 controller 方法的返回值都统一成这个返回对象： @Controller @RequestMapping("/users") public class UserController { @Autowired private UserMapper userMapper; @RequestMapping("/{id}") @ResponseBody public Result findById(@PathVariable Integer id) { User user = userMapper.selectById(id); Integer code = user != null ? Code.OK : Code.ERR; String msg = user != null ? "数据查询成功" : "数据查询失败"; return new Result(code, msg, user); } // ... } 五、REST风格 5.1、简介 REST（Representational State Transfer）风格是一种软件架构风格，用于设计网络应用程序，其核心概念旨在通过 HTTP 协议实现客户端与服务器之间简洁、可扩展且高效的交互。 传统风格资源描述形式： http://lcoalhost/user/getById?id=1 http://localhost/user/saveUser REST风格描述形式： http://localhost/user/1 http://localhost/user REST 风格是一种设计接口的约定方式，并非规范。 5.2、规则 REST 使用统一的接口与服务器进行交互，基于 HTTP 协议的标准方法： GET 用于获取资源 POST 用于创建资源 PUT 用于更新资源 DELETE 用于删除资源 5.3、相关注解 5.3.1、@RestController @RestController 是 Spring 4.0 引入的一个组合注解，它是 @Controller 和 @ResponseBody 的结合体。其主要作用是将一个控制器类标记为使用 REST 风格，使用 @RestController 注解的类中的所有处理方法默认都会将返回值直接写入 HTTP 响应体，以 JSON、XML 等数据格式返回，而不是返回视图进行渲染。 5.3.2、@PathVariable @PathVariable 是 Spring MVC 中用于将 URL 中的模板变量绑定到控制器方法形参上的注解。它通常用于 RESTful API 中，从 URL 路径中提取参数值。 如根据 ID 查询用户的控制器方法： @GetMapping("/users/{id}") public String findById(@PathVariable Long id) { // ... } 那么对于 GET 请求链接 http://localhost/users/123456，该控制器可以通过 @PathVariable 将 “123456” 绑定到形参 id 上。 也支持在路径中定义多个路径变量： http://localhost/users/123456/orders/987654321 在控制器方法中接收多个参数： @GetMapping("/users/{userId}/orders/{orderId}") public Order getOrder(@PathVariable Long userId, @PathVariable Long orderId) { // ... } Spring MVC 5.3 及以上版本支持可选路径变量。如果路径变量是可选的，可以设置属性 required = false： @GetMapping("/users/{id}") public User getUser(@PathVariable(required = false) Long id) { if (id == null) { // 返回所有用户 return userService.getAllUsers(); } // 返回指定id的用户 return userService.getUserById(id); } 那么： http://localhost/users id为null，返回所有用户 http://lcoalhost/users/123 返回id为123的用户 5.3.3、@RequestParam 详见 3.1。 5.3.4、@RequestBody 详见 3.3。 5.4、Rest风格开发示例 5.3.1、查询 // 查询全部 @GetMapping("/users") public xxxResponse findAll() { // ... } // 根据主键查询 @GetMapping("/users/{id}") public xxxResponse findById(@PathVariable Long id) { // ... } 5.3.2、新增 @PostMapping("/users") public xxxResponse add(@RequestBody User user) { // ... } 5.3.3、修改（更新） @PutMapping("/users") public xxxResponse update(@RequestBody User user) { //... } 5.3.4、删除 @DeleteMapping("/delete/{id}") public xxxResponse delete(@PathVariable Long id) { // ... } 六、异常处理 6.1、自定义异常 新建一个自定义异常类 BusinessException： public class BusinessException extends RuntimeException { private Integer code; public BusinessException(Integer code, String message) { super(message); this.code = code; } // get和set方法 } 自定义异常编码： public class ErrorCode { public static final Integer TIMEOUT_ERROR = 10001; // 其他异常编码 } 在业务层代码中抛出异常： throw new BusinessException(ErrorCode.TIMEOUT_ERROR, "请求超时，请稍后再试"); 6.2、处理异常的方式 6.2.1、使用@ControllerAdvice和@ExceptionHandler @ControllerAdvice 是 Spring 框架提供的一个用于定义全局异常处理、数据绑定和数据预处理等逻辑的注解。在配合标注了 @ExceptionHandler 注解的方法使用时，可以在拦截到对应的异常之后终止原 controller 方法的执行，并转入该方法执行设定好的异常处理逻辑。 在 controller 包中新建一个全局异常处理类 GlobalExceptionHandler，在类中的方法上面使用 @ExceptionHandler 注解指定这个方法要处理哪种异常： @ControllerAdvice public class GlobalExceptionHandler { // Exception是所有异常的父类，在此表示拦截到所有的异常都会进行处理 @ExceptionHandler(Exception.class) // 方法参数中加入这种异常类型的形参，就可以获取到这个异常的信息 public ResponseEntity<String> doException(Exception ex) { return new ResponseEntity<>("异常信息: " + ex.getMessage()); } // 只处理RuntimeException异常 @ExceptionHandler(RuntimeException.class) public Response<T> doRuntimeException(RuntimeException ex){ // RuntimeException异常处理逻辑 } // 只处理IOException异常 @ExceptionHandler(IOException.class) public Response<T> doIOException(IOException ex){ // IOException异常处理逻辑 } // ... } 如果在控制器中使用 Rest 风格的开发，可以使用 @RestControllerAdvice 注解，@RestControllerAdvice 是 @ControllerAdvice 和 @ResponseBody 的组合注解，类中的方法返回值会自动进行 JSON 或 XML 等格式的序列化，直接作为响应体返回给客户端。 6.2.2、实现HandlerExceptionResolver接口 HandlerExceptionResolver 是 Spring Web 框架中的一个接口，它提供了一种统一处理控制器（@Controller）中抛出的异常的机制。通过实现这个接口，开发者可以自定义异常处理逻辑，以满足不同的业务需求，比如返回特定格式的错误响应、记录异常日志等。 处理异常主要通过该接口中的 resolveException 方法实现 方法参数： HttpServletRequest request：当前请求对象，通过它可以获取请求的各种信息，如请求头、请求参数等。 HttpServletResponse response：当前响应对象，可用于设置响应头、响应状态码等。 Object handler：处理当前请求的处理器对象，通常是一个控制器方法。 Exception ex：在处理请求过程中抛出的异常对象。 方法返回值： ModelAndView 是 Spring MVC 中用于封装视图和模型数据的类。如果返回 null，表示该异常解析器没有处理该异常，Spring 将继续尝试其他的异常解析器。如果返回一个非空的 ModelAndView 对象，Spring 会根据其中的视图信息渲染相应的视图，并将模型数据传递给视图。 新建一个异常处理类 CustomExceptionResolver，用 @Component 注解声明这是一个 Spring Bean，实现 HandlerExceptionResolver 接口中的 resolveException 方法： @Component public class CustomExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); if (ex instanceof IllegalArgumentException) { modelAndView.setViewName("error/400"); // 跳转到 400 错误页面 modelAndView.addObject("errorMessage", "非法参数: " + ex.getMessage()); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } else { modelAndView.setViewName("error/500"); // 跳转到 500 错误页面 modelAndView.addObject("errorMessage", "服务器内部错误: " + ex.getMessage()); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } return modelAndView; } } 七、拦截器 在 Spring 中，拦截器是利用 AOP（面向切面编程）的思想实现的一种机制，用在请求处理的不同阶段（如请求到达 controller 方法之前、controller 方法执行之后、视图渲染之前等）执行自定义逻辑，在以下的场景中广泛使用： 权限验证：在请求到达控制器之前，检查用户是否具有访问该资源的权限，如验证用户登录状态。 日志记录：记录请求的相关信息，如请求的 URL、参数、处理时间等，方便后续的调试和监控。 性能监控：统计请求的处理时间，找出性能瓶颈。 请求参数处理：对请求参数进行统一的预处理，如编码转换、参数验证等。 7.1、创建拦截器 在 controller 包中新建一个包 interceptor，创建拦截器类 ProjectInterceptor，实现 HandlerInterceptor 接口，并用 @Component 声明为一个 bean： @Component public class ProjectInterceptor implements HandlerInterceptor { // 在控制器处理请求之前调用 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 通过handler对象经过反射可以获取到原controller方法 System.out.println("preHandle: 请求到达控制器之前"); // 可以在此处进行权限验证、日志记录等操作 // 如果返回 false，请求将被中断，不再执行postHandle与afterCompletion return true; } // 在控制器处理请求之后、视图渲染之前调用 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle: 控制器处理请求之后"); // 可以在此处修改模型数据或视图 } // 在视图渲染完成之后调用（无论请求是否成功） @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion: 视图渲染完成之后"); // 可以在此处进行资源清理、日志记录等操作 } } 7.2、注册和配置拦截器 在 config 包下新建一个配置类 SpringMvcSupport，继承 WebMvcConfigurationSupport 类，并重写 addInterceptors 方法，在这个方法中注册和配置拦截器： @Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { // 注入之前定义好的拦截器类 @Autowired private ProjectInterceptor projectInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor) // 指定要拦截的路径,可以传入多个路径 .addPathPatterns("/**") // 指定要排除的路径,可以传入多个路径 .excludePathPatterns("/login", "/register"); } } addPathPatterns 和 excludePathPatterns 方法均支持 Ant 风格的路径匹配规则，具体语法规则如下： ?：匹配单个字符。 示例：/user? 可以匹配 /user1、/userA，但不能匹配 /user12。 \*：匹配任意数量的字符（不包括路径分隔符 /）。 示例：/user/* 可以匹配 /user/123、/user/profile，但不能匹配 /user/123/address。 `\**：匹配任意数量的字符（包括路径分隔符/`）。 示例：/user/** 可以匹配 /user/123、/user/123/address。 {variable}：匹配路径变量。 示例：/user/{id} 可以匹配 /user/123，并将 123 绑定到路径变量 id 除了新建一个 SpringMvcSupport 配置类来配置拦截器的方法外，还可以让原来的 SpringMvc 配置类来实现 WebMvcConfigurer 接口中的 addInterceptors 方法，也能达到相同的效果： @Configuration @ComponentScan("com.xxx.controller") @EnableWebMvc public class SpringMvcSupport implements WebMvcConfigurer { // 注入之前定义好的拦截器类 @Autowired private ProjectInterceptor projectInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptor) // 指定要拦截的路径,可以传入多个路径 .addPathPatterns("/**") // 指定要排除的路径,可以传入多个路径 .excludePathPatterns("/login", "/register"); } } 7.3、执行流程和顺序 拦截器执行流程： 如果有多个拦截器，形成拦截器链，它们的执行顺序如下： preHandle：按照注册顺序依次执行，必定运行。 postHandle：按照注册顺序的逆序执行，可能不运行。 afterCompletion：按照注册顺序的逆序执行，可能不运行。 例如拦截器 A、B、C 按顺序注册： preHandle 执行顺序：A → B。 postHandle 执行顺序：B → A。 afterCompletion 执行顺序：B → A。
目录： 一、演示效果 二、源代码 1.HTML代码 2.CSS 在B站上看到一个up主写的一段下拉菜单代码，实现效果还挺好看的，遂进行小改之后拿来收藏，以供日后使用。 源代码出自：B站up主 山羊の前端小窝 视频链接：https://www.bilibili.com/video/BV1S44y147oV 一、演示效果 演示如下，鼠标悬浮即可查看效果： 二、源代码 1.HTML代码 消息 回复我的 收到的赞 我的消息 动态 知识分子没文化 博客 收藏夹 默认收藏夹 计算机编程 有点意思 说的不错 投稿 专栏投稿 音频投稿 贴纸投稿 视频投稿 投稿管理 2.CSS * { margin: 0; padding: 0; list-style: none; font-size: 20px; color: #f4f1de; } .shell { display: flex; justify-content: center; margin-top:50px; } .button, .portrait { background-color: #50536e; width: 170px; height: 65px; text-align: center; line-height: 65px; transition: 0.3s; /* 指定浏览网页时鼠标指针的形状 */ cursor: pointer; } .portrait::before { content: ''; display: block; width: 100px; height: 100px; border-radius: 50%; transform: translate(30px, -30px); background-image: url("https://image.wlplove.com/static/img/icon/headpic.png"); background-size: cover; border: 10px solid #fff; } .information { width: 220px; background-color: #e07a5f; transform: translate(-20px, -200px); border-radius: 10px; padding: 20px 0; line-height: 0; height: 0; transition: 0.3s; /* opacity属性指定了一个元素的不透明度，其取值从0-1。*/ /* 在0时会完全看不见，1表示完全可见 */ opacity: 0; } .button:hover { background-color: #d15a39; } .button li:hover { background-color: #ffb29d; } .button ul li { height: 0; transition: 0.2s; opacity: 0; transform: translateY(-65px); background-color: #e07a5f; } .button:hover li { height: 65px; opacity: 1; transform: translateY(0); } .portrait:hover .information { opacity: 1; line-height: 65px; transform: translate(-20px, -10px); height: auto; } a{ text-decoration: none; }
目录 一、创建Webapp项目 二、Spring配置类 三、数据源对象（以Druid为例） 四、整合MyBatis 4.1、数据库配置 4.2、MyBatis配置 五、整合SpringMVC 六、整合Log4j 七、整合Junit 环境说明： 数据库：MySQL 8.0 Java版本：JDK8 通过注解整合 SSM 框架流程： 创建 Web 工程 SSM 整合 Spring 框架：SpringConfig MyBatis 框架：JdbcConfig / jdbc.properties / MybatisConfig SpringMVC 框架：ServletConfig / SpringMvcConfig 一、创建Webapp项目 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 二、Spring配置类 引入 spring-conext 的依赖坐标： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.25.RELEASE</version> </dependency> 创建一个 Java 类 SpringConfig 作为 Spring 配置类，类上面添加 @Configuration 注解标识这是一个配置类，添加 @ComponentScan 注解来设置扫描注解的路径 @Configuration @ComponentScan("com.xxx") /** * 如果有多个要扫描的包路径，可以用数组格式： * @ComponentScan({"com.xxx.dao","com.xxx.service"}) */ public class SpringConfig { } 三、数据源对象（以Druid为例） 导入 Druid 数据源的依赖坐标： <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.22</version> </dependency> 新建一个配置数据库连接信息的类 JdbcConfig，里面引入配置文件中的数据库信息，然后用一个方法构造并返回一个 DataSource 对象，最后用 @Bean 注解设置这个方法的返回值成为 Spring IoC 容器的一个 Bean： public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; /** * 数据源Bean * @return */ @Bean public DataSource dataSource() { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } } Spring 配置类 SpringConfig 中用 Import 注解引入 JdbcConfig 这个类： @Configuration @ComponentScan("com.xxx") +@Import({JdbcConfig.class}) public class SpringConfig { } 四、整合MyBatis 4.1、数据库配置 在 src/main/resources 目录下新建一个配置数据库连接信息的配置文件 jdbc.properties： jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db?useSSL=false&setUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=root 使用 @PropertySource 注解在 Spring 配置类 SpringConfig 上加载外部的 properties 文件： @Configuration @ComponentScan({"com.xxx"}) +@PropertySource("classpath:jdbc.properties") public class SpringConfig { } 4.2、MyBatis配置 导入 MyBatis 及 MySQL 的相关依赖坐标： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.25.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.16</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> 新建一个 MyBatis 的配置类 MybatisConfig，配置 SqlSessionFactoryBean 和 MapperScannerConfigurer 这两个 Bean： public class MybatisConfig { @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); ssfb.setDataSource(dataSource); ssfb.setTypeAliasesPackage("com.xxx.xxx"); return ssfb; } @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer msc = new MapperScannerConfigurer(); // Mapper的XML映射文件所在路径 msc.setBasePackage("com.xxx.dao"); return msc; } } Spring 配置类 SpringConfig 中用 Import 注解引入 MybatisConfig 这个类： @Configuration @ComponentScan("com.xxx") +@Import({JdbcConfig.class, MybatisConfig.class}) @PropertySource("classpath:jdbc.properties") public class SpringConfig { } 五、整合SpringMVC 导入 SpringMVC、Servlet 与 jackson 的依赖坐标： <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.25.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.18.2</version> </dependency> 新建 SpringMVC 配置类 SpringMvcConfig： @Configuration @ComponentScan("com.wlplove.controller") @EnableWebMvc public class SpringMvcConfig { } 新建 Servlet 的初始化类 ServletInitializer： public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } } 六、整合Log4j 导入 Log4j 的依赖坐标： <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.23.1</version> </dependency> 在 "src/main/java/resources" 下新建一个 Log4j 的配置文件 Log4j2.xml： <?xml version="1.0" encoding="UTF-8"?> <configuration> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> </Console> <!-- <File name="allLog" fileName="logs/AlliInOne.log" append="true">--> <!-- <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>--> <!-- <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{9.9.9.1}(%L) %m%n"/>--> <!-- </File>--> <RollingFile name="rollingFileInfo" fileName="logs/${date:yyyy-MM}/log-info-${date:yyyy-MM-dd}.log" filePattern="logs/${date:yyyy-MM}/log-info-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders> <loggers> <!-- level指定日志级别，从低到高的优先级： ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF --> <Logger name="org.mybatis" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <Logger name="org.springframework" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <root level="DEBUG"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </root> </loggers> </configuration> Log4j 配置文件详解：彻底掌握Log4j2 - 蚂蚁小哥 - 博客园 修改 MyBatis 配置类中的 SqlSessionFactoryBean，设置其 Configuration 属性： public class MybatisConfig { // ... @Bean public SqlSessionFactoryBean getSqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); ssfb.setTypeAliasesPackage("com.xxx.xxx"); ssfb.setDataSource(dataSource); + Configuration configuration = new Configuration(); + // 修改MyBatis使用的日志框架为Log4j + configuration.setLogImpl(Log4j2Impl.class); + ssfb.setConfiguration(configuration); return ssfb; } // ... } 七、整合Junit 导入 Junit 和 Spring-test 的依赖坐标： <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.10.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.10.RELEASE</version> </dependency> 新建一个测试类： // 在 JUnit 5 中集成 Spring 功能（如果是Junit4则换成@RunWith(SpringJunit4ClassRunner.class)） @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SpringConfig.class) public class SpringTest { @Autowired private UserMapper userMapper; @Test public void find() { User user = userMapper.select(); } }
目录： 一、通过注解定义Bean 1.1、启用注解支持 1.2、定义Bean 1.3、@Component的派生注解 1.3.1、@Repository 1.3.2、@Service 1.3.3、@Controller 1.3.4、@Configuration 1.4、用注解代替XML配置文件 1.4.1、配置类 1.4.2、初始化IoC容器 二、通过注解使用Bean 2.1、自动装配 2.1.1、@Autowired 2.1.2、@Qualifier 2.1.3、@Resource 2.1.4、@Primary 2.1.5、@Value 2.2、读取properties文件配置 2.3、作用域 2.4、自定义Bean初始化/销毁操作 2.5、总结 三、整合框架 3.1、数据源对象（以Druid为例） 3.2、整合Mybatis 3.3、整合Log4j 3.4、整合Junit 四、Spring事务 一、通过注解定义Bean 1.1、启用注解支持 <context:annotation-config /> 若要以注解方式注入 Bean，则需要开启扫描包中的组件，并用 base-package 属性指定扫描的基本包路径： <context:component-scan base-package="com.xxx" /> 使用 <context:annotation-scan> 标签时，默认将隐式启用对注解的支持。 1.2、定义Bean 在 XML 配置中如果要将一个 Bean 交给 Spring IoC 容器管理，需要进行如下配置： <bean id="userService" class="com.wlplove.service.impl.UserServiceImpl" /> 若用注解要实现相同目的，只需要在要被管理的 Java 类上添加 @Component 注解，并在后面的括号中指定 Bean 的名称： // 注解后面的括号里是 bean 的名称 @Component("userServiceImpl") public class UserServiceImpl implements UserService { // ... } @Component 注解也可以不指定 Bean 名称，Spring 会自动为该 Bean 生成一个默认的名称，通常是类名的首字母小写形式： @Component // 可以用名称“userServiceImpl”来获取这个Bean public class UserServiceImpl implements UserService { // ... } 所以只需要在 Java 类上加入 @Component 注解，用于标识这个类是 Spring 容器中的组件（即 Bean），就可以实现与 XML 配置中的 <bean> 标签相同的作用。 1.3、@Component的派生注解 此外，Spring 还提供了 @Component 的几个派生注解：@Repository、@Service、@Controller、@Configuration，这几个注解的功能和用法与 @Component 相同，但它们在使用场景上有所不同。 1.3.1、@Repository 用于数据访问层（Dao 层）中与数据库交互的类。 Spring 会对使用 @Repository 注解的类进行特定的异常处理（将数据访问层的异常，如 SQLException 等转换为 Spring 的 DataAccessException 异常，方便统一处理和异常传播）。 @Repository public interface UserMapper { // ... } 1.3.2、@Service 用于标识业务逻辑层（Service 层）中处理核心业务逻辑的类。 使用 @Service 注解可以将一个类声明为业务逻辑组件，将其对象存入 Spring 容器中，以便在其他组件（如Controller）中通过注入该 service 类的实例来使用其业务逻辑。 @Service public class UserServiceImpl implements UserService { // ... } 1.3.3、@Controller 用于标识控制层（Controller 层）中处理响应和请求的类。 被 @Controller 标记的类实际上就是一个 Spring MVC Controller 对象，它可以处理请求，并通过 @RequestMapping 等注解将不同的请求分发到对应的方法上。 @Controller public class UserController { // ... } 1.3.4、@Configuration 用于标记替换 XML 配置文件的配置类，这个注解的用法将在 1.4 中详细说明。 1.4、用注解代替XML配置文件 Spring 支持完全去除 XML 配置文件实现纯注解开发，实现的方式就是使用一个 Java 类来代替原本的 XML 配置文件。 1.4.1、配置类 创建一个 Java 类，类上面添加 @Configuration 注解标识这是一个配置类： @Configuration public class SpringConfig { // ... } 在 XML 配置文件中会用到 <context:annotation-config base-package=""> 标签来设置扫描注解的路径，在配置类上添加 @ComponentScan 注解也可以实现相同的效果： @Configuration +@ComponentScan("com.xxx") public class SpringConfig { // ... } 如果有多个包路径，可以用数组格式： @ComponentScan({"com.xxx.dao","com.xxx.service"}) 1.4.2、初始化IoC容器 当创建出一个配置类之后，初始化 Spring IoC 容器的方式也需要改变。 原来是通过 ClassPathXmlApplicationContext 类加载 XML 配置文件初始化得到 IoC 容器： ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml"); 现在改用 AnnotationConfigApplicationContext 类来加载配置类得到 Spring IoC 容器： ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); 二、通过注解使用Bean 2.1、自动装配 2.1.1、@Autowired 在要引用的依赖上面使用 @Autowired 注解开启自动装配注入该依赖： @Service public class BookServiceImpl implements BookService { @Autowired private BookDao bookDao; public void save() { System.out.println("book service save ..."); bookDao.insert(); } } @Autowired 注解默认按照类型（byType）进行自动装配。 2.1.2、@Qualifier 如果 Spring IoC 容器中存在多个类型相同的 Bean 时，仅仅使用 @Autowired 根据类型自动装配时就导致 Spring 无法确定应该自动注入哪一个 Bean，便会抛出 NoUniqueBeanDefinitionException 异常。那么此时使用 @Qualifier 注解来指定要装配的 Bean 名称： @Repository public class BookDao1 implements BookDao { // ... } @Repository public class BookDao2 implements BookDao { // ... } @Service public class BookServiceImpl implements BookService { @Autowired // 存在两个BookDao类型的Bean，这里指定注入名称为bookDao1的Bean @Qualifier("bookDao1") private BookDao bookDao; } 需要注意的是，@Qualifier 不能单独使用，必须与 @Autowired 一起使用。因为 @Autowired 主要是根据类型进行自动装配，而 @Qualifier 则在此基础上匹配 Bean 名称，从而进行更精确的限制。 2.1.3、@Resource 还有一个与 @Autowired 类似的注解是 @Resource，默认按照名称（byName）进行自动装配，通过其 name 属性指定要注入的 Bean 名称： @Service public class BookServiceImpl implements BookService @Resource(name = "bookDao2") private BookDao bookDao; } 不像 @Autowired 是 Spring 框架提供的用于按类型（byType）自动装配的注解，@Resource 是 JavaEE 标准中（javax.annotation.Resource）提供的用于按名称（byName）自动装配的注解，并非 Spring 框架所特有的。 2.1.4、@Primary 与 @Qualifier 类似，@Primary 注解也可以用来解决当存在多个相同类型的 Bean 时应该注入哪一个 Bean 的问题。 如果 Spring IoC 容器中存在多个类型相同的 Bean，给该 Bean 上面添加 @Primary 注解，则 Spring 会优先使用标注了 @Primary 的 Bean。 2.1.5、@Value 使用 @Value 注解实现简单类型的注入： @Service public class UserServiceImpl implements UserService { @Value(30) private int age; @Value("root") private String userName; } @Value 注解除了用于给简单类型的成员注入固定的值以外，也可以用于将配置文件中的属性注入给简单类型的成员，配置文件中的属性名写在占位符 ${} 里面： @Service public class UserServiceImpl implements UserService { @Value("${user.name}") private String userName; } 2.2、读取properties文件配置 在 src/main/resources 目录下新建一个配置数据库连接信息的配置文件 jdbc.properties： jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db?useSSL=false&setUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=root 使用 @PropertySource 注解在 Spring 配置类上加载外部的 properties 文件，在要注入值的成员上添加 @Value 注解指定注入哪个属性： /** * Spring配置类 */ @Configuration @ComponentScan({"com.xxx"}) @PropertySource("classpath:jdbc.properties") public class SpringConfig { // ... } /** * 使用属性 */ public class DataBaseConnInfo { // 注入配置文件中的属性 @Value("${jdbc.driverName}") private String driverName; @Value("${jdbc.url}") private String url; } 若要加载多个配置文件应使用数组： @PropertySource({"classpath:jdbc.properties","classpath:appConfig.properties"}) 2.3、作用域 使用注解 @Scope 定义 Bean 的作用域是 prototype（原型/非单例）或者 singleton（单例）。 public class AppConfig { @Bean // @Scope("prototype") @Scope("singleton") public MyBean myBean() { return new MyBean(); } } 2.4、自定义Bean初始化/销毁操作 使用 @PostConstruct 注解定义初始化方法（方法名不限），将在构造方法之后执行该方法。 使用 @PreDestroy 注解定义销毁方法（方法名不限），在容器销毁前执行该方法，一般用来释放占用的资源等。 public class UserServiceImpl implements UserService { @PostConstruct publid void init() { System.out.println("init ...."); } @PreDestroy public void destory() { System.out.println("destory ..."); } } 2.5、总结 三、整合框架 3.1、数据源对象（以Druid为例） 导入 Druid 数据源的依赖坐标： <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.22</version> </dependency> 新建一个配置数据库连接的类 JdbcConfig，里面引入配置文件中的数据库信息，然后用一个方法构造并返回一个 DataSource 对象，最后用 @Bean 注解设置这个方法的返回值成为 Spring IoC 容器的一个对象： public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; /** * 数据源 * @return */ @Bean public DataSource dataSource() { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } } Spring 配置类中用 Import 注解引入 JdbcConfig 这个类： @Configuration @ComponentScan("com.xxx") +@Import({JdbcConfig.class}) public class SpringConfig { // ... } 3.2、整合Mybatis 导入 MyBatis 的依赖坐标： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.1.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.16</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> 新建一个 MyBatis 配置类 MybatisConfig，配置 SqlSessionFactoryBean 和 MapperScannerConfigurer 这两个 Bean： public class MybatisConfig { @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); ssfb.setDataSource(dataSource); ssfb.setTypeAliasesPackage("com.xxx.xxx"); return ssfb; } @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer msc = new MapperScannerConfigurer(); // Mapper接口所在的包路径 msc.setBasePackage("com.xxx.mapper"); return msc; } } Spring 配置类中用 Import 注解引入 MybatisConfig 这个类： @Configuration @ComponentScan("com.xxx") +@Import({JdbcConfig.class, MybatisConfig.class}) public class SpringConfig { // ... } 3.3、整合Log4j 导入 Log4j 的依赖坐标： <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.23.1</version> </dependency> 在 "src/main/java/resources" 下新建一个 Log4j 的配置文件 Log4j2.xml： <?xml version="1.0" encoding="UTF-8"?> <configuration> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> </Console> <!-- <File name="allLog" fileName="logs/AlliInOne.log" append="true">--> <!-- <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>--> <!-- <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{9.9.9.1}(%L) %m%n"/>--> <!-- </File>--> <RollingFile name="rollingFileInfo" fileName="logs/${date:yyyy-MM}/log-info-${date:yyyy-MM-dd}.log" filePattern="logs/${date:yyyy-MM}/log-info-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders> <loggers> <!-- level指定日志级别，从低到高的优先级： ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF --> <Logger name="org.mybatis" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <Logger name="org.springframework" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <root level="DEBUG"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </root> </loggers> </configuration> Log4j 配置文件详解：彻底掌握Log4j2 - 蚂蚁小哥 - 博客园 修改 Mybatis 配置类中的 SqlSessionFactoryBean，设置其 Configuration 属性： public class MybatisConfig { // ... @Bean public SqlSessionFactoryBean getSqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); ssfb.setTypeAliasesPackage("com.xxx.xxx"); ssfb.setDataSource(dataSource); + Configuration configuration = new Configuration(); + // 修改MyBatis使用的日志框架为Log4j2 + configuration.setLogImpl(Log4j2Impl.class); + ssfb.setConfiguration(configuration); return ssfb; } // ... } 3.4、整合Junit 导入 Junit 和 spring-test 的依赖坐标： <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.10.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.10.RELEASE</version> </dependency> 新建一个测试类： // 在 JUnit 5 中集成 Spring 功能，如果是Junit4则换成@RunWith(SpringJunit4ClassRunner.class) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SpringConfig.class) public class SpringTest { @Autowired private UserMapper userMapper; @Test public void find() { User user = userMapper.select(); } } 四、Spring事务 导入 Spring 事务的依赖坐标： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.10.RELEASE</version> </dependency> 在 Spring 的配置类上添加注解 @EnableTransactionManagement 开启 Spring 的事务管理功能： @Configuration @ComponentScan("com.xxx") @Import({JdbcConfig.class, MybatisConfig.class}) +@EnableTransactionManagement public class SpringConfig { // ... } 配置类中添加 PlatformTransactionManager 这个 Bean： @Bean public PlatformTransactionManager getTransactionManager(DataSource dataSource) { DataSourceTransactionManager dstm = new DataSourceTransactionManager(); dstm.setDataSource(dataSource); return dstm; } 最后在 service 方法或类上面用 @Transactional 注解设置添加事务管理，在执行该方法或类中的方法时便会开启事务管理，如果程序执行时发生异常就回滚之前的数据库操作。 需要注意的是，当在同一类中调用有 @Transactional 注解的方法时，可能不会触发事务管理，因为它绕过了 Spring 的代理机制，解决办法是将这个方法也标记为 @Transactional。
目录： 一、创建Webapp项目 二、加载properties文件 2.1、新建properties文件 2.2、指定要加载的properties文件 2.3、读取properties文件属性值的方式 三、数据源对象（以Druid为例） 3.1、导入Druid数据源依赖坐标 3.2、在XML文件中配置数据源对象为Spring管理的Bean 四、整合MyBatis 4.1、导入依赖坐标 4.2、配置SqlSessionFactoryBean 4.3、配置MapperScannerConfigurer 五、整合Junit 六、整合Log4j 在 pom.xml 文件中导入 Spring 的坐标依赖： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> 一、创建Webapp项目 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 在 src/main/resources 目录下新建一个 spring-config.xml 文件作为 Spring 的配置文件： <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans> 二、加载properties文件 2.1、新建properties文件 在 src/main/resources 目录下新建一个配置数据库连接信息的配置文件 jdbc.properties： jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db jdbc.username=root jdbc.password=root 2.2、指定要加载的properties文件 在 Spring 的 XML 配置文件中加载指定 properties 文件，写法有多种： 加载资源路径（src/main/java/resources）下指定的一个 properties 文件： <context:property-placeholder location="classpath:jdbc.properties"/> 也可以加载资源路径下的多个 properties 文件： <context:property-placeholder location="classpath:jdbc.properties,classpath:jdbc2.properties"/> 使用通配符加载 properties 文件：在资源路径或 jar 包中搜索并加载所有 properties 文件 <context:property-placeholder location="classpath*:*.properties"/> 再加上 system-properties-mode="NEVER"，表示 Spring 容器在解析 properties 配置文件时，不使用系统属性来替换配置文件中的属性，从而避免系统属性对配置产生影响： <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/> 2.3、读取properties文件属性值的方式 <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> 三、数据源对象（以Druid为例） 3.1、导入Druid数据源依赖坐标 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.22</version> </dependency> 3.2、在XML文件中配置数据源对象为Spring管理的Bean <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="initialSize" value="10"/> <property name="maxActive" value="100"/> <property name="maxWait" value="-1"/> </bean> 四、整合MyBatis 4.1、导入依赖坐标 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.1.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.16</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> 4.2、配置SqlSessionFactoryBean SqlSessionFactoryBean 是 Spring 与 MyBatis 集成时使用的一个关键类，它实现了 Spring 的 FactoryBean<SqlSessionFactory> 接口，用于创建 SqlSessionFactory 对象。 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:com/wlplove/dao/*.xml"/> <property name="typeAliasesPackage" value="com.wlplove.domain"/> <!-- <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>--> <property name="configuration"> <bean class="org.apache.ibatis.session.Configuration"> <property name="mapUnderscoreToCamelCase" value="true"/> <property name="cacheEna bled" value="true"/> <property name="defaultExecutorType" value="SIMPLE"/> <property name="logImpl" value="org.apache.ibatis.logging.log4j2.Log4j2Impl"/> </bean> </property> </bean> 4.3、配置MapperScannerConfigurer MapperScannerConfigurer 是 Spring 框架中用于整合 MyBatis 的一个配置类，它可以扫描指定包下的 Mapper 接口，并将它们的实现类自动注入到 Spring IoC 容器中。 <bean name="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.wlplove.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> 五、整合Junit 导入 Junit 和 spring-test 的依赖坐标： <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.10.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.10.RELEASE</version> </dependency> 新建一个测试类： // 在 JUnit 5 中集成 Spring 功能，如果是Junit4则换成@RunWith(SpringJunit4ClassRunner.class) @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SpringConfig.class) public class SpringTest { @Autowired private UserMapper userMapper; @Test public void test() { User user = userMapper.select(); } } 六、整合Log4j 导入 Log4j 的依赖坐标： <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.23.1</version> </dependency> 在 "src/main/java/resources" 下新建一个 Log4j 的配置文件 Log4j2.xml： <?xml version="1.0" encoding="UTF-8"?> <configuration> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> </Console> <!-- <File name="allLog" fileName="logs/AlliInOne.log" append="true">--> <!-- <ThresholdFilter level="ALL" onMatch="ACCEPT" onMismatch="DENY"/>--> <!-- <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{9.9.9.1}(%L) %m%n"/>--> <!-- </File>--> <RollingFile name="rollingFileInfo" fileName="logs/${date:yyyy-MM}/log-info-${date:yyyy-MM-dd}.log" filePattern="logs/${date:yyyy-MM}/log-info-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/> <Policies> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="20"/> </RollingFile> </Appenders> <loggers> <!-- level指定日志级别，从低到高的优先级： ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF --> <Logger name="org.mybatis" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <Logger name="org.springframework" level="WARN" additivity="false"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </Logger> <root level="DEBUG"> <appender-ref ref="console"/> <appender-ref ref="rollingFileInfo"/> </root> </loggers> </configuration> Log4j 配置文件详解：彻底掌握Log4j2 - 蚂蚁小哥 - 博客园 修改 Spring 配置中的 SqlSessionFactoryBean，修改 MyBatis 使用的日志框架为 Log4j2： <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:com/wlplove/dao/*.xml"/> <property name="typeAliasesPackage" value="com.wlplove.entity"/> <property name="configuration"> <bean class="org.apache.ibatis.session.Configuration"> <property name="logImpl" value="org.apache.ibatis.logging.log4j2.Log4j2Impl"/> </bean> </property> </bean>