Mybatis基础入门笔记

一、软件开发常用结构

1.1 三层架构

 界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。(jsp ,html ,servlet)用户看到的界面。
 业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据。(完成相关的业务逻辑)
 数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等的。


 三层对应的包
   界面层: controller包 (servlet)
   业务逻辑层: service 包(XXXService类)
   数据访问层: dao包(XXXDao类)


 三层中类的交互
   用户使用界面层--> 业务逻辑层--->数据访问层(持久层)-->数据库(mysql)

在这里插入图片描述

 在spring框架中,三层对应的处理框架
   界面层---servlet---springmvc(框架)
   业务逻辑层---service类--spring(框架)
   数据访问层---dao类--mybatis(框架)---->代替JDBC

为什么要使用三层?

  • 结构清晰、耦合度低, 各层分工明确(界面与逻辑代码分离开)
  • 可维护性高,可扩展性高
  • 有利于标准化
  • 开发人员可以只关注整个结构中的其中某一层的功能实现
  • 有利于各层逻辑的复用

1.2 框架

简单的说,框架其实就是半成品软件(模板),就是一组组件,供你快速搭建你的系统,在框架基础上加入你要完成的功能。另外,框架是安全的,可复用的,不断升级的软件。

框架是一个模块

  • 框架中定义好了一些功能。这些功能是可用的。
  • 可以在项目中加入自己的功能, 这些功能可以利用框架中写好的功能。

框架特点:

  • 框架一般不是全能的, 不能做所有事情
  • 框架是针对某一个领域有效。 特长在某一个方面,比如mybatis做数据库操作强,但是他不能做其它的。
  • 框架是一个软件

1.1.1 回顾 JDBC 编程

jdbc代码:

package com.xzz;

import com.xzz.domain.Student;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class a {
    @Test
    public void findStudent() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //注册 mysql 驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //连接数据的基本信息 url ,username,password
            String url = "jdbc:mysql://localhost:3306/student?characterEncoding=utf8&useSSL=false&serverTimezone = UTC";
            String username = "root";
            String password = "123456";
            //创建连接对象
            conn = DriverManager.getConnection(url, username, password);
            //保存查询结果
            List<Student> stuList = new ArrayList<>();
            //创建 Statement, 用来执行 sql 语句
            stmt = conn.createStatement();
            //执行查询,创建记录集,
            rs = stmt.executeQuery("select * from student");
            while (rs.next()) {
                Student stu = new Student();
                stu.setId(rs.getInt("id"));
                stu.setName(rs.getString("name"));
                stu.setAge(rs.getInt("age"));
                //从数据库取出数据转为 Student 对象,封装到 List 集合
                stuList.add(stu);
            }
            System.out.println("查询结果:"+ "\n"+stuList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭资源
                if (rs != null){
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

1.1.2 使用 JDBC 的缺陷

  • 代码比较多,开发效率低
  • 需要关注 Connection ,Statement, ResultSet 对象创建和销毁
  • 对 ResultSet 查询的结果,需要自己封装为 List
  • 重复的代码比较多些
  • 业务代码和数据库的操作混在一起

1.3 mybatis框架

一个操作数据库的框架,早期叫做ibatis, 代码在github。mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架),是一个基于 Java 的持久层框架。
1)sql mapper :sql映射可以把数据库表中的一行数据映射为一个java对象。一行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据。

2) Data Access Objects(DAOs) : 数据访问 , 对数据库执行增删改查。

mybatis提供了哪些功能:

  1. 提供了创建Connection ,Statement, ResultSet的能力 ,不用开发人员创建这些对象
  2. 提供了执行sql语句的能力, 不用你执行sql
  3. 提供了循环sql,把sql的结果转为java对象, List集合的能力。不需要开发人员手动去写下列的代码。
	  while (rs.next()) {
		Student stu = new Student();
		stu.setId(rs.getInt("id"));
		stu.setName(rs.getString("name"));
		stu.setAge(rs.getInt("age"));
		//从数据库取出数据转为 Student 对象,封装到 List 集合
		stuList.add(stu);
	  }
  1. 提供了关闭资源的能力,不用你关闭Connection, Statement, ResultSet。

开发人员做的是: 提供sql语句,mybatis自动处理sql,并得到List集合或java对象(表中的数据)

总结:

  • mybatis是一个sql映射框架,提供了数据库的操作能力,是增强的JDBC。
  • 使用mybatis让开发人员关注写sql就可以了,不必关心Connection,Statement,ResultSet 的创建,销毁以及sql的执行、处理返回结果。这些工作由mybatis自动处理完成。

