论springboot里使用Mybatis的妙用
发布时间:2024-12-13 13:11:07
Mybatis概述
MyBatis 的核心概念和工作原理
SQL 映射(SQL Mapping):
MyBatis 将 SQL 语句与 Java 方法映射在一起,开发者可以在 XML 文件或注解中编写 SQL,然后将 SQL 与具体的方法绑定。
MyBatis 提供了简单的配置语法,避免了繁琐的 JDBC 代码,帮助开发者专注于 SQL 的编写和调优。
动态 SQL 支持:
MyBatis 提供了动态 SQL 标签(如 <if>、<where>、<choose> 等)来帮助构建 SQL 语句,适应不同的查询条件。
Mapper 接口:
在 MyBatis 中,Mapper 是用来描述和管理 SQL 的接口。通过在接口上添加 SQL 映射,开发者可以通过调用接口方法来完成数据库操作。
会话管理(SqlSession):
MyBatis 提供了 SqlSession 对象,用于执行数据库操作。通过 SqlSession,开发者可以执行 CRUD 操作,同时管理数据库事务。
MyBatis 的使用步骤
定义数据库表结构:准备好数据库表以及字段信息。
编写 POJO 类:创建数据库表的对应实体类(POJO),用于封装表数据。
创建 Mapper 接口:定义数据操作接口,并编写 SQL 映射文件,绑定 Mapper 接口与 SQL 语句。
配置 MyBatis 环境:编写配置文件(如 mybatis-config.xml),设置数据库连接、映射路径等。
使用 SqlSession 执行操作:通过 SqlSession 对象调用 Mapper 方法,执行查询、插入、更新或删除操作。
MyBatis 的优势
SQL 控制力强:可以手动优化 SQL,提高性能。
学习成本低:SQL 是数据库交互的基础,SQL 控制能力和操作的透明性更高。
与 Spring 的整合度高:可以通过 MyBatis-Spring 项目无缝整合在 Spring 项目中。
注意事项
维护性:SQL 语句分散在代码中,较大的项目中 SQL 的维护可能变得复杂。
动态 SQL 的复杂度:复杂的动态 SQL 可能变得难以阅读和调试。
示例
假设有一个 User 表,包含 id、name、age 三个字段:
定义 POJO 类
java
public class User {
private Integer id;
private String name;
private Integer age;
// getters and setters
}
Mapper 接口
java
public interface UserMapper {
User selectUserById(int id);
List<User> selectAllUsers();
}
Mapper XML 配置
xml
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" resultType="User">
SELECT * FROM User WHERE id = #{id}
</select>
<select id="selectAllUsers" resultType="User">
SELECT * FROM User
</select>
</mapper>
调用 Mapper 方法
java
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
MyBatis 以其灵活性和对 SQL 的高掌控力在数据库操作中得到广泛应用,是许多开发者的 ORM 首选。
配置MyBatis
在springboot项目中pom.xml里引入mybatis依赖
<!-- mybatis起步依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis和springboot依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
由于是在springboot里,配置mybatis和数据库的就在这个目录下的application.properties文件里“项目名/src/main/resources/application.properties ”
spring.application.name=springboot_mybatis
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/personalblog
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456
我们在启动类同级创建一个pojo包存放实体类User 类定义了用户的基本信息,使用了合适的封装类型(如 Integer 和 Short)。使用包装类型的好处是可以处理 null 值,避免在数据库中未设置值时引发空指针异常。
package com.liuxin.pojo;
public class User {
private Integer id; // 用户ID
private String name; // 用户姓名
private Short age; // 用户年龄
private Short gender; // 用户性别
private String phone; // 用户电话号码
// 其他属性...
}
创建mapper包存放mapper接口类@Mapper 注解,告诉 MyBatis 这个接口是一个 Mapper,MyBatis 会自动生成实现类并交给 Spring 的 IOC 容器管理。
使用 @Select 注解直接在接口方法上编写 SQL 语句是一种方便的方法,尤其在小型项目中。但在大型项目中,通常会使用 XML 文件来管理 SQL 语句,以便于维护和管理。
package com.liuxin.mapper;
import com.liuxin.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper//在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理
public interface UserMapper {
//查询全部用户信息
@Select("select * from user")
public List<User> list();
}
接下来我们就可以到src/test测试类SpringbootMybatisApplicationTests.java里去使用这个接口
package com.liuxin;
import com.liuxin.mapper.UserMapper;
import com.liuxin.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest//springboot整合单元测试的注解,,它会加载整个 Spring Boot 应用上下文,以便于进行集成测试。
class SpringbootMybatisApplicationTests {
@Autowired//@Autowired 注解用于自动注入 UserMapper
private UserMapper userMapper;
@Test//此注解会默认加载整个springboot项目
public void testListUser(){
List<User> userList = userMapper.list();//这个方法返回是是数据库查询的信息
userList.stream().forEach(user -> {//stream流, Java 8 的 Stream API 进行遍历
System.out.println(user);
});
}
}
运行后就可以获得以下信息
User{id=1, name='白眉鹰王', age=55, gender=1, phone='18800000000'}
User{id=2, name='金毛狮王', age=45, gender=1, phone='18800000001'}
User{id=3, name='青翼蝠王', age=38, gender=1, phone='18800000002'}
User{id=4, name='紫衫龙王', age=42, gender=2, phone='18800000003'}
User{id=5, name='光明左使', age=37, gender=1, phone='18800000004'}
User{id=6, name='光明右使', age=48, gender=1, phone='18800000005'}
什么是 JDBC ?(可跳)
JDBC(Java Database Connectivity) 是 Java 提供的一种用于连接和操作数据库的 API。它为 Java 应用程序提供了一种标准的方式与关系型数据库进行交互。通过 JDBC,开发者可以执行 SQL 语句、处理结果集以及进行事务管理等。
JDBC 的基本工作流程:
加载数据库驱动:使用 Class.forName() 加载 JDBC 驱动。
建立数据库连接:使用 DriverManager.getConnection() 方法创建连接。
创建 Statement:通过连接对象创建 Statement、PreparedStatement 或 CallableStatement 对象。
执行 SQL 语句:调用 executeQuery() 或 executeUpdate() 方法执行 SQL 语句。
处理结果集:通过 ResultSet 对象获取查询结果。
关闭连接:完成操作后,关闭 ResultSet、Statement 和 Connection。
JDBC 的主要特点:
数据库无关性:JDBC 提供的 API 是数据库无关的,可以连接不同类型的数据库。
低级 API:JDBC 是一个低级别的 API,开发者需要处理连接、SQL 语句、结果集等,代码量相对较大。
MyBatis 与 JDBC 的关系
MyBatis 是一个持久层框架,用于简化数据库操作。它与 JDBC 的关系可以从以下几个方面来理解:
封装 JDBC:MyBatis 在内部使用 JDBC 进行数据库操作,但它对 JDBC 进行了封装,使得开发者可以更方便地使用数据库。开发者无需编写繁琐的 JDBC 代码,MyBatis 提供了更高层次的接口。
SQL 映射:MyBatis 允许开发者将 SQL 语句与 Java 方法进行映射。通过 XML 或注解,开发者可以直接在 Java 代码中定义 SQL,而不必直接操作 Statement 和 ResultSet。
自动映射结果:MyBatis 可以自动将 SQL 查询结果映射到 Java 对象,减少了手动转换结果集的工作。
支持复杂查询:MyBatis 提供了丰富的 SQL 支持,包括动态 SQL、嵌套查询等,开发者可以使用更复杂的查询逻辑,而不需要直接处理 SQL 语句的拼接。
事务管理:MyBatis 提供了简单的事务管理功能,可以与 Spring 等框架集成,方便进行事务控制。
总结
JDBC 是一种用于 Java 应用程序与数据库之间的连接和操作的 API,适合进行底层的数据库操作。
MyBatis 是一个基于 JDBC 的持久层框架,它提供了更高层次的封装,使得数据库操作更简单、更易于维护。通过 MyBatis,开发者可以更专注于业务逻辑,而不必过多关注底层数据库的操作细节。
什么是数据库连接池?(可跳)
数据库连接池是一个用于管理数据库连接的工具,它在应用程序启动时创建和维护一定数量的数据库连接。连接池将这些连接统一管理,使得应用程序在需要时可以快速获取一个空闲的连接,而不必每次都建立新的数据库连接,从而显著提高了数据库访问的效率。
数据库连接池的主要特性和作用:
预创建连接:连接池在启动时就会创建一定数量的数据库连接,避免了高并发场景下频繁建立和销毁连接的开销。
复用连接:连接池可以将空闲的连接复用,减少系统的资源占用。
限流保护:连接池可以限制同时连接到数据库的最大连接数,防止数据库因请求过多而崩溃。
自动管理:连接池会自动管理连接的创建、复用和销毁,确保连接的高效和稳定性。
数据库连接池的常用实现
常用的数据库连接池包括:
HikariCP:性能优越,配置简单,Spring Boot 默认连接池。
DBCP(Database Connection Pool):Apache 提供的连接池,稳定性较高。
C3P0:提供一些高级功能,如超时连接检测、自动回收等。
Druid:阿里巴巴的连接池,性能好,提供了丰富的监控功能。
连接池与 JDBC 的关系
在传统的 JDBC 应用中,每次操作数据库都需要:
通过 DriverManager.getConnection() 创建新的数据库连接。
执行完操作后手动关闭连接。
这种方法在高并发环境中会导致大量的连接开销。数据库连接池可以将 JDBC 连接进行复用,应用程序可以从池中快速获取连接,操作完后再将连接归还给池,从而减少了频繁创建和关闭连接的成本。
连接池与 MyBatis 的关系
MyBatis 是基于 JDBC 的持久层框架,因此它也需要和数据库进行连接。在高并发应用中,直接使用 JDBC 的原始连接方式会影响性能,因此通常会结合数据库连接池一起使用。MyBatis 中可以配置数据库连接池来管理数据库连接。
在 MyBatis 配置文件(如 mybatis-config.xml)中,可以指定连接池类型,并设置连接池参数。例如:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED"> <!-- 使用连接池 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="poolMaximumActiveConnections" value="10"/>
<property name="poolMaximumIdleConnections" value="5"/>
</dataSource>
</environment>
</environments>
连接池在 Spring Boot + MyBatis 中的使用
在 Spring Boot 中,默认会自动配置 HikariCP 作为数据库连接池。开发者只需在 application.properties 中指定数据库配置参数,Spring Boot 会自动使用连接池,并将其应用到 MyBatis 中:
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.maximum-pool-size=10
总结
数据库连接池用于管理和优化数据库连接,减少连接的创建和销毁开销,提高系统性能。
JDBC使用连接池可以提升数据库访问效率。
MyBatis与连接池结合,可以有效管理数据库连接资源,提高查询和事务处理的性能。
在Spring Boot + MyBatis的组合中,Spring Boot 默认提供了 HikariCP 连接池的自动配置,使数据库连接的管理更加高效。