文章目录
- MyBatis介绍
- JDBC缺点
- MyBatis简化
- MyBatis快速入门之查询user表中的所有数据
- 1、创建user表,添加数据
- 2、创建模块,导入坐标
- 3、编写MyBatis核心配置文件 --> 替换连接信息,解决硬编码问题
- 4、编写SQL映射文件 --> 同一管理sql语句,解决硬编码问题
- 5、编码
- 使用Mapper代理方式完成
- MyBatis核心配置文件概述
- environments标签
- mapper标签
- Properties标签
- typeAliases标签
- MyBatis相应API
- SqlSession工厂构建器SqlSessionFactoryBuilder
- SqlSession工厂对象SqlSessionFactory
- SqlSession会话对象
- MyBatisX 插件
- 实践案例-查询所有数据
- 实体类属性名 和 数据库表列名 不一致,不能自动封装数据
- 实践案例-查看详情
- 实践案例-多条件查询
- SQL语句设置多个参数有几种方式?
- 实践案例:多条件查询(动态条件)
我亦无他,唯手熟尔。
时间:2023年5月2日12:41:27
MyBatis介绍
- MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发
- MyBatis 本是 Apache 的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,2013年11月迁移到Github
官网:https://mybatis.org/mybatis-3/zh/index.html
持久层
- 负责将数据到保存到数据库的那一层代码
- JavaEE三层架构:表现层、业务层、持久层
框架
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
JDBC缺点
MyBatis简化
MyBatis快速入门之查询user表中的所有数据
1、创建user表,添加数据
create database mybatis;
use mybatis;
drop table if exists tb_user;
create table tb_user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
gender char(1),
addr varchar(30)
);
INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
2、创建模块,导入坐标
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--junit 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- 添加slf4j日志api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- 添加logback-classic依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 添加logback-core依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
3、编写MyBatis核心配置文件 --> 替换连接信息,解决硬编码问题
<?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>
<typeAliases>
<package name="com.wly.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息,可以配置多个environment,
通过default属性切换不同的environment
-->
<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/mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<!--<mapper resource="com/wly/mapper/userMapper.xml"/>-->
<!--Mapper代理方式-->
<package name="com.wly.mapper"/>
</mappers>
</configuration>
4、编写SQL映射文件 --> 同一管理sql语句,解决硬编码问题
public interface UserMapper {
List<User> selectAll();
User selectById(int id);
}
5、编码
- 定义POJO类
- 加载核心配置文件,获取AqlSessionFactory对象
- 获取SqlSession对象,执行SQL
- 释放资源
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.执行sql
List<User> users = sqlSession.selectList("test.selectAll");
System.out.println(users);
//4. 释放资源
sqlSession.close();
}
}
使用Mapper代理方式完成
1、定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放在同一目录下
2、设置SQL映射文件的namespace属性为Mapper接口全限定名
3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一直
4、编码
1、通过SqlSession的getMapper方法获取Mapper接口的代理对象
2、通过调用方法完成sql的执行
细节: 如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
// 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
MyBatis核心配置文件概述
environments标签
数据库环境的配置,支持多环境配置
其中,事务管理器(transactionManager)类型有两种:
- JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
- MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false来阻止它默认的关闭行为。
其中,数据源(dataSource)类型有三种:
- UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
- POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
- JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI上下文的引用。
mapper标签
该标签的作用是加载映射的,加载方式有如下几种:
使用相对于类路径的资源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>
Properties标签
实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件
typeAliases标签
mybatis框架已经为我们设置好的一些常用的类型的别名
MyBatis相应API
SqlSession工厂构建器SqlSessionFactoryBuilder
常用API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象
// 获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
其中, Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。
SqlSession工厂对象SqlSessionFactory
SqlSessionFactory 有多个个方法创建 SqlSession 实例。常用的有如下两个:
SqlSession会话对象
SqlSession 实例在 MyBatis 中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。
执行语句的方法主要有:
<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)
操作事务的方法主要有:
void commit()
void rollback()
MyBatisX 插件
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
主要功能:
- XML 和 接口方法 相互跳转
- 根据接口方法生成
statement
安装:
实践案例-查询所有数据
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
-- id 主键
id int primary key auto_increment,
-- 品牌名称
brand_name varchar(20),
-- 企业名称
company_name varchar(20),
-- 排序字段
ordered int,
-- 描述信息
description varchar(100),
-- 状态:0:禁用 1:启用
status int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
('小米', '小米科技有限公司', 50, 'are you ok', 1);
SELECT * FROM tb_brand;
1、编写接口方法
- 参数:无
- 结果:List
/**
* 查询所有
*/
List<Brand> selectAll();
2、编写SQL语句:SQL映射文件
<select id="selectAll" resultType="Brand">
select *
from tb_brand;
</select>
3、执行方法,测试
实体类属性名 和 数据库表列名 不一致,不能自动封装数据
- 起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样可以定义 片段,提升复用性
resultMap
:定义<resultMap>
完成不一致的属性名和列名的映射
<select id="selectAll" resultType="Brand">
select id, brand_name as brandName, company_name as companyName, ordered, description, status
from tb_brand;
</select>
<!--
数据库表的字段名称和实体类的属性名称不一样
则不能自动封装数据。
方式1:起别名,对不一样的列名起别名,让别名和实体类的属性名一样.缺点:每次查询都要定义一次别名
方式2:resultMap
1、定义<resultMap>标签
2、在<select>标签中,使用resultMap属性替换resultType属性
-->
<!--
id:唯一标识
type:映射的类型,支持别名
-->
<resultMap id="brandResultMap" type="brand">
<!--
id:完成主键字段的映射
result:完成一般字段的映射
-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select *
from tb_brand;
</select>
实践案例-查看详情
1、编写接口方法:Mapper接口
- 参数:id
- 结果:Brand
/**
* 查看详情:根据Id查询
*/
Brand selectById(int id);
2、编写SQL语句:SQL映射文件
<select id="selectById" resultMap="brandResultMap">
select *
from tb_brand where id = #{id}
</select>
3、执行方法,测试
@Test
public void testSelectById() throws IOException {
//接收参数
int id = 2;
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
Brand brand = brandMapper.selectById(id);
System.out.println(brand);
sqlSession.close();
}
总结:
- 参数占位符:
1)#{}
:执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
2)${}
:拼SQL。会存在SQL注入问题
3)使用时机:
参数传递,都使用#{}
如果要对表名、列名进行动态设置,只能使用${}
进行sql拼接。 parameterType
:- 用于设置参数类型,该参数可以省略
- SQL 语句中特殊字符处理:
- 转义字符
<![CDATA[ 内容 ]]>
:CD提示
实践案例-多条件查询
1、编写接口方法:Mapper接口
- 参数:所有查询条件
- 结果:List
List<Brand> selectByCondition(@Param("status")int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);
2、编写SQL语句:SQL映射文件
<!--
条件查询
-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where
status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
3、执行方法,测试
SQL语句设置多个参数有几种方式?
- 散装参数:如果方法中有多个参数,需要使用
@Param("SQL中的参数名称")
使用麻烦 - 实体类封装参数
只需要保证SQL中的参数名 和 实体类属性名对应上,即可设置成功 - map集合
只需要保证SQL中的参数名 和 map集合的键的名称对应上,即可设置成功