二、MyBatis 框架快速入门

搭建mybatis开发环境:

  • 创建mysql数据库和表

  • 创建Maven工程

  • 加入相关依赖

  • 加入maven插件

  • 编写实体类

  • 编写Dao接口,定义方法

  • 编写Dao接口对应的mapper文件

  • 创建mybatis主配置文件

  • 创建测试类,测试mapper文件里面的方法

  • 配置日志功能(可选)

    2.1 主要类的介绍

    在这里插入图片描述

1) Resources: mybatis中的一个类, 负责读取主配置文件
InputStream in = Resources.getResourceAsStream(“mybatis.xml”);
2) SqlSessionFactoryBuilder : 创建SqlSessionFactory对象。
//创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);

3)SqlSessionFactory : 重量级对象, 程序创建这一个对象耗时比较长,使用资源比较多。在整个项目中,有一个就够用了。

 SqlSessionFactory:接口  , 接口实现类: DefaultSqlSessionFactory
  SqlSessionFactory作用: 获取SqlSession对象。SqlSession sqlSession = factory.openSession();

  SqlSession中的openSession()方法说明:
   1.openSession() :无参数的, 获取是非自动提交事务的SqlSession对象
	2.openSession(boolean): openSession(true)  获取自动提交事务的SqlSession. 
	                         openSession(false)  非自动提交事务的SqlSession对象

4)SqlSession:
SqlSession接口 :定义了操作数据库的方法,例如 selectOne() ,selectList() ,insert(),update(), delete(), commit(), rollback()等与操作数据库有关的方法。 SqlSession接口的实现类DefaultSqlSession。

注意:

  • 使用要求: SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句之前,使用openSession()获取SqlSession对象。
  • 在执行完sql语句后,需要关闭它,执行SqlSession.close(). 这样能保证他的使用是线程安全的。

2.2 工具类的使用

为什么要使用工具类,我们先来看看没有使用工具类的情况下,实现的代码:
在这里插入图片描述

我们可以看到,在执行SQL语句前,需要引入mybatis配置文件,以及创建可以执行SQL语句的对象,这些操作在以后的各个业务方法中都是必要的,且重复的。为了让这些代码能够在多个业务方法中能够复用,我们可以将这部分可重复使用的代码抽离到一个文件中,再要使用的地方在调用即可,减少冗余的代码,提高性能,也提高程序的可读性。

2.2.1 创建 MyBatisUtil 类

在这里插入图片描述

2.3 传统的DAO使用方式

使用 Dao 的实现类,操作数据库

2.3.1 创建 Dao 接口实现类

在该类中实现接口中的方法,这里展示select方法。在这里插入图片描述
测试方法:
在这里插入图片描述

2.3.2 传统 Dao 开发方式的分析

从前面例子中可以看出,自定义 Dao 的实现类仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。

2.4 使用动态代理的条件

对传统的DAO进行分析:

List<Student> studentList  = dao.selectStudents(); 调用
1.dao对象,类型是StudentDao,全限定名称是:com.xzz.dao.StudentDao
  全限定名称 和 namespace 是一样的。

2.方法名称, selectStudents, 这个方法就是 mapper文件中的 id值 selectStudents
通过dao.selectStudents就相当于找到mapper文件中对应的SQL语句,这也就相当于StudentDaoImpl里面对应的sqlId。所以mybatis可以通过这条链路知道要执行select方法还是insert方法。

3.通过dao中方法的返回值也可以确定MyBatis要调用的SqlSession的方法
   如果返回值是List ,调用的是SqlSession.selectList()方法。
   如果返回值 int ,或是非List的, 看mapper文件中的 标签是<insert>,<update> 就会调用
   SqlSession的insert, update等方法

 mybatis的动态代理: mybatis根据 dao的方法调用,获取执行sql语句的信息。
    mybatis根据你的dao接口,创建出一个dao接口的实现类, 并创建这个类的对象。
    完成SqlSession调用方法, 访问数据库。

2.5 MyBatis 框架 Dao 代理

2.5.1 Dao 代理实现 CURD

步骤:
1)去掉 Dao 接口实现类
2)getMapper 获取代理对象
只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值。

SqlSession session = factory.openSession();
StudentDao dao = session.getMapper(StudentDao.class);

使用工具类:

StudentDao studentDao =
MyBatisUtil.getSqlSession().getMapper(StudentDao.class);

3)使用 Dao 代理对象方法执行 sql 语句
在这里插入图片描述

