Springboot基础知识(16)- 整合 MyBatis
MyBatis 是一个半自动化的 ORM 框架,所谓半自动化是指 MyBatis 只支持将数据库查出的数据映射到 POJO 实体类上,而实体到数据库的映射则需要我们自己编写 SQL 语句实现,相较于Hibernate 这种完全自动化的框架,Mybatis 更加灵活,我们可以根据自身的需求编写 sql 语句来实现复杂的数据库操作。
随着 Spring Boot 越来越流行,越来越多的被厂商及开发者所认可,MyBatis 也开发了一套基于 Spring Boot 模式的 starter:mybatis-spring-boot-starter。
本文将在 “ Springboot基础知识(08)- spring-boot-starter-web(Web启动器)” 里 SpringbootWeb 项目 整合 Thymeleaf 模板 的基础上,对整合 MyBatis 进行讲解。
1. 导入 JDBC、MariaDB 和 MyBatis 相关依赖包
访问 http://www.mvnrepository.com/,查询 spring-boot-starter-data-jdbc、mybatis-spring-boot-starter 等
修改 pom.xml:
1 <project ... > 2 ... 3 4 <dependencies> 5 ... 6 7 <!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client --> 8 <dependency> 9 <groupId>org.mariadb.jdbc</groupId> 10 <artifactId>mariadb-java-client</artifactId> 11 </dependency> 12 13 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jdbc --> 14 <dependency> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-data-jdbc</artifactId> 17 </dependency> 18 19 <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> 20 <dependency> 21 <groupId>org.mybatis.spring.boot</groupId> 22 <artifactId>mybatis-spring-boot-starter</artifactId> 23 <version>2.2.0</version> 24 </dependency> 25 26 ... 27 </dependencies> 28 29 ... 30 </project>
注:Spring Boot 默认为数据库驱动程序做了版本仲裁,所以我们在导入数据库驱动时,可以不再声明版本。需要注意的是,数据库驱动的版本必须与数据库的版本相对应。
在IDE中项目列表 -> SpringbootWeb -> 点击鼠标右键 -> Maven -> Reload Project
2. 配置 MyBatis
在 Spring Boot 的配置文件 src/main/resources/application.properties 中对 MyBatis 进行配置。
1 # 数据源配置 2 spring.datasource.username=root # 数据库登陆用户名 3 spring.datasource.password=123456 # 数据库登陆密码 4 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb # 数据库url 5 spring.datasource.driver-class-name=org.mariadb.jdbc.Driver # 数据库驱动 6 7 # MyBatis 配置 8 mybatis.mapper-locations=classpath:mybatis/mapper/*.xml 9 mybatis.type-aliases-package=com.example.entity 10 mybatis.configuration.map-underscore-to-camel-case=true
3. 配置数据库(MariaDB)
1) XAMPP for Windows
https://www.apachefriends.org/download.html
本文安装版本 7.4.25,用到 XAMPP 的如下功能:
+ Apache 2.4.51
+ MariaDB 10.4.21 (MySQL的分支)
+ PHP 7.4.25 (VC15 X86 64bit thread safe) + PEAR
+ phpMyAdmin 5.1.1
2) 创建数据库 testdb 和 admin 表,SQL 脚本如下
1 CREATE TABLE `admin` ( 2 `id` int(11) NOT NULL, 3 `username` varchar(50) NOT NULL, 4 `password` varchar(255) DEFAULT NULL, 5 `age` int(11) DEFAULT NULL, 6 `createtime` timestamp NULL DEFAULT NULL 7 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 8 9 INSERT INTO `admin` (`id`, `username`, `password`, `age`, `createtime`) VALUES 10 (1, 'admin', '123456', 21, '2020-01-01 01:01:01'),(2, 'test', '123456', 28, '2020-02-02 02:02:02');
4. 示例
1) 创建 src/main/resources/templates/auth.html 文件
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Auth</title> 6 </head> 7 <body> 8 9 <h3>Auth</h3> 10 11 <p th:text="${msg}"></p> 12 13 <form action="/user/auth/post" method="POST"> 14 15 <p>Username: <input type="text" name="username" value="admin" /></p> 16 <p>Password: <input type="text" name="password" value="123456" /></p> 17 18 <p><input type="submit" value="Submit" /></p> 19 20 </form> 21 22 </body> 23 </html>
2) 根据 admin 表创建 src/main/java/com/example/entity/Admin.java 文件
1 import java.util.Date; 2 3 public class Admin { 4 private Integer id; 5 private String username; 6 private String password; 7 private Integer age; 8 private Date createtime; 9 10 public Admin() { 11 12 } 13 14 public String getUsername() { 15 return username; 16 } 17 public void setName(String username) { 18 this.username = username; 19 } 20 21 public String getPassword() { 22 return password; 23 } 24 public void setPassword(String password) { 25 this.password = password; 26 } 27 28 public Integer getAge() { 29 return age; 30 } 31 public void setAge(Integer age) { 32 this.age = age; 33 } 34 35 public Date getCreatetime() { 36 return createtime; 37 } 38 public void setCreatetime(Date createtime) { 39 this.createtime = createtime; 40 } 41 42 @Override 43 public String toString() { 44 return "Admin {" + 45 "username = " + username + 46 ", password = " + password + 47 ", age = " + age + 48 ", createtime = " + createtime + 49 '}'; 50 } 51 }
3) 创建 src/main/java/com/example/mapper/AdminMapper.java 文件
1 package com.example.mapper; 2 3 import org.apache.ibatis.annotations.Mapper; 4 import com.example.entity.Admin; 5 6 @Mapper 7 public interface AdminMapper { 8 // 通过用户名密码查询用户 9 Admin getByNameAndPassword(Admin admin); 10 }
当 mapper 接口较多时,可以在 Spring Boot 主启动类上使用 @MapperScan 注解扫描指定包下的 mapper 接口,而不再需要在每个 mapper 接口上都标注 @Mapper 注解。
4) 创建 Mapper 映射文件
在配置文件 application.properties 通过 mybatis.mapper-locations 指定的位置中创建 AdminMapper.xml,代码如下。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.example.mapper.AdminMapper"> 4 <resultMap id="BaseResultMap" type="Admin"> 5 <id column="id" jdbcType="INTEGER" property="id"/> 6 <result column="username" jdbcType="VARCHAR" property="username"/> 7 <result column="password" jdbcType="VARCHAR" property="password"/> 8 <result column="age" jdbcType="VARCHAR" property="age"/> 9 <result column="createtime" jdbcType="DATE" property="createtime"/> 10 </resultMap> 11 12 <sql id="Base_Column_List"> 13 id, username, password, age, createtime 14 </sql> 15 16 <!-- 根据用户名密码查询用户信息,application.properties 中已通过 type-aliases-package 指定了实体类所在包 --> 17 <select id="getByNameAndPassword" resultType="Admin"> 18 SELECT * 19 FROM admin 20 WHERE username = #{username,jdbcType=VARCHAR} 21 AND password = #{password,jdbcType=VARCHAR} 22 </select> 23 </mapper>
使用 Mapper 进行开发时,需要遵循以下规则:
(1) mapper 映射文件中 namespace 必须与对应的 mapper 接口的完全限定名一致。
(2) mapper 映射文件中 statement 的 id 必须与 mapper 接口中的方法的方法名一致
(3) mapper 映射文件中 statement 的 parameterType 指定的类型必须与 mapper 接口中方法的参数类型一致。
(4) mapper 映射文件中 statement 的 resultType 指定的类型必须与 mapper 接口中方法的返回值类型一致。
5) 创建 src/main/java/com/example/service/AdminService.java 文件
1 package com.example.service; 2 3 import com.example.entity.Admin; 4 5 public interface AdminService { 6 public Admin getByNameAndPassword(Admin admin); 7 }
6) 创建 src/main/java/com/example/service/AdminServiceImpl.java 文件
1 package com.example.service; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Service; 5 6 import com.example.entity.Admin; 7 import com.example.mapper.AdminMapper; 8 import com.example.service.AdminService; 9 10 @Service("adminService") 11 public class AdminServiceImpl implements AdminService { 12 @Autowired 13 AdminMapper adminMapper; 14 15 @Override 16 public Admin getByNameAndPassword(Admin admin) { 17 return adminMapper.getByNameAndPassword(admin); 18 } 19 }
7) 创建 src/main/java/com/example/controller/UserController.java 文件
1 package com.example.controller; 2 3 import java.util.Map; 4 import javax.servlet.http.HttpSession; 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.beans.factory.annotation.Autowired; 8 9 import com.example.entity.Admin; 10 import com.example.service.AdminService; 11 12 @Controller 13 @RequestMapping("/user") 14 public class UserController { 15 @Autowired 16 AdminService adminService; 17 18 @RequestMapping("/auth") 19 public String auth() { 20 return "auth"; 21 } 22 23 @RequestMapping("/auth/post") 24 public String authPost(Admin admin, Map<String, Object> map, HttpSession session) { 25 26 Admin loginAdmin = adminService.getByNameAndPassword(admin); 27 if (loginAdmin != null) { 28 session.setAttribute("loginAdmin", loginAdmin); 29 return "redirect:/home"; 30 } else { 31 map.put("msg", "Invalid username or password"); 32 } 33 34 return "auth"; 35 } 36 }
访问:http://localhost:9090/user/auth ,点击页面 “Submit” 按钮后页面跳转到 http://localhost:9090/home 表示 myBatis 访问数据库成功,home 页面可以参考 auth.html 自行添加到模版文件夹中。
5. 用注解方式代替 Mapper 映射文件 (AdminMapper.xml)
上面的示例中, mapper 映射文件其实就是一个 XML 配置文件,它存在 XML 配置文件的通病,即编写繁琐,容易出错。即使是一个十分简单项目,涉及的 SQL 语句也都十分简单,我们仍然需要花费一定的时间在mapper 映射文件的配置上。
为了解决这个问题,MyBatis 针对实际实际业务中使用最多的 “增删改查”操作,分别提供了以下注解来替换 mapper 映射文件,简化配置:
@Select
@Insert
@Update
@Delete
通过以上注解,基本可以满足我们对数据库的增删改查操作。
1) 修改 src/main/java/com/example/mapper/AdminMapper.java 文件
1 package com.example.mapper; 2 3 import org.apache.ibatis.annotations.Mapper; 4 import org.apache.ibatis.annotations.Select; 5 import org.apache.ibatis.annotations.Delete; 6 import org.apache.ibatis.annotations.Insert; 7 import org.apache.ibatis.annotations.Update; 8 9 import com.example.entity.Admin; 10 11 @Mapper 12 public interface AdminMapper { 13 14 @Select("SELECT * FROM admin WHERE username = #{username,jdbcType=VARCHAR} AND password = #{password,jdbcType=VARCHAR}") 15 Admin getByNameAndPassword(Admin admin); 16 17 @Delete("DELETE FROM admin WHERE id = #{id,jdbcType=INTEGER}") 18 int deleteByPrimaryKey(Integer id); 19 20 @Insert("INSERT INTO admin ( username, password, age)" + 21 "VALUES ( #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{age,jdbcType=VARCHAR})") 22 int insert(Admin admin); 23 24 @Update("UPDATE admin SET " + 25 " username = #{username,jdbcType=VARCHAR},\n" + 26 " password = #{password,jdbcType=VARCHAR},\n" + 27 " age = #{age,jdbcType=INTEGER}\n" + 28 "WHERE id = #{id,jdbcType=INTEGER}") 29 int updateByPrimaryKey(Admin admin); 30 }
2) 修改 src/main/resources/application.properties 文件,注释掉扫描 MyBatis 配置
1 # MyBatis 配置 2 #mybatis.mapper-locations=classpath:mybatis/mapper/*.xml 3 #mybatis.type-aliases-package=com.example.entity 4 #mybatis.configuration.map-underscore-to-camel-case=true
访问:http://localhost:9090/user/auth
mapper 接口中的任何一个方法,都只能使用一种配置方式,即注解和 mapper 映射文件二选一,但不同方法之间,这两种方式则可以混合使用,例如方法 1 使用注解方式,方法 2 使用 mapper 映射文件方式。
我们可以根据 SQL 的复杂程度,选择不同的方式来提高开发效率。
(1) 如果没有复杂的连接查询,我们可以使用注解的方式来简化配置;
(2) 如果涉及的 sql 较为复杂时,则使用 XML (mapper 映射文件)的方式更好一些。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战