Mybatis的基本使用
Mybatis的基本使用,包括园原生方式、代理开发以及注解开发
目录
一、Mybatis简介
- Mybatis是一款优秀的持久层框架,用于简化JSBC开发
- Mybatis官网:Mybatis官网
什么是持久层?
- 负责将数据保存到数据库的那一层代码
- JavaEE三层架构:表现层、业务层、持久层
JDBC缺点(关于JDBC,可见我上一篇文章JDBC编程详解以及Druid的使用)
- 硬编码
- 注册驱动,获取连接
- sql语句
- 操作繁琐
- 手动设置参数
- 手动封装数据集
二、Mybatis操作步骤
Mybati使用步骤总结
- 配置Mybtis核心配置文件(一般将其命名为 mybatis-config.xml)
- 根据核心配置文件创建 SqlSessionFactory 对象
- 通过 SqlSessionFactory 对象创建 SqlSession 对象
- 通过 SqlSession 对象操作数据库 CRUD
- 提交事务
- 释放资源
// 加载 mybatis核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取SqlSession 对象, 执行 sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行 sql
// "名称空间.id" 是sql映射文件中sql语句的唯一标识
List<User> users = sqlSession.selectList("名称空间.id");
// 释放资源
sqlSession.close();
①核心配置文件
从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。XML 配置文件中包含了对 MyBatis系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。通过核心配置文件,我们可以替换连接信息,解决硬编码问题。这里先给出一个简单的示例:
<?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>
<!--
加载配置文件信息,主要是数据源的连接信息
-->
<properties resource="db.properties"/>
<!--
类型别名,可简写 resultType,省略包名
-->
<typeAliases>
<package name="com.tyt.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息。可以配置多个environment,通过default切换不同的environment
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--连接信息-->
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="com/tyt/mapper/UserMapper.xml"/>
</mappers>
</configuration>
其中数据源的连接信息将其写在db.properties中,详情如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useSSL=false
username=root
password=****
②SQL映射文件
SQL映射文件可统一管理SQL语句,解决硬编码问题。这里给出一个示例(四个基础的增删改查):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:名称空间
-->
<mapper namespace="test">
<insert id="add" useGeneratedKeys="true" keyColumn="id">
insert into tb_brand (companyName, brandName, ordered, description, status)
values (#{companyName}, #{brandName}, #{ordered}, #{description}, #{status});
</insert>
<delete id="deleteById">
delete from tb_brand where id = #{id};
</delete>
<update id="update">
update tb_brand
set
brandName = #{brandName},
companyName = #{companyName},
ordered = #{ordered},
description = #{description},
status = #{status}
where id = #{id};
</update>
<select id="selectAll" resultType="Brand">
select * from tb_brand;
</select>
</mapper>
③参数符号
SQL映射文件中的sql语句有两个占位符,分别是:#{}
与${}
。
我们一般采用#{}
,#{}
在Mybatis会被解析为?
,就是JDBC中的PreparedStatement中的?
占位符,说明它也有预编译的功能。
* 参数占位符:
1: #{}: 将其替换为'?' , 防止 sql 注入
2: ${}: 拼 sql, 存在 sql 注入
3. 使用时机:
* 参数传递时: #{}
* 表名或列名不固定时: ${}
* 参数类型: parameterType 可省略
* 特殊字符处理
1、转义字符:
2. CDATA: <1[CDATA[ 符号 ]]>
④映射失败的解决方案
当数据库表列名与实体类属性名不一致时,不能自动封装数据。例如,在数据库中,使用下划线命名方式;在实体类中,使用驼峰命名。在此,提供了三种解决方案,其中第三个使用reultMap最为广泛使用。
我这里有一个表tb_brand并定义了实体类Brand,可以发现,在数据库中使用的下划线命名,在实体类中使用的驼峰命名。
- 方法一:起别名(在sql语句中,对不一样的列名起别名,别名与属性名一致)
缺点:繁琐,每次查询都要起别名- 方法二:定义sql片段
缺点:一个sql片段仅针对一种情况,不够灵活- 方法三:resultMap
三、Mapper代理开发
目的
- 解决原生方式(即二、Mybatis操作步骤)的硬编码
- 简化后期执行sql
- 定义与SQL映射文件同名的Mapper接口,并将其Mapper接口和SQL映射文件放置在同一目录
- 设置SQL映射文件的namespace属性为Mapper接口限定全名
- 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
- 编码
① 通过SqlSession的getMapper方法获取Mapper接口的代理对象
② 调用对应方法完成sql的执行
注:如果Mapper接口名称与SQL映射文件名称相同,并在同一目录,则可使用包扫描的方式简化SQL映射文件的加载
①SQL映射文件与SQL映射文件同名的Mapper接口
② 设置SQL映射文件的namespace属性为Mapper接口限定全名
四、注解开发
如果不习惯用xml配置文件,则可以考虑使用注解的开发方式。注解的开发方式,会将sql语句写入代码,缺点是后续可维护性与拓展性不强(若想修改sql语句,需要更改代码,重新打包部署,但使用xml方式,只需修改xml文件,并用新的文件替代原xml文件即可)
- 查询:@Select
- 添加:@Insert
- 修改:@Update
- 删除:@Delete
提示:
- 注解完成简单功能
- 配置文件完成复杂功能
五、SQL映射文件中sql语句高级
1、参数传递
Mybatis中SQL语句有3种方式可以设置参数:
①散装参数:需要使用@Param(“SQL中的参数占位符名称”)
②实体类封装参数:需要保证SQL中的参数名与实体类的属性名对应上
③Map集合需要保证SQL中的参数名与Map集合中的键的名称对应上
2、动态SQL
SQL语句随着用户输入或外部条件的变化而变化,我们称为动态SQL。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
① if
if 标签通常用于 WHERE 语句、UPDATE语句、INSERT语句,通过判断参数值来决定是否使用某个查询条件、判断是否更新或插入某一字段的值。
② choose
有时候需求并不需要应用所有条件,而只是想从多选型中选择一个。Mybatis提供了<choose>
标签(类似Java的switch),按顺序判断<when>
标签(类似Java的case)中条件,若条件都不满足,执行<otherwise>
标签(类似Java的default)的语句。
③trim
- where
当 if 标签过多,以下组合可能会报错。
这是因为当status
为null时,查询语句会出现...where and ...
的情况。
解决方法可将where
更改为where 1 = 1
,也可以利用<where>
标签。
- set
下面的组合中,当brandName为空时,也会报错。
这是因为当brandName
为null时,查询语句会出现..., where ...
的情况。
解决方法可以利用<set>
标签。
④foreach标签
<foreach>
标签主要用于构建in
条件,可在sql语句中对集合进行迭代。也可用于批量删除、添加等操作中。
属性介绍
- collection:collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合。
- item :表示在迭代过程中每一个元素的别名
- separator :分隔符,表示迭代时每个元素之间以什么分隔
- open :前缀
- close :后缀
- index :表示在迭代过程中每次迭代到的位置(下标)
3、添加数据主键返回
在某些需求中,需要在数据添加成功后,获取插入数据库数据的主键的值。
只需要在<insert>
标签中添加两个数据即可。useGeneratedKeys="true" keyProperty="主键列名"
六、其他
1、SqlSessionFactory工具类抽取
- 创建
SqlSessionFactory
代码优化
// 加载 mybatis核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- 缺点及解决:
- 代码重复:
使用工具类
- SqlSessionFactory工厂只创建一次,不能重复创建:
使用静态代码块
使用方法:
①定义获取SqlSessionFactory工具类
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
// 静态代码块会随类的加载而自动执行,且只执行一次
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
②获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
2、分页插件
①引入maven依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
②加入plugin配置
在mybatis核心配置文件中(mybatis-config.xml)配置PageHelper插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
③代码
- sql语句
<select id="selectByPage" resultType="Brand" >
select * from tb_brand
</select>
- java测试用例
// 加载 mybatis核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取SqlSession 对象, 执行 sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 设置分页相关参数 当前页 + 每页显示的条数
PageHelper.startPage(1, 2);
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = brandMapper.selectByPage();
System.out.println(brands);
sqlSession.close();
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)