Mybatis

Mybatis

1.事务以及四大特征

1.什么是事务

​ 数据库事务(Databases Transaction),是指作为单个逻辑工作单元执行的一系列操作.要么完全的执行,要么完全的不执行

​ 简单的说:事务就是将一堆的SQL语句(通常是增删改查)绑在一起,要么都执行成功,要么都执行失败

​ 以银行转账为例,张三转100块到李四的账号,这至少需要两条SQL语句:

​ 1.给张三的账户减去100

update账户表 set money=money-100 where name='张三

​ 2.给李四的账户加上100元

update 账户表 set money=money+1oo where name='李四'

​ 如果在第一条SQL语句执行成功后,在执行第二条SQL语句之前,程序被中断了(可能是抛出了异常),那么李四的账户上没有加100,但张三账户上减去100,在现实中是不允许的

2.事务的四大特性

​ 事务的四大特性(ACID)是:

​ 1.原子性(Atomicity):事务中所有操作是不可再分割的原子单位.事务中所有操作要么全部执行成功,要么全部执行失败

​ 2.一致性(Consistency):事务执行后,数据库状态与其他业务规则保持一致.

​ 3.隔离性(Isolation):隔离性是指在并发操作中,不同的事务之间应该隔离开来,使每个并发中的事务不会相互干扰.

​ 4.持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中

2.Mysql事务

​ start transaction; – 手动开启事务

​ rollback; – 回滚事务

​ commit – 提交事务

1.脏读(dirty read)

读到另一个事务的未提交更新数据,即读到了脏数据;

2.不可重复读(unrepeatable read)

对同一记录的两次读取不一致,因为另一事务对该记录做了修改(是针对修改操作)

3.幻读(虚读)(phantom read)

对同一张表的两次查询不一致,因为另一事务插入了一条记录

3.MyBatis简介(了解)

1.什么是MyBatis

​ MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦。

下图是MyBatis架构图:
在这里插入图片描述

(1)mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂

(2)基于SqlSessionFactory可以生成SqlSession对象

(3)SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的Connection对象,也是Mybatis中至关重要的一个对象。

(4)Executor是SqlSession底层的对象,用于执行SQL语句

(5)MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)

2.为什么要使用Mybatis

​ 1.使用传统方式访问JDBC数据库

​ (1)使用JDBC访问数据库有大量重复代码(比如注册驱动、获取连接、获取传输器、释放资源等);

​ (2)JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低;

​ (3)SQL是写死在程序中,一旦修改SQL,需要对类重新编译;

​ (4)对查询SQL执行后返回的ResultSet对象,需要手动处理,有时会特别麻烦;

​ 2.使用mybatis框架访问数据库:

​ (1)Mybatis对JDBC对了封装,可以简化JDBC代码;

​ (2)Mybatis自身支持连接池(也可以配置其他的连接池),因此可以提高程序的效率;

​ (3)Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译。

​ (4)对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。

总之,JDBC中所有的问题(代码繁琐、有太多重复代码、需要操作太多对象、释放资源、对结果的处理太麻烦等),在Mybatis框架中几乎都得到了解决!!

Hibernate 和 Mybatis都是持久层(Mybatis需要写SQL语句,而Hibernate)

4.MyBatis快速入门

对mydatabase里的emp表进行测试

表格式如下

create table emp(
	id int primary key auto_increment,
	name varchar(50),
	job varchar(50),
	salary double
);
1.创建maven工程
2.导入junit,mysql,mybatis等开发包

在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 -->
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.6.4</version>
	</dependency>
</dependencies>

可以自己去https://mvnrepository.com/里下载最新的maven依赖

3.添加mybatis-config.xml文件

1.在src/main/resource目录下,创建mybatis-config.xml文件(MyBatis的核心配置文件)

2.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 >
	<!-- 1.配置开发环境(需设置一个默认的环境) -->
	<environments default="develop">
		<!-- 这里可以配置多个环境,比如develop,test等 -->
		<environment id="develop">
			<!-- 1.1.配置事务管理方式:JDBC/MANAGED
			JDBC:将事务交给JDBC管理(推荐)
			MANAGED:自己管理事务
			  -->
			<transactionManager type="JDBC"></transactionManager>
			
			<!-- 1.2.配置数据源,即连接池方式:JNDI/POOLED/UNPOOLED
				JNDI:已过时
				POOLED:使用连接池(推荐)
				UNPOOLED:不使用连接池
			 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/><!-- jdbc驱动 -->
				<property name="url" value="jdbc:mysql://localhost:3306/yourdatabase?characterEncoding=utf-8"/>  <!-- 连接本地的数据库并设定编码格式为utf-8 -->
				<property name="username" value="root"/><!-- 用户名 -->
				<property name="password" value="root"/><!-- 密码 -->
			</dataSource>
		</environment>
	</environments>
	
	<!-- 2.加载Mapper配置文件(因mapper文件中配置了要执行的SQL语句) -->
	<mappers>
		<!-- 注意路径 -->
		<mapper resource="XxxMapper.xml"/> <!-- XxxMap为你自己的实体类所对应的mapper.xml文件 -->
	</mappers>
</configuration>

configuration是根标签,当前文件中所有的配置都在该标签内,注意其中配置的关键点:

默认的环境 ID(比如:default=“develop”)。

每个 environment 元素定义的环境 ID(比如:id=“develop”)。

事务管理器的配置(比如:type=“JDBC”)。

数据源的配置(比如:type=“POOLED”)。

1.encironments标签:该标签内部可以配置多个environment,即多种环境,每种环境可以做不同配置或连接不同数据库。例如,开发、测试、生产环境可能需要不同的配置,连接的数据库可能也不相同,因此我们可以配置三个environment,分别对应上面三种不同的环境。