三、动态代理

动态代理: 使用SqlSession.getMapper(dao接口.class) 获取这个dao接口的对象

3.1 传入参数

从java代码中把数据传入到mapper文件的sql语句中。

3.1.1 parameterType

parameterType: 写在mapper文件中的 一个属性。 表示dao接口中方法参数的数据类型。它的值是java的数据类型全限定名称或者是mybatis定义的别名。

  例如StudentDao接口
 public Student  selectStudentById(Integer id) 

那么parameterType可以是:
	parameterType="java.lang.Integer" 或 parameterType="int"

通过parameterType告诉mybatis在查询时,参数id是个整型值。

注意:parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数类型。所以可以没有。 一般我们也不写。

3.1.2 一个简单类型的参数:

   	 简单类型: mybatis把java的基本数据类型和String都叫简单类型。在mapper文件获取简单类型的一个参数的值,使用 #{任意字符}
接口:public Student  selectStudentById(Integer id) 
		  mapper:select id,name, email,age from student where id=#{studentId}

使用#{}之后, mybatis执行sql是使用jdbc中的PreparedStatement对象
由mybatis执行下面的代码:
 1. mybatis创建Connection , PreparedStatement对象
    String sql="select id,name, email,age from student where id=?";
    PreparedStatement pst = conn.preparedStatement(sql);
    pst.setInt(1,1001);

 2. 执行sql封装为resultType="com.xzz.domain.Student"这个对象
    ResultSet rs = ps.executeQuery();
    Student student = null;
    while(rs.next()){
       //从数据库取表的一行数据, 存到一个java对象属性中
       student = new Student();
       student.setId(rs.getInt("id));
       student.setName(rs.getString("name"));
       student.setEmail(rs.getString("email"));
       student.setAge(rs.getInt("age"));
    }

   return student;  //赋给了dao方法调用的返回值

注意: PreparedStatement对象的优点是,效率高,速度快,防止sql注入,建议使用#作为占位符传参。

在这里插入图片描述
在这里插入图片描述

3.1.3 多个参数,使用@Param命名参数(掌握)

当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。

  接口 public List<Student> selectMulitParam(@Param("myname") String name, @Param("myage") Integer age)
  使用  @Param("参数名")  String name 
    mapper文件:
     <select>
            select * from student where name=#{myname} or age=#{myage}
	  </select>

在这里插入图片描述

在这里插入图片描述

3.1.4 多个参数,使用java对象。语法 #{属性名} (掌握)

使用 java 对象传递参数时, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。

语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 }
javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。

常用格式 #{ property }, javaType, jdbcType的值mybatis反射能获取,可以省略。

接口文件:
在这里插入图片描述

mapper 文件:
格式有以下两种,一般省略javaType=string,jdbcType=VARCHAR。

<select id="selectMultiObject" resultType="com.xzz.domain.Student">
	select id,name,email,age from student where name=#{queryName} or age
=#{queryAge}
</select>
或
<select id="selectMultiObject" resultType="com.xzz.domain.Student">
	select id,name,email,age from student where name=#{queryName,javaType=string,jdbcType=VARCHAR} or age =#{queryAge,javaType=int,jdbcType=INTEGER}
</select>

在这里插入图片描述

测试类:
在这里插入图片描述

   vo: value object , 放一些存储数据的类。比如说 提交请求参数, name ,age 
	     现在想把name ,age 传给一个service 类。

   vo: view object , 从servlet把数据返回给浏览器使用的类,表示显示结果的类。

   pojo: 普通的有set, get方法的java类。 普通的java对象

		  Servlet --- StudentService( addStudent( MyParam  param)  )

   entity(domain域): 实体类, 和数据库中的表对应的类, 
     

3.1.5 使用参数位置传参 (了解)

多个参数都是简单类型的,可按位置传值。参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}

接口 文件:
在这里插入图片描述
mapper文件:
在这里插入图片描述

测试类:
在这里插入图片描述
结果:
在这里插入图片描述

注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

3.1.6 使用Map传值 (了解)

Map集合可以存储多个值,使用Map向mapper文件一次传入多个参数。Map集合使用String的key,Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。

接口文件:
在这里插入图片描述

mapper文件:
在这里插入图片描述

测试类:
在这里插入图片描述

注意: 缺点就是map中的key值是自定义的,如果map可以改了,mapper文件中的参数值位置的名字也要改,这样SQL语句和业务代码耦合度就高了。同时,map传参,也无法知道参数的类型是什么,参数有多少个,可读性差。不建议使用。

