Mybatis是一个优秀的持久层框架,支持自定义SQL查询、存储过程以及高级映射。本文将详细介绍Mybatis持久层框架入门的相关内容,包括环境搭建、核心概念解析和基本操作实现。从配置文件到基本CRUD操作,本文将提供详细的步骤和示例代码,帮助读者更好地理解和应用Mybatis。
Mybatis简介Mybatis 是一个优秀的持久层框架,它支持自定义 SQL 查询,存储过程以及高级映射。Mybatis 的前身是 iBatis,由 Apache 软件基金会孵化出来。Mybatis 通过简单的配置和 Java 类型映射,实现了使用标准 SQL 语句进行数据持久化操作。它提供了一个非常灵活的框架,可以方便地与各类数据库进行交互。
Mybatis的主要特点- 灵活的配置和映射:Mybatis 的配置文件非常简单,基本遵循 XML 规范。配置文件中的配置大多可以进行动态替换,可以通过
<property>
标签动态更新属性值,从而实现灵活配置。例如,数据库驱动和连接信息可以根据不同的环境进行替换。 - 支持自定义 SQL 查询:Mybatis 支持编写自定义 SQL 查询,可以充分利用数据库的特性来执行复杂的业务逻辑。开发者可以自定义 SQL 语句,然后将结果映射到 Java 对象。
- 支持存储过程:Mybatis 支持调用存储过程,可以将复杂的业务逻辑封装在数据库存储过程中。例如,可以通过
<select>
标签的resultMap
属性指定结果集的映射。 - 强大的结果映射:Mybatis 通过 ResultMap 的支持,可以实现对复杂查询结果的映射,支持嵌套结果映射。例如,可以使用
<resultMap>
标签定义多表关联的映射规则。 - 支持动态 SQL:Mybatis 提供了动态 SQL 的功能,可以避免硬编码的 SQL 语句,提高代码的可维护性和可读性。例如,可以使用
<if>
、<choose>
、<when>
和<otherwise>
标签来实现条件判断和分支逻辑。 - 插件扩展:Mybatis 提供了插件接口,可以根据需要自定义扩展功能。例如,可以编写插件来拦截和修改 SQL 语句的执行。
- 丰富的 API:Mybatis 提供了丰富的 API,可以方便地进行数据库操作。例如,可以通过
SqlSession
对象执行 CRUD 操作,也可以通过 Mapper 接口和 XML 映射文件定义 SQL 语句。
Mybatis 和 Hibernate 都是持久层框架,但它们的设计思想和使用方式有所不同。
- ORM(对象关系映射):Hibernate 是一个 ORM 框架,它将 Java 对象映射到数据库表中,通过简单的配置和注解即可完成对象和数据库表的映射。Mybatis 则是一个半自动化的框架,需要手动编写 SQL 语句,然后将结果映射到 Java 对象。
- SQL 查询:Hibernate 自动生成 SQL 语句,减少了开发者编写 SQL 语句的工作量。而 Mybatis 则需要开发者手动编写 SQL 语句。
- 性能:由于 Hibernate 自动生成 SQL 语句,因此在某些情况下性能可能不如 Mybatis。而 Mybatis 因为使用手动编写的 SQL 语句,可以进行优化,因此在性能上可能有更好的表现。
- 灵活性:Hibernate 的灵活性较低,它会自动管理对象的生命周期,而 Mybatis 提供了更多的控制权,可以更好地控制 SQL 语句和结果映射,灵活性更高。
- 学习曲线:Hibernate 的学习曲线较陡峭,因为它需要理解和掌握 ORM 的概念,而 Mybatis 的学习曲线相对平缓,因为它只需编写 SQL 语句和结果映射。
要使用 Mybatis,首先需要搭建一个基本的开发环境。
准备工作- 安装 JDK:确保 JDK 已经安装并配置好了环境变量。
- 安装 IDE:建议使用 IntelliJ IDEA 或 Eclipse,这些 IDE 提供了 Mybatis 的代码生成和调试支持。
- 安装数据库:Mybatis 支持多种数据库,可以选择 MySQL、Oracle、SQL Server 等。
- 创建 Maven 项目:使用 Maven 管理项目依赖,可以更加方便地管理和维护项目。
在 Maven 项目中添加 Mybatis 的依赖。在 pom.xml
文件中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
不同的 Mybatis 版本可能需要不同的依赖版本,请根据实际情况调整 version
属性。
假设要创建一个 user
表,可以在数据库中执行以下 SQL 语句:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
插入一些数据:
INSERT INTO `user` (`name`, `age`) VALUES ('John', 25);
INSERT INTO `user` (`name`, `age`) VALUES ('Jane', 22);
执行上述 SQL 语句后,user
表将创建成功,并插入两条记录。
在项目中创建一个配置文件 mybatis-config.xml
,并配置数据库连接信息:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
</configuration>
Mybatis核心概念解析
Mybatis 通过几个核心概念来实现数据的持久化操作:SqlSessionFactory
、SqlSession
、Mapper 接口
和 Mapper XML 文件
。
SqlSessionFactory
是 Mybatis 的核心对象,它是线程不安全的,因此通常会将其作为单例进行管理。通过 SqlSessionFactory
可以创建 SqlSession
,SqlSession
是 Mybatis 的会话对象,其中包含了执行 SQL 语句所需的方法。
创建 SqlSessionFactory
的代码示例如下:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
使用 SqlSession
执行 SQL 语句的示例如下:
SqlSession session = sqlSessionFactory.openSession();
User user = session.selectOne("com.example.mapper.UserMapper.selectUser", 1);
session.close();
Mapper接口与Mapper XML文件
Mapper 接口
是 Mybatis 提供的一种声明式编程方式。通过声明接口方法和对应的 SQL 语句,可以简化代码的编写。Mapper XML 文件
是用来配置 SQL 语句和结果映射的文件。
定义一个 UserMapper
接口:
public interface UserMapper {
User selectUser(int id);
}
对应的 UserMapper.xml
文件:
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUser" resultType="com.example.entity.User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
namespace
标签用于指定接口的全限定名,id
标签用于指定接口方法的名称,resultType
标签用于指定返回值类型。
通过 SqlSession
获取 UserMapper
实例并执行 SQL 语句:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.close();
{}和${}的区别与使用场景
在 SQL 语句中,#{}
和 ${}
用于占位符,但它们的工作方式有所不同。
#{}
:用于预编译参数,会将实际值作为参数传递给 SQL 语句,可以避免 SQL 注入攻击。例如:
<select id="selectUser" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
${}
:用于直接替换变量值,不进行预编译,可能引发 SQL 注入风险。例如:
<select id="selectUser" resultType="User">
SELECT * FROM user WHERE id = ${id}
</select>
建议使用 #{}
,除非有特殊需求。
ResultMap
是 Mybatis 中用于描述结果集映射的对象。它可以定义结果集中的列与 Java 对象属性之间的映射关系,支持嵌套结果映射,可以映射复杂的结果集。
定义一个 ResultMap
:
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>
id
标签用于映射主键列,result
标签用于映射普通列。
嵌套结果映射:
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<collection property="orders" column="id" ofType="Order" select="selectOrdersByUserId"/>
</resultMap>
collection
标签用于映射嵌套结果集,property
属性用于指定 Java 对象的属性名,column
属性用于指定 SQL 语句中的列名,ofType
属性用于指定嵌套对象的类型,select
属性用于指定用于查询嵌套结果集的 SQL 语句。
通过 SqlSession
获取 UserMapper
实例并执行 SQL 语句:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUsers();
session.close();
基本操作实现
Mybatis 提供了 CRUD 操作的支持,可以方便地实现增删改查功能。
CRUD操作(增删改查)插入操作
插入操作可以通过 Mapper 接口
或 SqlSession
实现。
定义一个 UserMapper
接口:
public interface UserMapper {
int insertUser(User user);
}
对应的 UserMapper.xml
文件:
<insert id="insertUser" parameterType="User">
INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
通过 SqlSession
执行插入操作:
SqlSession session = sqlSessionFactory.openSession();
User user = new User();
user.setName("Tom");
user.setAge(28);
int result = session.insert("com.example.mapper.UserMapper.insertUser", user);
session.commit();
session.close();
查询操作
查询操作可以通过 Mapper 接口
或 SqlSession
实现。
定义一个 UserMapper
接口:
public interface UserMapper {
List<User> selectUsers();
}
对应的 UserMapper.xml
文件:
<select id="selectUsers" resultType="User">
SELECT * FROM user
</select>
通过 SqlSession
执行查询操作:
SqlSession session = sqlSessionFactory.openSession();
List<User> users = session.selectList("com.example.mapper.UserMapper.selectUsers");
session.close();
更新操作
更新操作可以通过 Mapper 接口
或 SqlSession
实现。
定义一个 UserMapper
接口:
public interface UserMapper {
int updateUser(User user);
}
对应的 UserMapper.xml
文件:
<update id="updateUser" parameterType="User">
UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
通过 SqlSession
执行更新操作:
SqlSession session = sqlSessionFactory.openSession();
User user = new User();
user.setId(1);
user.setName("Jack");
user.setAge(29);
int result = session.update("com.example.mapper.UserMapper.updateUser", user);
session.commit();
session.close();
删除操作
删除操作可以通过 Mapper 接口
或 SqlSession
实现。
定义一个 UserMapper
接口:
public interface UserMapper {
int deleteUser(int id);
}
对应的 UserMapper.xml
文件:
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
通过 SqlSession
执行删除操作:
SqlSession session = sqlSessionFactory.openSession();
int result = session.delete("com.example.mapper.UserMapper.deleteUser", 1);
session.commit();
session.close();
使用Mapper接口实现CRUD
定义一个 UserMapper
接口:
public interface UserMapper {
int insertUser(User user);
List<User> selectUsers();
int updateUser(User user);
int deleteUser(int id);
}
对应的 UserMapper.xml
文件:
<insert id="insertUser" parameterType="User">
INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
<select id="selectUsers" resultType="User">
SELECT * FROM user
</select>
<update id="updateUser" parameterType="User">
UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
通过 SqlSession
获取 UserMapper
实例并执行 CRUD 操作:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("Tom");
user.setAge(28);
int result = mapper.insertUser(user);
session.commit();
List<User> users = mapper.selectUsers();
user.setId(1);
user.setName("Jack");
user.setAge(29);
result = mapper.updateUser(user);
session.commit();
int deleteUserResult = mapper.deleteUser(1);
session.commit();
session.close();
使用SqlSession实现CRUD
直接通过 SqlSession
执行 CRUD 操作:
SqlSession session = sqlSessionFactory.openSession();
// 插入操作
User user = new User();
user.setName("Tom");
user.setAge(28);
int result = session.insert("com.example.mapper.UserMapper.insertUser", user);
session.commit();
// 查询操作
List<User> users = session.selectList("com.example.mapper.UserMapper.selectUsers");
// 更新操作
user.setId(1);
user.setName("Jack");
user.setAge(29);
result = session.update("com.example.mapper.UserMapper.updateUser", user);
session.commit();
// 删除操作
result = session.delete("com.example.mapper.UserMapper.deleteUser", 1);
session.commit();
session.close();
动态SQL的使用
Mybatis 提供了动态 SQL 的功能,可以通过标签来实现复杂的查询逻辑。
if、choose、when、otherwise标签if
标签用于条件判断,choose
、when
和 otherwise
标签用于选择分支。
假设有一个查询用户信息的 SQL 语句,用户可以提供 name
和 age
参数,但这两个参数是可选的:
<select id="selectUser" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
where
标签用于生成 SQL 语句中的 WHERE
子句,if
标签用于条件判断。
choose
、when
和 otherwise
标签示例:
<select id="selectUser" resultType="User">
SELECT * FROM user
<where>
<choose>
<when test="name != null">
AND name = #{name}
</when>
<when test="age != null">
AND age = #{age}
</when>
<otherwise>
AND id = 1
</otherwise>
</choose>
</where>
</select>
choose
标签用于选择分支,when
标签用于条件判断,otherwise
标签用于默认分支。
set
标签用于生成 SQL 语句中的 SET
子句,foreach
标签用于遍历集合。
假设有一个更新用户信息的 SQL 语句,可以更新多个字段:
<update id="updateUser" parameterType="User">
UPDATE user
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age},
</if>
</set>
WHERE id = #{id}
</update>
foreach
标签用于遍历集合:
<select id="selectUsersByIds" resultType="User">
SELECT * FROM user
WHERE id IN
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach
标签用于遍历集合中的元素,item
属性用于指定当前元素的变量名,index
属性用于指定当前元素的索引,collection
属性用于指定集合的变量名,open
、separator
和 close
属性用于生成括号和分隔符。
假设有一个查询用户信息的 SQL 语句,可以根据不同的条件进行查询:
<select id="selectUser" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
<if test="ids != null and ids.length > 0">
AND id IN
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</where>
</select>
通过 if
、choose
、when
、otherwise
和 foreach
标签,可以灵活地实现复杂的查询逻辑。
Spring 是一个流行的 Java 框架,它提供了许多企业级功能,如依赖注入、事务管理等。将 Mybatis 与 Spring 集成可以充分利用 Spring 的这些功能。
Spring整合Mybatis的优势- 依赖注入:Spring 可以自动管理 Mybatis 的依赖,如
SqlSessionFactory
,并通过依赖注入的方式将其注入到需要使用的类中。 - 事务管理:Spring 提供了强大的事务管理功能,可以方便地管理数据库事务。
- AOP 支持:Spring 的 AOP 功能可以用于实现数据库操作的拦截和增强,如日志记录、权限控制等。
- 自动配置:Spring 可以自动配置 Mybatis 的配置文件,减少手动配置的工作量。
在 Spring 中配置 SqlSessionFactory
:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
定义一个 DataSource
配置:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
通过 @Autowired
注解注入 SqlSessionFactory
:
@Service
public class UserService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public List<User> getUsers() {
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUsers();
session.close();
return users;
}
}
实现基于注解的Mapper接口
通过 Spring 的 MapperScannerConfigurer
配置扫描类路径下的 Mapper 接口:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper"/>
</bean>
通过 Spring 的 @Autowired
注解自动注入 Mapper 接口:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> getUsers() {
List<User> users = userMapper.selectUsers();
return users;
}
}
通过上述配置,可以方便地将 Mybatis 与 Spring 集成,实现依赖注入和事务管理等功能。
共同学习,写下你的评论
评论加载中...
作者其他优质文章