1.封装JDBC,负责访问数据库,完成持久化操作(MyBatis框架)
2.使用其核心思想IOC管理组件,使用AOP思想实现功能增强(Spring)
3.接收浏览器发送的请求,并响应浏览器数据(SpringMVC)
SSM整合(结合案例整合SSM,进一步了解各个框架的功能)
iBatis提供的持久层框架包括SQL Maps(SQL映射:把我们java里面的实体类对象映射为数据库中的一条记录或者把数据库中的记录查询为我们当前java中的实体类对象)和Data Access Objects(三层架构里面的DAO层,主要作用是数据访问对象,然后来进行数据访问)。
MyBatis特性:
Hibernate框架里面的SQL语句都是框架生成的,而MyBatis框架里面的SQL语句都是需要自己写的。
(1)MyBatis是支持定制化SQL、存储过程以及高级映射(当我们去查询一条数据的时候,如果字段名和属性名一致,我们可以自动将我们的这条数据转换为相对应的实体类对象,但是当出现字段名和属性名不一致以及多对一的映射以及一对多的映射,这个时候没有办法正常映射,但是MyBatis提供了很便利的解决方案)的是很好,的优秀的持久层框架。
(2)MyBatis避免了几乎所有的JDBC代码(注册驱动,获取连接对象,获取预编译对象,执行SQL语句,获得结果)和手动设置参数以及获取结果集(我们有些数据是需要拼接到SQL里面的,开发的是B/S系统,好多数据都是从浏览器传输到服务器中,需要手动拼接到我们的SQL语句里面,JDBC是依靠手动拼接和占位符赋值的方式拼接到SQL中,而MyBatis中提供了#{}何${}的方式)
(3)MyBatis可以使用简单的XML或注解(操作数据库的方式)用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的java对象)映射成数据库中的记录。
JDBC将数据手动拼接到SQL语句里面,通过字符串拼接和占位符赋值的的方式拼接到SQL里面,MyBatis用#{和${的方式进行拼接。
(4)MyBatis是一个半自动的ORM(Object Relation Mapping对象关系映射)框架
Object为java中的对象,关系Relation为关系型数据库,是把我们当前java中的对象和我们的数据库中的一条记录来创建映射关系,我们可以把java中的一条对象映射为一条记录,也可以把当前数据库中的一条记录查询为一个java对象,是java中的实体类对象和我们当前的关系型数据库中的一条记录的之间的关系。
MyBatis下载:
网址如下所示:
GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java
里面为我们的下载文档,下载 最新版本,下载拍照版本。
和其它持久化层技术对比:
JDBC
(1)SQL夹杂在Java代码中耦合度高,导致硬编码内伤
(2)维护不易且实际开发需求中SQL有变化,频繁修改的情况多见(Java项目要打成jar包,而web工程要打成war包)
(3)代码冗长,开发效率低
Hibernate(全自动的持久型框架)和JPA:
(1)操作简便,开发效率高
(2)程序中的长难复杂SQL需要绕过框架
(3)内部自动生产的SQL,不容易做特殊优化
(4)基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难(进行增删改查的操作的时候,是实体类,不是表)。
(5)反射操作太多,导致数据库性能下降
MyBatis:
1.配置依赖和创建表、创建相对应的实体类:
在MyBatis中,有两种方式来写SQL语句,一种是注解,一种是XML。
(1)轻量级,性能出色
(2)SQL和Java编码分开,功能边界清晰,java代码专注业务、SQL语句专注数据
(3)开发效率稍逊于HIbernate,但是完全能够接收
MyBatis的配置环境:
1.MySQL 5 版本使用jdbc 5驱动,驱动类使用:com.mysql.jdbc.Driver
.MySQL 8 版本使用jdbc 8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
2.连接地址url:
MySQL 5 版本的url:
jdbc:mysql://+ip地址+端口号/+当前数据库的名称
jdbc:mysql://localhost:3306/ssm
MySQL 8 版本的url:一定要设置时区,没有设置时区则会报异常
jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
我们的本地仓库里面一定要设置好,还需要当前的镜像网站设计好,maven下载jar包从中央仓库下载的,但是速度慢,我们可以设置镜像网站,从镜像网站里面进行下载。
我们设置的依赖如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>untitled2</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mybatis_helloworld</artifactId>
<packaging>jar</packaging>
<name>mybatis_helloworld Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
</dependencies>
<build>
<finalName>mybatis_helloworld</finalName>
</build>
</project>
创建表的过程中主键不能为空。
char和varchar的区别:
MySQL中的字符串有两个常用的类型:char和varchar,二者各有优势,下面我们来详细分析一下。
通常在建表的时候对于String 类型的数据定义我们或许会很纠结 : 什么时候用char 什么时候用 varchar 呢?
首先可以明确的是:
char的长度是不可变的,而varchar的长度是可变的,也就是说,定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的。
尽管如此,char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。
再者,char的存储方式是,对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节;而varchar的存储方式是,对每个英文字符占用2个字节,汉字也占用2个字节。
两者的存储数据都非unicode的字符数据。
一般用 char 类型的 存放 固定的数据 如 身份证号(18) 电话号 性别 。。。。
用varchar 存放可变的数据 这个就太多了 。。。。char类型,如果不设置长度,则默认长度为1.
表和实体类是有映射关系的,我们来创建实体类:
我们创建的代码如下所示:
package com.rgf.mybatis.pojo;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String gender;
private String email;
public User() {
}
public User(Integer id, String username, String password, Integer age, String gender, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.gender = gender;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
'}';
}
}
先建表,后创建实体类,创建实体类的构造器(必须有无参构造),get和set方法,toString方法。
我们完成这些之后,我们就可以搭建mybatis框架,mybatis框架里面主要有两个比较核心的文件,一个是核心配置文件,一个是映射文件。核心配置文件中设置的是如何连接数据库,映射文件中是SQL语句是如何操作数据库。
2.创建MyBatis的核心配置文件
习惯上命名为mybatis-config.xml,
核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
核心配置文件存放的位置是src/main/resources目录下:
<?xml version="1.0" encoding="UTF-8" ?> <!--xml文件的一个声明-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd"><!--xml文件的约束,来规定当前配置文件中都能使用哪些标签-->
<configuration><!--根标签:配置-->
<!--配置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!--事务管理器-->
<dataSource type="POOLED"><!--数据源:帮助我们管理数据库的连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/><!--驱动类-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/><!--连接数据库的地址:jdbc:mysql://+ip地址+端口号/当前操作的数据库?+serverTimezone=UTC-->
<property name="username" value="root"/>
<property name="password" value="123456"/>
<!--我们需要这四个参数:当前这四个参数连接的数据库不一样,当前的这四个参数也是不一样的,所以不管在什么时候,我们要连接数据库,这四个参数是我们必须要设置的-->
</dataSource>
</environment>
</environments>
<!--我们在进行测试的时候,我们是通过读取核心配置文件然后获取了一个操作数据库的对象,然后咱们当前获取了操作数据库的对象后就可以直接执行了一个SQL,而SQL语句是在映射文件中,我们现在一定要把我们当前的映射文件配置到我们的核心配置文件里面,然后我们才可以通过加载核心配置文件去找到相对应得映射文件中得SQL来执行来实现我们要实现的效果-->
<!--引入mybatis的映射文件-->
<mappers>
<mapper resource=""/>
</mappers>
</configuration>
所以整体而言,Mybatis框架就是作为利用SQL语句进行操作数据库,主要有核心配置文件和映射文件,映射文件利用Mapper标签引入MyBatis的映射文件。当我们读取核心配置文件然后获取了一个操作数据库的对象,然后咱们当前获取了操作数据库的对象后就可以直接执行了一个SQL,而SQL语句是在映射文件中,我们现在一定要把我们当前的映射文件配置到我们的核心配置文件里面,然后我们才可以通过加载核心配置文件去找到相对应得映射文件中得SQL来执行来实现我们要实现的效果。
3.创建mapper接口:
MyBatis中的mapper接口相当于以前的dao,但是区别在于,mapper仅仅是接口,我们不需要提供实现类,我们创建接口以后,我们就可以通过MyBatis里面的一些功能来为他创建一个代理实现类,当我们去调用接口中的方法,然后就可以直接帮助我们对应一个SQL语句,来执行一个SQL语句。
package com.rgf.mybatis.mapper;
public interface UserMapper {
int insertUser();
}
4.创建MyBatis的映射文件
ORM:对象关系映射
对象:java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系
java概念 | 数据库概念 |
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
1.映射文件的命名规则:
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
一张表对应一个实体类,而一个Mapper接口对应一个映射文件。
Mapper接口里面的方法对应的是映射文件里面的SQL语句。
因此一个映射文件对应一个实体类,对应一张表的操作。
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
我们的映射文件创建在resources文件夹下面创建一个包为mappers的UserMapper.xml
我们创建的映射文件如下所示:
<!--xml文件的声明-->
<?xml version="1.0" encoding="UTF-8" ?>
<!--当前文件的约束,规定当前的配置文件中能够所使用的标签-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--根标签-->
<!--mapper接口和映射文件要保证两个一致:
1.mapper接口的全类名和映射文件的namespace一致
2.mapper接口中的方法的方法名要和映射文件中的sql的id保持一致
-->
<mapper namespace="com.rgf.mybatis.mapper.UserMapper">
<!--int insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
</insert>
</mapper>
package com.rgf.mybatis.mapper;
//一个Mapper接口对应了映射文件中的一个SQL语句
public interface UserMapper {
int insertUser();
}
我们创建完映射文件后,需要在核心配置文件里面引入mybatis的映射文件:
<?xml version="1.0" encoding="UTF-8" ?> <!--xml文件的一个声明-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd"><!--xml文件的约束,来规定当前配置文件中都能使用哪些标签-->
<configuration><!--根标签:配置-->
<!--配置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!--事务管理器-->
<dataSource type="POOLED"><!--数据源:帮助我们管理数据库的连接-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/><!--驱动类-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/><!--连接数据库的地址-->
<property name="username" value="root"/>
<property name="password" value="123456"/>
<!--我们需要这四个参数:当前这四个参数连接的数据库不一样,当前的这四个参数也是不一样的,所以不管在什么时候,我们要连接数据库,这四个参数是我们必须要设置的-->
</dataSource>
</environment>
</environments>
<!--我们在进行测试的时候,我们是通过读取核心配置文件然后获取了一个操作数据库的对象,然后咱们当前获取了操作数据库的对象后就可以直接执行了一个SQL,而SQL语句是在映射文件中,我们现在一定要把我们当前的映射文件配置到我们的核心配置文件里面,然后我们才可以通过加载核心配置文件去找到相对应得映射文件中得SQL来执行来实现我们要实现的效果-->
<!--引入mybatis的映射文件-->
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
综上所述,我们了解到核心配置文件和映射文件两者是如何进行关联的,首先:
核心配置文件是通过调用Mapper接口里面的方法来调用映射文件里面的SQL语句。
核心配置文件里面要加载映射文件,我们先创建Mapper接口,Mapper接口里面的方法名与映射文件里面的SQL语句的id是要相对应的,映射文件里面的namespace与Mapper接口的地址一致。完成映射文件后一=定要在核心配置文件Mappers里面引入。
我们通过设置测试类来查看MyBatis的添加用户功能:
设置代码如下所示:
package com.rgf.mybatis.test;
import com.rgf.mybatis.mapper.UserMapper;
import com.rgf.mybatis.pojo.User;
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 java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
//获取核心配置文件的输入流(读的功能)输出流(写的功能)(获取字节输入流)
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//找到帮助我们执行SQL语句的对象。
//获取SqlSessionFactoryBuilder对象(builder为构建器,用来构建SqlSessionFactory)
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取SqlSessionFactory对象(SqlSessionFactory对象是一个工厂对象,使用的是工厂模式,可以提供去掉Factory的SqlSession对象)
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取sql的会话对象SqlSession,是MyBatis提供的操作数据库的对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行SQL语句的,而sql语句与当前的UserMapper接口中的方法对应的
//需要创建Mapper接口的对象,调用其中的方法,但是接口不能直接创建实例化对象,我们必须重写当前接口中的抽象方法。
//获取UserMapper的代理实现类对象,用的代理模式帮助我们创建了当前mapper接口的代理实现类,实现了我们当前的UserMapper接口,帮助我们去重写接口中的方法
//getMapper方法,传进去的为某一个类型的class对象,返回的是当前类型的实例化对象。
UserMapper mapper= sqlSession.getMapper(UserMapper.class);
//通过我们当前Mapper接口的全类名找到我们当前的映射文件,然后再通过我们当前要调用的方法来找到我们当前映射文件中的SQL语句来执行,并将结果返回,这就是重写的过程。
// 调用mapper接口中的方法,实现添加用户信息的功能
//方法一:int result = mapper.insertUser();
//通过sql语句的唯一标识找到sql并执行,唯一标识是namespace.sqlId,方法二:
int result = sqlSession.insert("com.rgf.mybatis.mapper.UserMapper.insertUser");
System.out.println("结果:"+result);
//通过这种方法,是需要自己提交和进行回滚的,不会自动提交的。提交事务
sqlSession.commit();
//关闭SqlSession对象
sqlSession.close();
}
}
我们运行之后如下所示:
出现为1即为成功,我们进行查看数据表:
测试添加用户信息的功能:
我们去编写测试类去测试MyBatis的调用数据库添加用户信息的功能:
我们将代码设置如下所示:
package com.rgf.mybatis.test;
import com.rgf.mybatis.mapper.UserMapper;
import com.rgf.mybatis.pojo.User;
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 java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
//获取核心配置文件的输入流(读的功能)输出流(写的功能)(获取字节输入流)
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//找到帮助我们执行SQL语句的对象。
//获取SqlSessionFactoryBuilder对象(builder为构建器,用来构建SqlSessionFactory)
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取SqlSessionFactory对象(SqlSessionFactory对象是一个工厂对象,使用的是工厂模式,可以提供去掉Factory的对象)
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取sql的会话对象SqlSession,是MyBatis提供的操作数据库的对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//SqlSession sqlSession = sqlSessionFactory.openSession();不会自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true); 会自动提交事务
//执行SQL语句的,而sql语句与当前的UserMapper接口中的方法对应的
//需要创建Mapper接口的对象,调用其中的方法,但是接口不能直接创建实例化对象,我们必须重写当前接口中的抽象方法。
//获取UserMapper的代理实现类对象,用的代理模式帮助我们创建了当前mapper接口的代理实现类,实现了我们当前的UserMapper接口,帮助我们去重写接口中的方法
//getMapper方法,传进去的为某一个类型的class对象,返回的是当前类型的实例化对象。
UserMapper mapper= sqlSession.getMapper(UserMapper.class);
//通过我们当前Mapper接口的全类名找到我们当前的映射文件,然后再通过我们当前要调用的方法来找到我们当前映射文件中的SQL语句来执行,并将结果返回。
// 调用mapper接口中的方法,实现添加用户信息的功能
//方法一:int result = mapper.insertUser();
//通过sql语句的唯一标识找到sql并执行,唯一标识是namespace.sqlId,方法二:
int result = sqlSession.insert("com.rgf.mybatis.mapper.UserMapper.insertUser");
System.out.println("结果:"+result);
//通过这种方法,是需要自己提交和进行回滚的,不会自动提交的。手动提交事务
// sqlSession.commit();
//关闭SqlSession对象
sqlSession.close();
}
}
我们运行之后如下所示:
我们发现底层为Sqlsession.insert方法,我们追进去如下所示:
走到这里的时候,invoke方法就是执行的方法。
源码将所要执行的SQL语句进行了封装,封装到了我们当前的command中,
type为我们当前的操作,为添加,而name为Sqlsession.SqlId.
我们发现我们在所写的代码是一致的,其中sqlsessiomn.getName().就是我们所传进去的唯一标识。
我们进入数据库里面进行查看:
我们发现已经成功加入进去,由于运行了多次,加入了多个数据。
为了可以详细查看运行结果,我们将日志文件导入如下所示:添加日志功能
我们先在pom.xml里面引入如下文件:
<!--log4j日志-->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
我们设置的日志的配置文件,在文件包resources下面:命名为log4j.xml,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5d %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n"/>
</layout>
</appender>
<logger name="java.sql">
<level value="debug"/>
</logger>
<logger name="org.apache.ibatis" >
<level value="info"/>
</logger>
<!-- 默认配置,级别为debug 且根据name为log.console和 log.file两个appender输出-->
<root>
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>
里面爆红的地方我们可以不进行管理,影响不大。
日志的级别:
FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)
从左到右打印的内容越来越详细
我们运行之后输出的一些日志信息如下所示:
我们可以发现我们当前执行的sql语句,我们当前所传输的参数,我们当前最终所执行的结果。
我们的过程为创建了一个核心配置文件,来配置了连接数据库的环境,然后引入了映射文件。然后我们创建了Mapper接口和映射文件,然后来保证两个一致,首先保证映射文件的namespace与mapper接口的全类名一致,然后映射文件的方法的sql语句的id要与mapper接口中的方法名保持一致。我们就可以在MyBatis面向接口然后来实现sql语句的执行。
我们通过源码来进行分析:
我们在int result = mapper.insertUser();打开断点。我们先进入源码如下所示:
里面的invoke方法就是执行的方法,映射的方法:
我们发现该源码传进去了一个this对象,还有我们当前方法的参数:args.我们发现该方法的底层仍然是找到映射文件,从而去执行SQL语句。
测试修改和删除用户的功能:
我们先在UserMapper里面写如下接口:
//修改用户信息 void updateUser(); //删除用户信息 void deleteUser();
然后我们再映射文件里面编写sql语句:
在mapper标签里面写如下语句
<update id="updateUser"> update t_user set username='root',password='123' where id=3 </update> <delete id="deleteUser"> delete from t_user where id=3 </delete>
完成之后我们进行编写测试类:
由于我们要使用sqlsession对象,我们先将获取的过程进行封装:创建一个静态方法,提供sqlSession对象。
package com.rgf.mybatis.utils; 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.InputStream; public class SqlSessionUtil { public static SqlSession getSqlSession() { SqlSession sqlSession = null; try { //获取核心配置文件的输入流 //此时我们为捕获异常,这个时候要抛的话要抛到调用他的地方。 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //获取SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); //获取SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); //获取Sqlsession对象 sqlSession = sqlSessionFactory.openSession(true); } catch (IOException e) { e.printStackTrace(); } return sqlSession; } }
之后我们编写的测试类如下所示:
@Test public void testUpdate(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateUser(); sqlSession.close(); } @Test public void testDelete(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.deleteUser(); sqlSession.close(); }
我们先运行修改类之后如下所示:
我们运行删除类之后如下所示:
测试查询功能测试:
我们所写的主方法为:
//查询用户信息 //根据id查询用户信息 //根据我们所需要的返回值来确定返回值类型 User getUserById();
下面写我们的映射文件:
<!--resultType:设置结果类型,即查询的数据要转换为的java类型,有相对应的实体类 resultMap:自定义映射,处理多对一或一对多的映射关系,没有相对应的实体类 --> <select id="getUserById" resultType="com.rgf.mybatis.pojo.User"> select * from t_user where id=1 </select>
之后我们将测视类进行编写:
@Test public void testGetUserById(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(); System.out.println(user); sqlSession.close(); }
我们进行查询之后如下所示:
我们进行查询多个数据,我们进行设置接口里面的方法:
//查询所有的用户信息 List<User> getAllUser();
之后我们在映射文件里编写sql语句:
<select id="getAllUser" resultType="com.rgf.mybatis.pojo.User"> select * from t_user </select>
我们编写的测试类如下所示:
@Test public void testGetAllUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> list = mapper.getAllUser(); list.forEach(System.out::println); sqlSession.close(); }
运行之后如下所示:
环境配置文件:environment标签:
<!--environments:配置连接数据库的环境,可以设置多个environment标签,以下为开发环境,我们也可以设置test环境。
属性:
default:设置默认使用的环境的id
>
-->
<environments default="development">
<!--
environment:设置一个具体的连接数据库的环境
属性: id:设置环境的唯一标识,不能重复
-->
<environment id="development">
<!--transactionManger:设置事务管理器
属性:
type:设置事务管理的方式
type="JDBC|MANAGED"
JDBC:表示使用JDBC中原生的事务管理方式(事务提交或回滚,可以手动或自动)
MANAGED:被管理,例如Spring,ioc和aop,aop的重要应用就是声明式事务。
-->
<transactionManager type="JDBC"/>
<!--dataSource与当前连接数据库的连接有关的
设置数据源
属性:
type:设置数据源的类型
type="POOLED|UNPOOLED|JNDI"
POOLED:表示使用数据库连接池
UNPOOLED:表示不使用数据库连接池,每一次在获取连接的时候,都是重新来连接的。
JNDI:表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<!--连接数据库的一些数据:
1.驱动类
2.url,连接地址
3.username:用户名
4.password:密码
-->
核心配置文件properties:
我们创建核心配置文件,如下所示:
我们在resources里面创建Resources bundle文件,如下所示:
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC jdbc.username=root jdbc.password=123456
之后我们修改核心配置文件进行引用:
在<configuration>标签里面
<!--引入properties文件,此后就可以在当前文件中使用${key}的方式来访问value--> <properties resource="jdbc.properties"/>
之后修改如下所示:
<property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/>
之后我们继续进行测试,测试内容如下所示:
核心配置文件之typeAliasese:
可以设置别名:
<!--MyBatis核心配置文件中的标签必须要按照指定的顺序去配置: properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory? --> <!-- typeAliases:设置类型别名,即为某个具体的类型设置一个别名 在MyBatis的范围中,就可以使用别名表示一个具体的类型 --> <typeAliases> <!-- type:设置需要起别名的类型 alias:设置某个类型的别名 我们也可以不用设置alias属性,这样子会有一个默认的类名,且不区分大小写。 --> <typeAlias type="com.rgf.mybatis.pojo.User" alias="abc"></typeAlias> </typeAliases>
设置好别名之后,我们在映射文件里就可以使用别名进行使用:
<select id="getAllUser" resultType="abc"> select * from t_user </select>
我们继续运行之后,仍然如下所示:
当然,我们也可以使用默认名,即当我们没有进行设置alias的时候,有一个默认的别名,即为类名,并且不区分大小写。
我们也可以设置对包的默认名的设置:(由于实体类放在一个包下面)
<!--通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写--> <typeAliases> <package name="com.rgf.mybatis.pojo"/> </typeAliases>
核心配置文件之mappers:
我们发现如上所示:
我们可以通过如下所示指定他的别名:
<typeAlias type="com.rgf.mybatis.pojo.User" alias="abc"></typeAlias>
指定某个类型的别名:
<typeAlias type="com.rgf.mybatis.pojo.User" alias="abc"></typeAlias>
通过包来指定别名:
<!--通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写--> <package name="com.rgf.mybatis.pojo"/>
核心配置文件之mappers标签:
我们创建mapper文件夹,如下所示:
我们在创建过程中,采用directory,过程为com/rgf/mybatis/mapper,这样子创建之后就是一层一层的目录,如下所示:
创建如下所示:
<!--引入mybatis的映射文件--> <mappers> <!--<mapper resource="mappers/UserMapper.xml"/>--> <!--以包的方式引入映射文件,但是必须满足两个条件: 1.mapper接口和映射文件所在的包必须一致 2.mapper接口的名字和映射文件的名字必须一致 --> <package name="com.rgf.mybatis.mapper"/> </mappers>
我们运行之后发现的确在同一个在同一个包下:
我们继续运行之后如下所示:
IDEA创建核心配置文件和映射文件:
我们的核心配置文件的模板如下所示:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"/> <!--MyBatis核心配置文件中的标签必须要按照指定的顺序去配置: properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory? --> <typeAliases> <package name=""/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--引入mybatis的映射文件--> <mappers> <package name=""/> </mappers> </configuration>
命名为mybatis-config.xml.
我们的映射文件的模板如下所示:、
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace=""> </mapper>
我们将该模板命名为mybatis-mapper,