3.2 # 和 $

# :占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法。

在这里插入图片描述

$:字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。

1、select id,name, email,age from student where id=#{studentId}
# 的结果: select id,name, email,age from student where id=? 


2、select id,name, email,age from student where id=${studentId}
$ 的结果:select id,name, email,age from student where id=1001

String sql="select id,name, email,age from student where id=" + "1001";
使用的Statement对象执行sql, 效率比PreparedStatement低。

$:可以替换表名或者列名, 或者你能确定数据是安全的可以使用$。
在这里插入图片描述

# 和 $区别

  • #使用 ?在sql语句中做占位的, 使用的是PreparedStatement执行sql,效率高
  • #能够避免sql注入,更安全。
  • $不使用占位符,是字符串连接方式,使用的是Statement对象执行sql,效率低
  • $有sql注入的风险,缺乏安全性。
  • $:可以替换表名或者列名

3.3 mybatis的输出结果

mybatis执行了sql语句,得到java对象。
在这里插入图片描述

3.3.1 resultType

resultType: 结果类型, 指sql语句执行完毕后, 数据转为的java对象, java类型是任意的。

A. 简单类型
简单类型就是SQL返回的类型是简单类型的,比如说int,string等。
测试文件:
在这里插入图片描述
mapper文件:
在这里插入图片描述
像上面这种返回表中学生人数的就是简单类型。

注意:
resultType结果类型的值:
1. 类型的全限定名称 2. 类型的别名, 例如 java.lang.Integer别名是int

B. 对象类型:就是返回的类型是对象类型,例如下列测试用例中返回的是实体类Student的类型就是对象类型

测试文件:
在这里插入图片描述
mapper文件:
在这里插入图片描述
我们可以看到不管dao调用SQL语句执行后返回的是实体类类型,还是List类型,returnType都是实体类型,因为List<Student>是把SQL查询的结果按照实体类对应的属性名封装成Student类型的,然后再放到List集合里面,而不是封装成List。所以这可以看出,returnType是支持java任意类型的。也就是说,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。

处理方式:

  • mybatis执行sql语句, 然后mybatis调用类的无参数构造方法,创建对象。
  • mybatis把ResultSet指定列值赋给同名的属性。

简单来说:
就是使用无参构造方法创建对象,然后调用 setXXX 给属性赋值。
Student student = new Student();

sql语句列 java 对象方法
id setId( rs.getInt(“id”) ) 调用列名对应的 set 方法
id 列 --- setId()
name 列 --- setName()
name setName( rs.getString(“name”) )
email setEmail( rs.getString(“email”) )
age setAge( rs.getInt(“age”) )

<select id="selectMultiPosition" resultType="com.bjpowernode.domain.Student">
       select id,name, email,age from student
</select>

  对等的jdbc
  ResultSet rs = executeQuery(" select id,name, email,age from student" )
  while(rs.next()){
            Student  student = new Student();
			student.setId(rs.getInt("id"));
			student.setName(rs.getString("name"))
  }

C. map类型:SQL语句返回值是map类型。当sql 的查询结果作为 Map 的 key 和 value时,推荐使用 Map<String,Object>。

注意:Map 作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于一条记录是错误。

在这里插入图片描述
在这里插入图片描述
返回map用的比较少,一般是返回对象比较多。

3.3.2 定义自定义类型的别名

定义自定义类型的别名

  • 在mybatis主配置文件中定义,使<typeAlias>定义别名
  • 可以在resultType中使用自定义别名

mybatis主配置文件:
第一种方式:
在这里插入图片描述
第二种方式:
在这里插入图片描述
在这里插入图片描述
一般第二种方式是常用的别名定义。但是还是比较推荐使用全限定名称,比较安全。因为有可能指定包下,有可能会出现同名的类,使用别名的话,就难以区分是哪一个。

mapper文件:
在这里插入图片描述
测试类:
在这里插入图片描述

运行测试类的结果还是一样:
在这里插入图片描述

3.3.3 resultMap

resultMap:结果映射, 指定列名和java对象的属性对应关系。原来是将列名直接赋值给java对象的同名属性,要是你不想将类名赋值给同名属性的话就可以使用returnMap。能更灵活的把列值赋值给指定属性。

使用方式:

  • 先定义 resultMap,指定列名和属性的对应关系。
  • 在<select>中把 resultType 替换为 resultMap。

使用场景:

  • 你自定义列值赋值给哪个属性
  • 当你的列名和属性名不一样时,一定使用resultMap