但是要记住,environment可以配置多个,但是最终要使用的只能是其中一个!

2.environment标签内部可以配置多种配置信息,下面介绍事务管理配置和数据源配置。

3.transactionManage事务管理配置,mybatis中有两种事务管理方式,也就是 type="[JDBC|MANAGED]。

​ JDBC:这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。推荐使用。

​ MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。需要自己手动添加并管理。不推荐使用。

4.dataSource标签:数据源,也就是连接池配置。这里type指定数据源类型,有三种内建的类型:JNDI、POOLED、UNPOOLED

​ JNDI:已过时,不推荐使用!

​ POOLED:使用连接池,mybatis会创建连接池,并从连接池中获取连接访问数据库,在操作完成后,将会把连接返回连接池。

​ UNPOOLED不使用连接池,该方式适用于只有小规模数量并发用户的简单应用程序上。

5.mappers标签:用于导入mapper文件的位置,其中可以配置多个mapper,即可以导入多个mapper文件。

4.添加并编写实体类

这里我们以员工类Emp为例

在src/main/java目录下创建pojo包,并创建Emp类

package com.king.pojo;
/**
 * 实体类,用于封装Emp表中的一条用户信息
 */
public class Emp {
	//1.声明实体类中的属性
	private Integer id;
	private String name;
	private String job;
	private Double salary;
	
	//2.提供对应的getter和setter方法
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	
	//3.重写toString方法
	@Override
	public String toString() {
		return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
	}
}
5.添加EmpMapper.xml文件

1.在src/main/resource目录下,创建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 -->
	<!-- 练习1: 查询emp表中的所有员工信息
		resultType指定查询的结果将会封装到什么类型中 -->
	<select id="findAll" resultType="com.king.pojo.Emp">
		select * from emp
	</select>
	<!-- 
	resultType:返回值类型,简单类型(例如:Integer,String,Emp等)
		如果返回集合(List<Emp>),只需配置集合中的元素类型即可!
	-->
</mapper>

1.第1行是xml的文档声明,用于声明xml的版本和编码

2.第2、3、4行,引入了xml约束文档,当前xml文档将会按照mybatis-3-mapper.dtd文件所要求的规则进行书写。

3.Mapper标签:根标签,其中namespace(名称空间,也叫命名空间),要求不能重复。其实就是一个名称,一般我们指定为"包名+文件名"。

4.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,但不能同时使用。

6.建立测试类测试

在src/main/java目录下建立testMybatis包,建立TestMybatis类

package com.king.testMybatis;
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 com.king.pojo.Emp;
/**
 * Mybatis的快速入门案例
 * 查询emp表中的所有的员工信息,将员工信息封装到list集合中返回
 * @author Administrator
 *
 */
public class TestMybatis {
    //练习1:查询所有员工的信息
    @Test
    public void testFindAll() throws Exception {
        //1.读取mybatis核心配置文件(mybatis-config.xml)
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.获取SqlSessionFactory工厂对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.读取SqlSession对象(打开了域数据库的连接)
        SqlSession session = factory.openSession(); 
        //4.执行mapper文件中的sql语句,返回处理结果
        List<Emp> list = session.selectList("EmpMapper.findAll");
        //5.输出结果
        for (Emp emp : list) {
            System.out.println(emp);
        } 
    }
}

5.MyBatis增删改查

1.新增员工

1.编辑EmpMapper.xml文件,添加新增

<!-- 注意:除了查询的标签外,其他标签不用指定resultType,因为返回值都是int类型 -->
<update id="insert" >
	insert into emp value(null, 'king', 'singer', 888)
</update>

2.编写TestMybatis类,添加testInsert方法,实现增加员工的操作

@Test
public void testInsert() { 
	//执行sql语句, 返回执行结果
	int rows = session.update("EmpMapper.insert");
	//提交事务
	session.commit();
	System.out.println("影响的行数: "+rows);
}
2.修改员工

1.编辑EmpMapper.xml文件,添加新员工对应的sql

<update id="update">
	update emp set job='歌手&演员', salary=8888 where name='king'
</update>

2.编写TestMybatis类,添加testUpdate方法,实现修改员工的信息

@Test
public void testUpdate() { }
	//执行sql语句, 返回执行结果
	int rows = session.update("EmpMapper.update");
	//提交事务
	session.commit();
	System.out.println("影响行数:"+rows);
}
3.删除员工

1.编辑EmpMapper.xml文件,添加新增员工对应的sql

<update id="delete">
	delete from emp where name='king'
</update>

2.编写TestMybatis类,添加testDelete方法,实现删除员工

@Test
public void testDelete() {
	//执行sql语句, 返回执行结果
	int rows = session.update("EmpMapper.delete");
	//提交事务
	session.commit();
	System.out.println("影响行数:"+rows);
}
4. #{ }占位符

在上面的增删改查操作中,SQL语句中的值是写死在SQL中,而在实际开发中,此处的值往往是用户提交过来的值,因此这里我们需要将SQL中写死的值替换为占位符。

除员工

1.编辑EmpMapper.xml文件,添加新增员工对应的sql

<update id="delete">
	delete from emp where name='king'
</update>

2.编写TestMybatis类,添加testDelete方法,实现删除员工

@Test
public void testDelete() {
	//执行sql语句, 返回执行结果
	int rows = session.update("EmpMapper.delete");
	//提交事务
	session.commit();
	System.out.println("影响行数:"+rows);
}
4. #{ }占位符

在上面的增删改查操作中,SQL语句中的值是写死在SQL中,而在实际开发中,此处的值往往是用户提交过来的值,因此这里我们需要将SQL中写死的值替换为占位符。

使用占位符完成上面的增删改查练习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值