一. Mybatis概述
原本是Apache的一个开源项目叫iBatis,2010年迁移到Google Code旗下,改名为Mybatis
- Mybatis是一款优秀的持久层框架,是对JDBC的封装
- Mybatis几乎避免了JDBC所有的手动设置参数以及手动获取结果的操作
- Mybatis可以使用注解或XML文件来配置和映射,将数据库中的数据映射成java中的一个对象
二. Mybatis环境搭建
1.创建一张表和表对应的实体类
因为mybatis可以帮我们将数据库中的数据直接封装到一个java对象中,所以我们需要在数据库中创建一张对象表,在java程序中创建一个实体类,以便于mybatis可以将数据封装到对应的实体类产生的对象中
注意:数据库中有哪些数据,实体类中就有哪些属性,并且要生成get和set方法
CREATE TABLE admin(
id INT PRIMARY KEY AUTO_INCREMENT,
account VARCHAR(20) UNIQUE NOT NULL,
PASSWORD VARCHAR(32) NOT NULL,
gender CHAR(1)
)
public class Admin {
private int id;
private String account;
private String password;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Admin{" +
"id=" + id +
", account='" + account + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
2. 导入mybatis和mysql的jar包
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
3. 创建mybatis全局配置文件
在resources文件夹中创建一个.xml文件,并将下面代码复制到该文件中
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--.dtd文件是用来规定标签语法规范的-->
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/> <!--打印执行日志-->
</settings>
<!--为类型配置别名-->
<typeAliases>
<package name="com.ffyc.mybatis.model"/>
<!--<typeAlias type="com.ffyc.mybatis.model.Admin" alias="admin"></typeAlias>-->
</typeAliases>
<environments default="development">
<environment id="development">
<!--
事务管理方式:就是一次对数据库操作过程中,执行多条sql的管理
转账:
从A账户向B账户转钱
A-500
代码 异常
B +500
把所有的操作的都成功执行后,在提交事务,让数据库最终执行本次提交的所有sql
-->
<transactionManager type="JDBC"/> <!--使用jdbc事务管理-->
<!--数据库连接池配置
频繁的创建销毁与数据库的连接对象是比较占用时间和空间
可以在池子中默认创建若干个连接对象,在请求使用时,直接从连接池中取出一个对象,用完再还回去
减少创建和销毁的时间开销
-->
<dataSource type="POOLED">
<!--数据库连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--配置sql映射文件-->
<mappers>
<mapper resource="mappers/AdminMapper.xml"></mapper>
</mappers>
</configuration>
4.定义接口
在Dao层创建一个用于和数据库交互的接口,里面定义一些需要和数据库交互的方法
package com.ffyc.mybatis.dao;
import com.ffyc.mybatis.model.Admin;
import java.util.List;
public interface AdminDao {
Admin findAdminById(int id); //通过ID查询用户
List<Admin> findAdmins(); //返回所有用户集合
void savedAdmins(Admin admin); //新增用户信息
}
5. 创建sql映射文件
在resources文件夹中,创建一个Mappers文件夹,并在该文件夹中创建一个.xml文件,用于实现上述接口中定义的方法(写sql)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--与接口进行绑定-->
<mapper namespace="com.ffyc.mybatis.dao.AdminDao">
<insert id="savedAdmins" parameterType="Admin">
insert into admin(account)values (#{account})
</insert>
<select id="findAdminById" parameterType="int" resultType="Admin">
select * from admin where id = #{id}
</select>
<!--使用别名即可
id值 必须与对应接口中的方法名一致
parameterType 和接口中的参数类型一致
resultType 和接口中的返回值类型一致
-->
<select id="findAdmins" resultType="Admin">
select * from admin
</select>
</mapper>
映射文件创建完成后,一定要将映射文件导入mybatis全局配置文件中
<!--配置sql映射文件-->
<mappers>
<mapper resource="mappers/AdminMapper.xml"></mapper>
</mappers>
6. 测试Mybatis
import com.ffyc.mybatis.model.Admin;
import com.ffyc.mybatis.util.MybatisUtil;
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 java.io.IOException;
import java.io.Reader;
import java.util.List;
public class Test1 {
public static void main(String[] args) throws IOException {
//将mybatis.xml文件读入到该文件中
Reader reader = Resources.getResourceAsReader("mybatis.xml");
//获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建sqlSession对象
SqlSession sqlSession = MybatisUtil.getSqlSessionFactory();
//为接口创建一个代理对象
AdminDao adminDao = sqlSession.getMapper(AdminDao.class);
//调用我们自己的方法
Admin admin = adminDao.findAdminById(1);
System.out.println(admin);
List<Admin> admins = adminDao.findAdmins();
System.out.println(admins);
Admin admin1 = new Admin();
admin1.setAccount("aaaaaaaa");
adminDao.savedAdmins(admin1);
Admin admin2 = new Admin();
admin2.setAccount("bbbbbbbbbbb");
adminDao.savedAdmins(admin2);
sqlSession.commit(); //提交事务
}
}
三. Mybatis配置详解
1. mybatis全局配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--.dtd文件是用来规定标签语法规范的-->
上述代码是规定配置文件中能出现哪些标签,如果没有在.dtd文件中出现的标签是不能定义的,否则会报错
<configuration>
</configuration>
mybatis全局配置文件的根标签,所有配置信息都要写到该标签中
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/> <!--打印执行日志-->
</settings>
可以在执行时打印执行的日志,就可以具体的看到数据库的执行过程,比如创建了几个数据库连接池对象,什么时候提交的事务等
<!--为类型配置别名-->
<typeAliases>
<!--name是定义的接口的路径,不包含接口名,这样就可以直接用接口名当返回值或参数类型-->
<package name="com.ffyc.mybatis.model"/>
<!--这是第二种方法,type是接口的全类名,alias是定义的别名,可以用别名当做返回值或参数类型-->
<!--<typeAlias type="com.ffyc.mybatis.model.Admin" alias="admin"></typeAlias>-->
</typeAliases>
可以为mapper配置文件中的类型起别名,mapper配置文件中的参数类型和返回值类型一般要写全类名,这样会很麻烦,但是我们可以利用上述方案,给类型起别名,这样在配置mapper文件时就可以将类型简写了
<environments default="development">
<environment id="development">
<!--
事务管理方式:就是一次对数据库操作过程中,执行多条sql的管理
转账:
从A账户向B账户转钱
A-500
代码 异常
B +500
把所有的操作的都成功执行后,在提交事务,让数据库最终执行本次提交的所有sql
-->
<transactionManager type="JDBC"/> <!--使用jdbc事务管理-->
<!--数据库连接池配置
频繁的创建销毁与数据库的连接对象是比较占用时间和空间
可以在池子中默认创建若干个连接对象,在请求使用时,直接从连接池中取出一个对象,用完再还回去
减少创建和销毁的时间开销
-->
<dataSource type="POOLED">
<!--数据库连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
上述代码是设置事务的管理方式和数据库建立连接的地址,用到了数据库连接池
事务:在一次与数据库交互的过程中要执行多条sql
如果在执行时,一条sql执行了,但在执行另一条之前遇到了异常,就可能导致另一条sql没有执行,就会导致错误的发生,这就好比,A向B转账,已经扣了A 500 但没有给B加 500 所以为了解决这个问题,在mybatis中,不像之前的JDBC一样会自动提交事务,而是需要我们在所有逻辑都已经执行完,并且不会发生异常的情况下自己提交事务
注意:在于数据库的交互中,如果我们只是提交了sql数据库并不会立即执行该sql,而是当我们提交了事务数据库才会真正执行sql,在mybatis中利用sqlSession对象中的commit方法提交事务
<dataSource type="POOLED">
<!--数据库连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
这个数据库连接池就是之前定义的与数据库连接所需要的加载驱动,与哪个数据库进行连接,数据库账号和密码,可以看到利用mybatis我们只需要将这些在配置文件配置一次即可
数据库连接池:池,就是一种缓存技术,当用户量比较大时,会频繁的与数据库交互,这样程序就要不停地创建和销毁连接对象,这样会占用大量的时间和空间,为了解决这个问题,我们就利用了这么一种池化思想,提前创建一些连接对象,当用户需要连接上来时,如果池中有空闲的连接对象,就不用创建新的,而是直接将该连接对象分配给这个用户,当这个用户使用完毕时,也不用销毁,而是将标记修改为空闲即可
<!--配置sql映射文件-->
<mappers>
<mapper resource="mappers/AdminMapper.xml"></mapper>
</mappers>
这段代码是将创建的sql映射文件配置到全局的mybatis配置文件中,resource后面跟的是sql映射文件的全名
2. 创建sql映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
和mybatis配置文件相同,这段代码同样是规定了可以定义哪些标签在这个sql映射文件中
<mapper namespace="com.ffyc.mybatis.dao.AdminDao">
</mapper>
<mapper></mapper>标签是配置文件的根标签,所有的配置都写在该文件中,namspqce后面的是接口的全类名
<insert id="savedAdmins" parameterType="Admin">
insert into admin(account)values (#{account})
</insert>
<select id="findAdminById" parameterType="int" resultType="Admin">
select * from admin where id = #{id}
</select>
<!--使用别名即可
id值 必须与对应接口中的方法名一致
parameterType 和接口中的参数类型一致
resultType 和接口中的返回值类型一致
-->
<select id="findAdmins" resultType="Admin">
select * from admin
</select>
上面这几个都是为了实现接口中的方法,定义的与数据库进行交互的sql语句,利用这个可以实现与数据库的交互<select></select>标签是查询,<insert></insert>标签是插入,切记id和接口中的方法名一致,parameterType是形参类型,resultType是最终返回值的类型,这里本来是要写全类名的,但由于之前起了别名,所以这里可以直接用接口名Admin当做返回值类型
3. 定义接口
package com.ffyc.mybatis.dao;
import com.ffyc.mybatis.model.Admin;
import java.util.List;
public interface AdminDao {
Admin findAdminById(int id);
List<Admin> findAdmins();
void savedAdmins(Admin admin);
}
接口中主要就是定义一些与数据库交互的方法,声明该方法的形参和返回值,以便于sql映射文件中可以设置好参数类型和返回值,这样mybatis就可以帮我们把数据封装到对象中
4. 测试mybatis
//将mybatis.xml文件读入到该文件中
Reader reader = Resources.getResourceAsReader("mybatis.xml");
将mybatis.xml文件读到类中,这样就可以在该类中使用mybatis配置文件中的信息
//获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
获取sqlSessionFactory对象主要的目的是为了获取sqlSession对象
//创建sqlSession对象
SqlSession sqlSession = MybatisUtil.getSqlSessionFactory();
根据sqlSessionFactory对象获取sqlSession对象,获得sqlSession对象主要是为了获取可以调用方法的代理对象
//为接口创建一个代理对象
AdminDao adminDao = sqlSession.getMapper(AdminDao.class);
根据sqlSession对象获得一个代理对象,根据该代理对象可以调用接口中的方法
注意:接口的代理对象并不是真正的接口的对象,因为接口/抽象类是不能产生对象的,所以这只是一个该接口的代理对象,该对象可以根据配置信息中的路径来找到该方法并通过映射文件找到该方法对应的sql来执行
四. Mybatis Dao层面向接口开发
面向接口开发方式只需要程序员编写接口,由Mybatis框架创建接口的动态代理 对象,使用sqlsession.getMapper(接口.class);获得代理对象
面向接口开发需要遵循以下规范:
1.Mapper.xml文件中的namespace与mapper接口的类路径相同.
2.Mapper接口方法名和Mapper.xml中定义的每个statement的id相同.
3.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的 parameterType 的类型相同. 4.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的 resultType 的类型相同.