第一种场景:定义列值赋值给哪个属性
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

从结果中可看到,已经将name列的值复制给了Java对象中的email属性。

第二种场景:列名和属性名不一样
在这里插入图片描述
第一种方式是使用returnMap,第二种方式使用returnType,要注意区分。

注意:

  • resultMap和resultType不要一起用,二选一
  • returnMap的映射关系是可以复用的,只要在其他查询中使用returnMap指定映射关系中定义的id名,就可以直接复用。

3.3.4 模糊 like 的两种方法

模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”

第一种方式:java代码中指定like要匹配的内容
在这里插入图片描述
在这里插入图片描述
第二种方式:在 mapper 文件 sql 语句的条件位置加上“%”
在这里插入图片描述
在这里插入图片描述

四、动态sql

动态sql: sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。

动态sql的实现,使用的是mybatis提供的标签,例如<if> ,<where>,<foreach>,来对条件作出判断以实现动态拼接 SQL 语句。

4.1 if标签

<if>是判断条件的,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
语法:
<if test=“判断java对象的属性值”>
部分sql语句
</if>
在这里插入图片描述

4.2 where标签

<where> 用来包含 多个<if>的, 当多个if有一个成立的, <where>会自动增加一个where关键字, 并去掉 if中多余的 and ,or等。

<if/>标签的不足就是需要在 where 后手工添加 1=1 的子句。因为,若 where 后的所有<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,此时SQL会出错。所以,在 where 后,添加永为真的子句 1=1,以防止这种情况的发生。但当数据量很大时,会
严重影响查询效率。

使用<where/>标签的好处:
在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加where 子句。需要注意的是,第一个<if/>标签中的 SQL 片断,可以不包含 and。不过,写上 and 也可以,系统会将多余的 and 去掉。但其它<if/>中 SQL 片断的 and必须写上,否则 SQL 语句将拼接出错。
在这里插入图片描述

4.3 forEach标签

<foreach> 循环java中的数组,list集合的。 主要用在sql的in语句中。

    学生id是 1001,1002,1003的三个学生

	 select * from student where id in (1001,1002,1003)

	 public List<Student> selectFor(List<Integer> idlist)

	 List<Integer> list = new ...
	 list.add(1001);
	 list.add(1002);
	 list.add(1003);

	 dao.selectFor(list)

语法:
	 <foreach collection="接口中方法参数的类型" item="数组或集合成员的变量" open="开始的字符" close="结束的字符" separator="成员之间的分隔符">
             #{xxx}
    </foreach>

注意:
collection:表示接口中的方法参数的类型, 如果是数组使用array , 如果是list集合使用list
item:自定义的,表示数组或集合成员的变量
open:循环开始是的字符
close:循环结束时的字符
separator:集合成员之间的分隔符

第一种使用方式:遍历 List<简单类型>,可以用<if>标签来判断list是否为空(list !=null and list.size > 0 ),来动态添加where子句。
在这里插入图片描述
在这里插入图片描述
第二种方式:遍历 List< 对象类型>

在这里插入图片描述

在这里插入图片描述

4.4 动态SQL代码段

sql代码片段:就是复用一些SQL语句,通过<sql/>标签定义 SQL 片断,以便其它 SQL 标签复用该代码段。而其它标签使用该 SQL 片断时,需要使用<include/>子标签。该<sql/>标签可以定义 SQL 语句中的任何部分,因此<include/>子标签可以放在动态 SQL的任何位置。

使用步骤:

  • 先定义 <sql id=“自定义名称(唯一)”> sql语句, 表名,字段等
  • 再使用<include refid=“id的值” />在这里插入图片描述
    在这里插入图片描述

五、MyBatis 配置文件

5.1 主配置文件

前面的项目中使用的 mybatis.xml 就是主配置文件。

主配置文件特点:
1) 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">

2)根元素<configuration>
3)主要包含内容:

  • 定义别名
  • 数据源
  • mapper 文件

5.2 dataSource 标签

Mybatis 中访问数据库,可以使用连接池技术,但它采用的是自己的连接池技术。在 Mybatis 的 mybatis.xml配置文件中,通过来实现 Mybatis 中连接池的配置。

5.2.1 dataSource 类型

Mybatis 将数据源分为三类:

  • UNPOOLED 不使用连接池的数据源
  • POOLED 使用连接池的数据源
  • JNDI 使用 JNDI 实现的数据源

