在Java企业级应用开发领域,ORM框架无疑是构建高性能数据访问层的关键工具之一。MyBatis作为一款轻量级、易于学习且高度可定制化的持久层框架,以其简洁的设计理念、卓越的灵活性和高效的SQL处理能力,赢得了广大开发者的青睐。本文将系统全面地探讨MyBatis的基础架构、核心特性和应用场景,并结合实际开发经验,引导读者深入了解和高效使用MyBatis。本文偏向基础应用讲解,深入可查阅官方文档。
MyBatis是一款基于Java的持久层框架,它通过映射配置文件或注解方式将SQL语句与Java对象关联起来,极大降低了传统JDBC编程的复杂度。MyBatis通过SqlSession API提供CRUD操作,并支持事务管理和结果映射等功能,使得开发者能够集中精力于业务逻辑开发,而非繁琐的数据库交互细节。
Mybatis框架的简单应用架构,如图所示:
1. 映射配置与动态SQL
标签精细化地配置结果集到Java对象的映射规则,支持嵌套结果集、集合、联合查询等多种复杂映射场景。
,
,
,
,
,
等,使得SQL语句可以根据Java变量的值动态生成,极大地增强了SQL表达力和灵活性。XML是一种可扩展性语言,用户可以自己定义标签,用来描述特定类型的数据;
XML的语法严格,每个标签都必须有一个结束标签,标签的嵌套关系也必须合法;
1.MyBatis Framework
2.MySQL Driver
1.在resources目录下创建 mappers目录,用来存放xml配置文件
2.下载映射文件模板
3. application.properties中添加配置:mybatis框架映射配置文件的位置
# 设置MyBatis框架的映射(Mapper)配置文件的位置
mybatis.mapper-locations=classpath:mappers/*.xml
说明
在 Mybatis 的 XML 文件中,SQL 语句都是使用 SQL 标签来定义的。
常用的SQL标签
select
用于查询操作,包括多表查询、条件查询等。可以使用 resultType 来指定返回结果的类型。
insert
用于插入操作,并将其自动注入实体类中。
update
用于更新操作,包括更新一条记录或者批量更新。
delete
用于删除操作,包括删除一条记录或者批量删除。
if、foreach、set
用于条件控制,可以根据不同的条件进行查询、插入、更新和删除操作。if 标签用于指定可以 为空的查询条件,foreach 标签用于循环查询,set 标签用于指定更新操作的字段值。
sql:用于定义可重用的 SQL 片段,通常是一些较为复杂的 SQL 片段。可以在其它 SQL 语句 中使用 include 标签来引用 SQL 片段。
include:用于引入外部的 SQL 片段。可以在 include 标签的 refid 属性中指定外部 SQL 片段 的名字,然后在当前 SQL 中使用它。
这些 SQL 标签可以随意组合,可以使 SQL 语句变得很灵活和强大。通常需要根据实际业务场 景选择合适的标签来实现相应的 SQL 操作。
基于本业务实现MyBatis基本操作,掌握MyBatis中xml配置SQL的应用。
UserMapper.java
@Mapper
public interface UserMapper {
/**在User表中插入一条表记录*/
int insert(User user);
}
UserMapper.xml
INSERT INTO user VALUES (NULL,#{username},#{password},#{nickname},#
{created})
// 自动装配
@Autowired
private UserMapper userMapper;
// 测试插入数据
@Test
void testInsert(){
User user = new User();
user.setUsername("熊三");
user.setPassword("123456");
user.setNickname("只手遮天");
user.setCreated(new Date());
// 调用接口方法
System.out.println(userMapper.insert(user));
}
基于SpringBoot脚手架工程对MyBatis框架的整合,实现对微博内容weibo表进行操作。
WeiboMapper.java
package cn.qiang._04mybatis.mapper;
import cn.qiang._04mybatis.pojo.Weibo;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface WeiboMapper {
/**在微博表中插入数据*/
int insert(Weibo weibo);
/**根据微博id查询数据*/
Weibo selectByWeiboId(int id);
/**查询所有微博信息*/
List selectWeibo();
/**更新微博表数据*/
int updateById(Weibo weibo);
/**删除微博表数据*/
int deleteById(int id);
}
INSERT INTO weibo
VALUES (NULL, #{content}, #{created}, #{userId})
UPDATE weibo
SET content=#{content},
created=#{created},
user_id=#{userId}
WHERE id = #{id}
DELETE
FROM weibo
WHERE id = 2
/**自动装配*/
@Autowired
private WeiboMapper weiboMapper;
/**在微博表中插入数据-测试方法*/
@Test
void InsertWeibo(){
Weibo weibo = new Weibo();
weibo.setContent("今天天气真不错呀");
weibo.setCreated(new Date());
weibo.setUserId(1);
weiboMapper.insert(weibo);
}
/**查询所有微博信息-测试方法*/
@Test
void selectWeiboTest(){
System.out.println(weiboMapper.selectWeibo());
}
/**根据微博id查询数据*/
@Test
void selectByWeiboIdTest(){
System.out.println(weiboMapper.selectByWeiboId(2));
}
/**更新微博表数据-测试*/
@Test
void updateById(){
Weibo weibo = new Weibo();
weibo.setId(2);
weibo.setContent("人生得意须尽欢");
weibo.setCreated(new Date());
weibo.setUserId(2);
System.out.println(weiboMapper.updateById(weibo));
}
/**删除微博表数据-测试*/
@Test
void deleteByIdTest(){
System.out.println(weiboMapper.deleteById(2));
}
CommentMapper
/**1.第一种批量删除: 传递Integer的数组*/
int deleteByIds1(Integer[] ids);
/**2.第二种批量删除:传递集合参数*/
int deleteByIds3(List ids);
DELETE FROM comment WHERE id IN(
#{id}
)
DELETE FROM comment WHERE id IN(
#{id}
)
/**1.第一种批量删除: 传递Integer的数组-测试*/
@Test
void delete1(){
// 测试数组方式删除
Integer[] ids = {2, 8};
commentMapper.deleteByIds1(ids);
}
/**2.第二种批量删除:传递集合参数-测试*/
@Test
void delete3(){
// 测试集合方式删除
ArrayList ids = new ArrayList<>();
ids.add(18);
ids.add(20);
ids.add(22);
commentMapper.deleteByIds2(ids);
}
说明
如果表中字段很多,但是只改部分字段数据,比如只修改部分字段的值,不修改其他字段的值,如 果使用对象作为参数则会将其他字段的值也修改为null,如果使用传参方式解决,参数过多也会很 麻烦,所以可以使用动态修改。
实现
使用xml中的
语法示例:
UPDATE product
title=#{title},
price=#{price},
num=#{num}
WHERE id=#{id};
CommentMapper
/**动态修改数据*/
int dynamicUpdate(Comment comment);
UPDATE comment
content=#{content},
created=#{created},
user_id=#{userId},
weibo_id=#{weiboId}
WHERE id=#{id};
/**动态修改数据-测试*/
@Test
void dynamicUpdateTest(){
Comment comment = new Comment();
comment.setId(27);
comment.setContent("莫使金樽空对月");
comment.setUserId(666);
commentMapper.dynamicUpdate(comment);
}
SQL语句重用是指在数据库应用程序中,多次执行相同或类似的SQL语句时,通过重用这些语句来提高 性能,减少系统消耗的资源。
使用
在三种动态删除的SQL语句中,都有重复的SQL语句: DELETE FROM comment WHERE id IN ,可以将 重复的语句抽取出来,来简化SQL。
1. mappers.CommentMapper.xml 将删除语句重复的SQL抽取出来
DELETE FROM comment WHERE id in
(
#{id}
)
(
#{id}
)
2. 执行对应的测试用例测试
用户昵称: 微博内容
花千骨说:今天天气不错挺风和日丽的
微博id、微博内容、用户昵
1. mapper.WeiboMapper
// 首页微博列表数据
List selectIndex();
2. mappers.WeiboMapper.xml
3. pojo.vo.WeiboIndexVO
public class WeiboIndexVO {
// 显示微博的id content , 再显示一个nickname
private Integer id;
private String content;
private String nickname;
}
4. 测试方法
@Test
void weiboIndexTest(){
System.out.println(weiboMapper.selectIndex());
}
MyBatis支持两种事务管理模式:自动提交和手动控制。在开启手动控制的情况下,开发者可通过SqlSession的commit()
和rollback()
方法管理事务边界。
通过引入相关依赖和配置,将MyBatis无缝整合到Spring Boot项目中,利用Spring的依赖注入和事务管理能力,简化配置和增强整体架构的协调性。
MyBatis-Spring模块提供了SqlSessionTemplate和MapperFactoryBean等组件,使得MyBatis可以更好地配合Spring容器进行事务管理和Mapper接口注入。
虽然Spring Data JPA提供了更为便捷的repository接口,但对于复杂查询和个性化需求,MyBatis的灵活性和可控性优势显著。
遵循单一职责原则,避免在一个Mapper接口中堆积过多SQL操作,保证映射文件结构清晰,提高代码可读性和可维护性。
结合业务特点,对SQL语句进行优化,合理利用MyBatis的一级缓存和二级缓存,降低数据库压力,提升系统性能。
配置合适的日志级别和日志框架(如Log4j、SLF4J),有助于在开发阶段快速定位问题,监控SQL执行情况和性能瓶颈。
MyBatis作为一款优秀的Java持久层框架,它的广泛应用得益于其简单直观的API设计、丰富的SQL定制能力以及与主流Java生态的深度融合。通过深入理解和掌握MyBatis的各项特性,我们可以在实际开发过程中更加游刃有余地应对各种复杂的数据库操作需求,构建出高效稳定的持久层解决方案。