Day01.mybatis框架
文章目录
课程计划:
- MyBatis快速<mark>入门</mark>
- MyBatis对数据库中数据的<mark>增删改查</mark>操作
#{}
<mark>占位符的应用</mark>- <mark>动态SQL</mark>的应用
- <mark>MyBatis的Mapper接口开发</mark>
1.1 什么是 MyBatis
MyBatis 本是<mark>apache</mark>的一个开源项目iBatis,
2010年这个项目由apache software foundation 迁移到了google code,
并且改名为MyBatis 。
<mark>2013年11月迁移到Github</mark>。
MyBatis是一个优秀的<mark>持久层框架</mark>,
它<mark>对jdbc</mark>的操作数据库的过程进行<mark>封装</mark>,
使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
-
Mybatis<mark>通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置</mark>起来,
-
并<mark>通过java对象和statement中的sql进行映射生成最终执行的sql语句</mark>,
-
最后由mybatis框架执行sql并将结果映射成java对象并返回。
总之,Mybatis对JDBC访问数据库的过程进行了封***r> 简化了JDBC代码,
解决JDBC将结果集封装为Java对象的麻烦。
下图是MyBatis架构图:
∗∗重要∗∗
mybatis-config.xml
是Mybatis的核心配置文件,
<mark>通过其中的配置可以生成SqlSessionFactory
,也就是SqlSession
工厂</mark>- 基于
SqlSessionFactory
可以生成SqlSession
对象 SqlSession
是一个可以发送SQL去执行,并返回结果的对象,
类似于JDBC中的Connection
对象,
也是Mybatis中至关重要的一个对象。- <mark>
Executor
是SqlSession底层的对象,用于执行SQL语句</mark> MapperStatement
对象也是SqlSession
底层的对象,- 用于接收输入映射
(SQL语句中的参数), - 以及做输出映射
(即将SQL查询的结果映射成相应的结果)
- 用于接收输入映射
文章目录
1.2 为什么要使用 MyBatis
思考:
在开始之前,思考下如何通过JDBC查询Emp表中的所有记录,
并封装到一个List集合中返回。
(演示:准备数据、导包、导入JDBC程序)
- 《Java培优班 - 第三十三天 - Jdbc回顾》 - https://blog.csdn.net/LawssssCat/article/details/103598260
1、使用传统方式JDBC访问数据库:
(1)使用JDBC访问数据库有大量重复代码(比如注册驱动、获取连接、获取传输器、释放资源等);
(2)JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低;
(3)SQL是写死在程序中,一旦修改SQL,需要对类重新编译;
(4)对查询SQL执行后返回的ResultSet对象,需要手动处理,有时会特别麻烦;
…
2、使用mybatis框架访问数据库:
- Mybatis对JDBC对了<mark>封装</mark>,可以<mark>简化JDBC代码</mark>;
- Mybatis<mark>自身支持连接池</mark>(也可以配置其他的连接池),因此可以提高程序的效率;
- Mybatis是将<mark>SQL配置在mapper文件</mark>中,修改SQL只是修改配置文件,<mark>类不需要重新编译</mark>。
- <mark>对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象</mark>。
- …
总之,JDBC中所有的问题(代码繁琐、有太多重复代码、需要操作太多对象、释放资源、对结果的处理太麻烦等),在Mybatis框架中几乎都得到了解决!!
文章目录
2 MyBatis快速入门
2.1 准备数据,创建库和表
1、创建yonghedb库、emp表,并插入若干条记录
-- 1、创建数据库 yonghedb 数据库
create database if not exists yonghedb charset utf8;
use yonghedb; -- 选择yonghedb数据库
-- 2、删除emp表(如果存在)
drop table if exists emp;
-- 3、在 yonghedb 库中创建 emp 表
create table emp(
id int primary key auto_increment,
name varchar(50),
job varchar(50),
salary double
);
-- 4、往 emp 表中, 插入若干条记录
insert into emp values(null, '王海涛', '程序员', 3300);
insert into emp values(null, '齐雷', '程序员', 2800);
insert into emp values(null, '刘沛霞', '程序员鼓励师', 2700);
insert into emp values(null, '陈子枢', '部门总监', 4200);
insert into emp values(null, '刘昱江', '程序员', 3000);
insert into emp values(null, '董长春', '程序员', 3500);
insert into emp values(null, '苍老师', '程序员', 3700);
insert into emp values(null, '韩少云', 'CEO', 5000);
2.2 创建工程,导入所需jar包、创建测试类
1、创建Maven的java工程
2、导入junit、mysql、mybaits等开发包
在pom.xml文件中引入相关依赖包即可
<dependencies>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 整合log4j -->
<!-- 通过使用Log4j,我们可以控制日志信息输送的目的地 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
3、创建com.tedu.mybatis.TestMybatis测试类,并提供findAll方法(查询emp表中所有的员工信息),开发步骤如下:
2、mybatis-config.xml文件配置如下:
mybatis-config文件头信息如下:
<?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">
<!-- MyBatis的全局配置文件 -->
<configuration >
</configuration>
详细配置如下:
在这里插入代码片
2.4 添加并编写Emp实体类
注意:
<mark>在当前实例中,Emp类中的属性和数据库表的字段名称必须一致,
否则将会无法将结果集封装到Java对象中。</mark>
在src/main/java目录下创建com.tedu.pojo.Emp类并实现Emp类:
提供私有属性以及对应的getter方法、setter方法,并重写toString方法
在这里插入代码片
2.5 添加EmpMapper.xml文件
1、在src/main/resources目录下,创建EmpMapper.xml文件 (实体类的映射文件)
2、EmpMapper.xml文件配置如下:
EmpMapper文件头信息如下:
<?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一般指定为当前文件的所在包路径+文件名(将来是接口名) 在程序中通过[ namespace + id ]定位到执行哪一条SQL语句 -->
<mapper namespace="">
</mapper>
详细配置如下:
在这里插入代码片
2.6 实现测试类,并测试
1、实现findAll方法,代码如下:
mybatis-configure.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">
<!-- MyBatis的全局配置文件 -->
<!-- 程序中读取的是这个文件, XxxMapper,xml文件在第二步中读取 即,XxxMapper.xml是通过这个文件来间接读取的! -->
<configuration >
<!-- 提示来源: "http://mybatis.org/dtd/mybatis-3-config.dtd" 中文件提供 -->
<!-- 0. 加载常量配置信息 -->
<properties resource="c3p0.properties"/>
<!-- 1. 配置开发环境 -->
<!-- 定义数据库信息,默认使用 develop 数据库构建环境 -->
<environments default="develop">
<environment id="develop">
<!-- 配置事务管理器(JDBC / MANAGED) type: JDBC: jdbc进行事务管理(√) MANAGED: 自己管理 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源(连接池) DataSource type: UNPOOLED ==》 不使用连接池 POOLED ==》 使用连接池 (√) JNDI ==》 (过时) -->
<dataSource type="POOLED" >
<property name="username" value="${c3p0.user}"/>
<property name="password" value="${c3p0.password}"/>
<property name="driver" value="${c3p0.driverClass}"/>
<property name="url" value="${c3p0.jdbcUrl}"/>
</dataSource>
</environment>
</environments>
<!-- 2. 导入XxxMapper.xml文件 -->
<!-- 定义映射器 -->
<mappers>
<!-- 使用这个方案,可以 单独 指定 Mapper的位置 -->
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
EmpMapper.xml
<?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一般指定为当前文件的所在包路径+文件名(将来是接口名) 在程序中通过[ namespace + id ]定位到执行哪一条SQL语句 -->
<!-- namespace、id 是定位标识!!重要! -->
<mapper namespace="EmpMapper">
<!-- 提示的来源:头文件中"http://mybatis.org/dtd/mybatis-3-mapper.dtd" 提供 -->
<!-- 如果没有提示,通过配置xml***获取。 -->
<!-- 练习1. 查询所有员工信息 -->
<select id="findAll" resultType="cn.edut.pojo.Empolyee">
select * from emp ;
</select>
</mapper>
TestMybatis
package cn.edut.day33;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import cn.edut.pojo.Empolyee;
/** * MyBatis快速入门程序 */
public class TestMybatis {
/** * 练习1:查询所有员工信息 List<Employee> * @throws IOException */
@Test
public void testFindAll() throws IOException {
//1. 读取 Mybatis 的核心配置文件(mybatis-config.xml)
InputStream in = Resources.getResourceAsStream("mybatis-config.xml") ;
//2. 通过配置获取一个SqlSessionFactory对象
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in) ;
//3. 通过工厂获取一个SqlSession对象
SqlSession session = ssf.openSession();
//4. 执行SQL语句(XxxMapper.xml), 返回处理后的结果
List<Empolyee> list = session.selectList("EmpMapper.findAll");
//5. 输出结果
for (Empolyee e : list) {
System.out.println(e);
}
}
}
2、执行findAll方法,输出结果为:
文章目录
3 MyBatis入门细节
3.1 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">
<!-- MyBatis的全局配置文件 -->
<configuration >
<!-- 配置环境,可配置多个环境(比如:develop开发、test测试) -->
<environments default="develop">
<environment id="develop">
<!-- 配置事务管理方式:JDBC/MANAGED JDBC:将事务交给JDBC管理(推荐) MANAGED:自己管理事务 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,即连接池 JNDI/POOLED/UNPOOLED JNDI:已过时 POOLED:使用连接池(推荐) UNPOOLED:不使用连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 引入Mapper配置文件,可以配置多个 -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
configuration
是根标签,当前文件中所有的配置都在该标签内,注意其中配置的关键点:
默认的环境 ID(比如:default="develop")。
每个 environment 元素定义的环境 ID(比如:id="develop")。
事务管理器的配置(比如:type="JDBC")。
数据源的配置(比如:type="POOLED")。
-
<mark>environments标签</mark>:
该标签内部可以配置多个environment,即多种环境,
每种环境可以做不同配置或连接不同数据库。
例如,
开发、测试、生产环境可能需要不同的配置,
连接的数据库可能也不相同,
因此我们可以配置三个environment,分别对应上面三种不同的环境。
但是要记住,environment可以配置多个,
<mark>但是最终要使用的只能是其中一个</mark>! -
<mark>environment标签</mark>:
内部可以配置多种配置信息,
下面介绍 ∗∗事务管理配置∗∗和 ∗∗数据源配置∗∗。 -
<mark>transactionManage标签</mark>:
∗∗事务管理配置∗∗
mybatis
中有两种事务管理方式,
也就是type="[JDBC|MANAGED]
。JDBC
:
这个配置就是直接使用了 JDBC 的提交和回滚设置,
它依赖于从数据源得到的连接来管理事务范围。
<mark>推荐使用</mark>。MANAGED
:
这个配置几乎没做什么。
它从来不提交或回滚一个连接。
需要自己手动添加并管理。
不推荐使用。
-
<mark>dataSource标签</mark>:
数据源,也就是连接池配置。
这里type指定数据源类型,有三种内建的类型:
JNDI
、POOLED
、UNPOOLED
JNDI
:
已过时,不推荐使用!POOLED
:
使用连接池,mybatis会创建连接池,并从连接池中获取连接访问数据库,在操作完成后,将会把连接返回连接池。UNPOOLED
:
不使用连接池,该方式适用于只有小规模数量并发用户的简单应用程序上。
-
<mark>mappers标签</mark>:
用于导入mapper文件的位置,
其中可以配置多个mapper,
即可以导入多个mapper文件。
3.2 EmpMapper.xml配置文件
<?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一般指定为当前文件的所在包路径+文件名 将来在程序中通过[ namespace + id ]定位到执行哪一条SQL语句 -->
<mapper namespace="EmpMapper">
<!-- 通过select、insert、update、delete标签声明要执行的SQL -->
<select id="findAll" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
<!-- resultType:返回值类型,简单类型(例如:Integer,String,Emp等) 如果返回集合(List<Emp>),只需配置集合中的元素类型即可! resultMap:复杂对象结构(例如多表关联查询等),后面用到再讲解 -->
</mapper>
- 第1行是xml的文档声明,用于声明xml的版本和编码
- 第2、3、4行,引入了xml约束文档,当前xml文档将会按照mybatis-3-mapper.dtd文件所要求的规则进行书写。
- Mapper标签:根标签,其中namespace(名称空间,也叫命名空间),要求不能重复。其实就是一个名称,一般我们指定为"包名+文件名"。
- select标签:用于指定将来要执行的各种SQL语句。标签上可以声明属性,下面介绍常用的属性:id、resultType、resultMap
- id属性:要求值不能重复。将来在执行SQL时,可以通过namespace + id找到指定SQL并执行。
- resultType属性:从这条SQL语句中返回所期望类型的类的完全限定名称(包名+类名)。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。
简而言之,resultType控制查询SQL执行后返回值的类型或集合中的泛型,例如查询emp表中的单条记录,返回值是一个Emp对象,因此,resultType=“com.tedu.pojo.Emp”;
如果查询emp表中的多条记录,返回值是一个List,此时resultType的值应该集合中的泛型,因此resultType=“com.tedu.pojo.Emp”;
resultMap属性:复杂对象结构(例如多表关联查询等)。 使用 resultType 或 resultMap,但不能同时使用。