在这里插入图片描述
我们在DataSource上Ctrl+H,可以看到DataSource的实现类有上图中的三个。其中 UNPOOLED ,POOLED 数据源实现了 javax.sq.DataSource 接口, JNDI 和前面两个实现方式不同,了解即可。

5.2.2 dataSource 配置

在 MyBatis.xml 主配置文件,配置 dataSource:
MyBatis 在初始化时,根据<dataSource>的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

在这里插入图片描述

5.3 事务

5.3.1 默认需要手动提交事务

Mybatis 框架是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的事务管理机制,即通过 Connection 的 commit()方法提交,通过 rollback()方法回滚。但默认情况下,MyBatis 将自动提交功能关闭了,改为了手动提交。即程序中需要显式的对事务进行提交或回滚。另外,Connection 对象是通过 setAutoCommit()方法来设置事务提交方式的,分为自动提交和手工提交。
在这里插入图片描述
<transactionManager type=“JDBC”/>该标签用于指定MyBatis所使用的事务管理器。MyBatis支持两种事务管理器类型:JDBC 与MANAGED。

5.3.2 自动提交事务

设置自动提交的方式,factory 的 openSession() 分为有参数和无参数的。有参数为 true,使用自动提交,可以修改 MyBatisUtil 的 getSqlSession()方法中的session = factory.openSession(true)语句,再执行sql操作(主要是insert,update,delete操作)时,就无需执行 session.commit()进行事务提交了,此时是自动提交。
在这里插入图片描述

5.4 使用数据库属性配置文件

1.数据库的属性配置文件: 把数据库连接信息放到一个单独的文件中。 和mybatis主配置文件分开。目的是便于修改,保存,处理多个数据库的信息。

1)在resources目录中定义一个属性配置文件, xxxx.properties ,例如 jdbc.properties
在属性配置文件中, 定义数据,格式是 key=value
key: 一般使用 . 做多级目录的。
例如 jdbc.mysql.driver , jdbc.driver, mydriver
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql//…
jdbc.username=root
jdbc.password=123456

在这里插入图片描述

2)在mybatis的主配置文件,使用<property> 指定文件的位置,并在需要使用值的地方, 通过${key}来指定相关的信息。
在这里插入图片描述
在这里插入图片描述

5.5 mappers (映射器)

mapper文件是用来定义SQL语句的,通过在mybatis主配置文件中引入mapper文件,相当于这些SQL操作都由mybatis来管理,在业务代码中我们直接调用指定的方法名就可以自动创建SQL语句,传值,执行SQL,并把结果封装成对应的java类型再返回。开发人员只需关注SQL语句的编写,再在业务代码中调用即可,无需关注SQL语句的定义,传值等操作。

定义mapper文件的映射关系,有两种方法:

1.<mapper resource=" " />
使用相对于类路径的资源,从 classpath 路径查找文件
例如:<mapper resource=“com/bjpowernode/dao/StudentDao.xml” />

该方式引入mapper文件有个缺点,就是一个mapper标签对应一个文件,文件多的时候需要一个个的引入,而且还要写出完整的路径,如果写错的话,调用就会失败。

2.mapper文件,使用package指定路径

 <mappers>

    <!--第二种方式: 使用包名
        name: xml文件(mapper文件)所在的包名, 这个包中所有xml文件一次都能加载给mybatis
        使用package的要求:
         1. mapper文件名称需要和接口名称一样, 区分大小写
         2. mapper文件和dao接口需要在同一目录
    -->
    <package name="com.xzz.dao"/>
</mappers>

六、PageHelper

PageHelper是做数据分页的。

6.1 Mybatis 通用分页插件

PageHelper是Mybatis 通用的分页插件,要使用PageHelper进行页面分页,需要先到https://github.com/pagehelper/Mybatis-PageHelper下载jar包。(如果使用maven添加依赖的话,无需自己下载)

PageHelper 支持多种数据库:

  • Oracle
  • Mysql
  • MariaDB
  • SQLite
  • Hsqldb
  • PostgreSQL
  • DB2
  • SqlServer(2005,2008)
  • Informix
  • H2
  • SqlServer2012
  • Derby
  • Phoenix

6.2 基于 PageHelper 分页的实现步骤

1.在pom.xml文件中引入依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

2.加入 plugin 配置

//在<environments> 之前加入
<plugins>
	<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>

该插件就相当于过滤器。

3.PageHelper 对象
查询语句之前调用 PageHelper.startPage 静态方法。除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法。在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个 MyBatis 查询方法会被进行分页处理。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/victory_CEO/article/details/115139605