IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> MyBatis详细入门教程教程!idea版本 -> 正文阅读

[Java知识库]MyBatis详细入门教程教程!idea版本

来源:动力节点MyBatis教程实战精讲视频及文档,再次表示感谢!!

https://www.bilibili.com/video/BV185411s7Ry?spm_id_from=333.999.0.0&vd_source=75a98c11a89e81de728ed7f28e735d32

本文PDF版下载链接,以及相关资料链接:
链接: https://pan.baidu.com/s/1e4SiPgKqrrv7ekOiX727pA 提取码: wl55

第一章 框架概述

1.1 软件开发常用的结构

1.1.1 三层架构

三层架构包含的三层: 界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)

  1. 界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和 用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。-----> jsp html

  2. 业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。 -----> service

  3. 数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交 给业务层,同时将业务层处理的数据保存到数据库. -----> dao

三层对应的包:

  • controller包 (servlet)

  • service包 (xxxService)

  • dao包(xxxDao)

三层类的交互关系:

? 用户—> 界面层—>业务逻辑层—>数据访问层—>DB 数据库
在这里插入图片描述

为什么要使用三层架构:

  1. 结构清晰、耦合度低, 各层分工明确

  2. 可维护性高,可扩展性高

  3. 有利于标准化

  4. 开发人员可以只关注整个结构中的其中某一层的功能实现

  5. 有利于各层逻辑的复用

三层对应的处理框架

界面层 — servlet — springmvc

业务逻辑层----service—spring

数据访问层— dao ---- mybatis

1.2 框架是什么

1.2.1 框架定义

? 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法 另一种认为,框架是可被应用开发者定制的应用骨架、模板。

? 简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来 说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能

? 框架是安全的,可复用的,不断升级的软件。

1.2.2 框架特点

  1. 不是全能的
  2. 框架是针对某一个邻域有效,特长在某一个方面
  3. 框架是别人写好的程序

1.2.3 框架解决要解决的问题

? 框架要解决的最重要的一个问题是技术整合,在 J2EE 的 框架中,有着各种各样的技术,不同的应 用,系统使用不同的技术解决问题。需要从 J2EE 中选择不同的技术,而技术自身的复杂性,有导致更大的风险。企业在开发软件项目时,主要目的是解决业务问题。 即要求企业负责技术本身,又要求解决业务问题。这是大多数企业不能完成的。框架把相关的技术融合在一起,企业开发可以集中在业务领 域方面。

? 另一个方面可以提高开发的效率。

1.3 为什么要用MyBatis

? 首先先来回顾一下 JDBC 以及 JDBC 存在的问题

1.3.1 JDBC编程方式

? 使用JDBC做一个查询

//STEP 1. 导入相关包
import java.sql.*;

public class SelectRecords {
  //JDBC驱动 和 地址
  static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
  static final String DB_URL = "jdbc:mysql://localhost/jdbc_db";

	//数据库用户名和密码
  static final String USER = "root";
  static final String PASS = "123456";

  public static void main(String[] args) {
    Connection conn = null;
    Statement stmt = null;
    try{
      //STEP 2: 注册JDBC驱动
      Class.forName("com.mysql.jdbc.Driver");

      //STEP 3: 打开一个连接
      System.out.println("Connecting to a selected database...");
      conn = DriverManager.getConnection(DB_URL, USER, PASS);
      System.out.println("Connected database successfully...");

      //STEP 4: 执行一个查询语句
      System.out.println("Creating statement...");
      stmt = conn.createStatement();

      String sql = "SELECT id, name, email, age FROM student";
      ResultSet rs = stmt.executeQuery(sql);
      //STEP 5: 遍历查询结果
      while(rs.next()){
        int id  = rs.getInt("id");
        int age = rs.getInt("age");
        String first = rs.getString("first");
        String last = rs.getString("last");
        System.out.print("ID: " + id);
        System.out.print(", Age: " + age);
        System.out.print(", First: " + first);
        System.out.println(", Last: " + last);
      }
      rs.close();
    }catch(SQLException se){
      //Handle errors for JDBC
      se.printStackTrace();
    }catch(Exception e){
      //Handle errors for Class.forName
      e.printStackTrace();
    }finally{
      //关闭资源
      try{
        if(stmt!=null)
          conn.close();
      }catch(SQLException se){
      }// do nothing
      try{
        if(conn!=null)
          conn.close();
      }catch(SQLException se){
        se.printStackTrace();
      }//end finally try
    }//end try
    System.out.println("Goodbye!");
  }//end main
}//end JDBCExample

1.3.2 JDBC的缺陷

  1. 代码冗余,开发效率低

  2. 需要关注 Connection ,Statement, ResultSet 对象创建和销毁

  3. 对 ResultSet 查询的结果,需要自己封装为 List

  4. 业务代码和数据库的操作混在一起

1.4 MyBatis框架概述

MyBatis 框架: MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。 iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的 持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)

1.4.1 MyBatis框架解决的问题

? 针对JDBC的缺陷,MyBatis减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ; 不用编写关闭资源代码, 直接使用 java 对象;直接表示结果数据,让开发者专注 SQL 的处理。

MyBatis 可以完成

  1. 注册数据库的驱动,例如 Class.forName(“com.mysql.jdbc.Driver”))

  2. 创建 JDBC 中必须使用的 Connection , Statement, ResultSet 对象

  3. 从 xml 中获取 sql,并执行 sql 语句,把 ResultSet 结果转换 java 对象,省略以下语句

List<Student> list = new ArrayLsit<>();
ResultSet rs = state.executeQuery(“select * from student”); 
while(rs.next){
	Student student = new Student(); 
	student.setName(rs.getString(“name”)); 
  student.setAge(rs.getInt(“age”)); 
  list.add(student);
}
  1. 关闭资源

ResultSet.close() , Statement.close() , Conenection.close()

第二章MyBatis框架入门

2.1 入门案例

Ch01-hello-mybatis:第一个入门的mybatis例子

实现步骤:

  1. 新建一个student表
  2. 加入Maven的MyBatis坐标 mysql驱动的坐标
  3. 创建实体类 Student —>对应的表中一行数据
  4. 创建持久层的dao接口,定义操作数据库的方法
  5. 创建一个mybatis使用的配置文件

? 叫做sql映射文件:写sql语句的 一般一个表一个sql映射文件 这个文件是xml文件

? 1) 这个xml写在接口所在的目录中

? 2) 文件名称和接口保持一致

  1. 创建mybatis的主配置文件

? 一个项目就是一个主配置文件

? 主配置文件提供了数据库的连接信息和SQL映射的文件位置信息

  1. 创建使用mybatis类,

? 通过mybatis访问数据库

接下来进行演示:先看一下项目结构
在这里插入图片描述

(1)在数据库中新建一个student表 , springdb库中

CREATE TABLE `student` (
`id` int(11) NOT NULL ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL, 
`age` int(11) DEFAULT NULL, 
PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

向数据库随便添加两行数据,如图:

在这里插入图片描述

(2)加入Maven的MyBatis坐标 mysql驱动的坐标

<dependencies>
    <!--mybatis依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>

    <!--mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>

    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

(3)创建实体类 Student —>对应的表中一行数据

创建domain.Student

package com.st.domain;
import jdk.nashorn.internal.objects.annotations.Setter;

//推荐实体类名和表名一样, 方便记忆
@Data  //使用Lombok
public class Student {

    //属性和表数据一样
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

(4)创建持久层的dao接口,定义操作数据库的方法

创建dao.StudentDao接口,接口中有一个查询方法

package com.st.dao;
import com.st.domain.Student;
import java.util.List;

//接口操作 student表
public interface StudentDao {
    //查询student表的所有数据
    public List<Student> selectStudents();

}

(5)创建一个mybatis的配置文件

? 该文件叫做sql映射文件:写sql语句的 ,一般一个表一个sql映射文件,在此处为StudentDao.xml

? 1.这个xml写在接口所在的目录中

? 2.文件名称和接口保持一致

<?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">  <!-- 这个是约束文件,检查当前文件出现的标签,必须符合mybatis的要求 -->
<mapper namespace="com.st.dao.StudentDao">
    <select id="selectStudents" resultType=>
        select id, name, email, age from student order by id;
    </select
</mapper>

mapper: 当前文件的根标签
namespace: 命名空间,唯一值,可以是自定义的字符串
要求你使用dao接口的全限定名称

select: 表示查询语句

  • id:要执行的sql语句的唯一标识,mybatis会使用这个id值来找到要执行的sql语句,使用接口中的方法名称
  • resultType:表示结果类型的,是sql语句执行后得到Resulset,遍历即可得到java对象的类型

(6)创建mybatis的主配置文件,主配置文件提供了数据库的连接信息和SQL映射的文件位置信息

在resources下创建mybatis.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">

<configuration>
    <!--环境配置:数据库的连接信息
        default:必须和某个environment中的id一样,告诉mybatis使用哪个数据库连接信息,也就是访问哪个数据库-->
    <environments default="development">
        <!--
        一个数据库信息的配置 环境
            id:一个唯一值,自定义,表示环境的名称-->
        <environment id="development">
            <!--
            transactionManager: mybatis的事务类型
                type:JDBC(表示使用jdbc中的Connection对象的commit rollback作为事务处理-->
            <transactionManager type="JDBC"/>
            <!--
            dataSource : 表示数据源,用来连接数据库的
                type:表示数据源的类型,POOLED表示使用连接池
            -->
            <dataSource type="POOLED">
                <!--这些值是固定的的  不能自定义-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/springdb"/>
                <property name="username" value="root"/>
                <property name="password" value="12345678"/>
            </dataSource>
        </environment>

        <!--测试 数据库-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="12345678"/>
            </dataSource>
        </environment>
    </environments>

    <!--最后一步-->
    <!--sql mapper的位置-->
	  <!--一个mapper标签指定一个文件的位置-->
    <mappers>      
        <mapper resource="com/st/dao/StudentDao.xml"/>
    </mappers>

</configuration>

在maven中配置扫描规则,pom中加入:

<!--扫包-->
<build>
  <resources>
    <resource>
      <directory>src/main/java</directory><!--所在的目录-->
      <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
  </resources>
</build>

(7)创建使用mybatis类,通过mybatis访问数据库

在com.st包下创建MyApp类:

package com.st;

import com.st.domain.Student;
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 javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyApp {

    public static void main(String[] args) throws IOException {
        //访问mybatis读取student数据
        //1.定义mybatis主配置文件的名称  从类路径的根开始
        String config = "mybatis.xml";
        //2.读取config表示的文件
        InputStream in = Resources.getResourceAsStream(config);
        //3.创建sqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory = builder.build(in);
        //5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
        SqlSession sqlSession = factory.openSession();
        //6.指定要执行的sql语句的标识  sql映射文件中的namespace + " . " + 标签id值
        String sqlId = "com.st.dao.StudentDao" + "." + "selectStudents";
        //7.执行sql语句,通过sqlId找到语句
        List<Student> studentList = sqlSession.selectList(sqlId);
        //8.输出结果 lambda表达式
        studentList.forEach(student -> System.out.println(student));
        //9.关闭SqlSession对象
        sqlSession.close();

    }
}

运行结果: 访问到了数据库,至此完成了MyBatis入门之旅。
在这里插入图片描述

2.2 增删改查

? 注意:insert update delete方法需要增加一步提交事务操作!

xml文件中:

1.dao对象,类型是StudentDao,全限定名称:com.st.dao.StudentDao
  全限定名称和namespace是一样的。

2.dao调用的方法名称;selectStudents
  方法名称和mapper文件中的id值是一样的

3.通过dao中方法的返回值可以确定MyBatis要调用的SqlSession的方法
  如果返回值是list, 调用SqlSession.selectList()方法
  如果返回值是int, 或是非list,则看mapper文件中的标签是什么

2.2.1 select

在StudentDao中添加方法:

//查
public List<Student> selectStudents();

在StudentDao.xml中添加:

<select id="selectStudents" resultType="com.st.domain.Student">
  select id, name, email, age from student order by id;
</select>

测试代码:

@Test
public void selectStudents() throws IOException {
  String config = "mybatis.xml";
  InputStream in = Resources.getResourceAsStream(config);
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  SqlSessionFactory factory = builder.build(in);
  SqlSession sqlSession = factory.openSession();

  String sqlId = "com.st.dao.StudentDao" + "." + "selectStudents";
  List<Student> studentList = sqlSession.selectList(sqlId);

  studentList.forEach(student -> System.out.println(student));
  sqlSession.close();
}

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

2.2.2 insert

在StudentDao中添加方法:

public int insertStudent(Student student);

在StudentDao.xml中添加:

<insert id="insertStudent">
  insert into student values (#{id}, #{name}, #{email}, #{age});
</insert>

测试代码:

    @Test
    public void insertStudent() throws IOException {
        String config = "mybatis.xml";
        InputStream in = Resources.getResourceAsStream(config);
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        SqlSession sqlSession = factory.openSession();
        //创建要插入的数据
        Student student = new Student();
        student.setId(2001);
        student.setName("孙悟空");
        student.setEmail("swk@xiyou.com");
        student.setAge(500);

        String sqlId = "com.st.dao.StudentDao" + "." + "insertStudent";
        int row = sqlSession.insert(sqlId, student);
        System.out.println("影响行数:" + row);

        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }
}

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

数据库中确实插入成功:

2.2.3 update

在StudentDao中添加方法:

public int updateStudent(Student student);

在StudentDao.xml中添加:

<update id="updateStudent" >
  update student set age = #{age} where id = #{id}
</update>

测试代码:

@Test
public void updateStudent() throws IOException {
  String config = "mybatis.xml";
  InputStream in = Resources.getResourceAsStream(config);
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  SqlSessionFactory factory = builder.build(in);
  SqlSession sqlSession = factory.openSession();

  Student student = new Student();
  student.setId(2001);
  student.setAge(1000);//将年龄更新为1000岁

  String sqlId = "com.st.dao.StudentDao" + "." + "updateStudent";
  int row = sqlSession.update(sqlId, student);
  System.out.println("影响行数:" + row);

  //提交事务
  sqlSession.commit();
  sqlSession.close();
}

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

数据库中确实更新成功:
在这里插入图片描述

2.2.4 delete

在StudentDao中添加方法:

public int insertStudent(Student student);

在StudentDao.xml中添加:

<insert id="insertStudent">
  insert into student values (#{id}, #{name}, #{email}, #{age});
</insert>

测试代码:

@Test
public void deleteStudent() throws IOException {
  String config = "mybatis.xml";
  InputStream in = Resources.getResourceAsStream(config);
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  SqlSessionFactory factory = builder.build(in);
  SqlSession sqlSession = factory.openSession();

  String sqlId = "com.st.dao.StudentDao" + "." + "deleteStudent";
  int row = sqlSession.update(sqlId, 2001);
  System.out.println("影响行数:" + row);
}

测试结果:

在这里插入图片描述

数据库中确实删除成功:
在这里插入图片描述

2.3 日志

? 一个语句是否执行成功,在idea中只能获取影响行数来判断,不能详细的看到每个sql语句执行的具体语句是什么,如果发生错误,不容易排查,为此,可使用日志功能来详细的查看每次运行执行的sql语句信息。

在主配置文件中对增加setting标签,位置在标签内部

<settings>
  <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

未使用日志:
在这里插入图片描述

使用日志:会给出具体的sql语句,方便查找错误
在这里插入图片描述

2.4 主要类的介绍

2.4.1 Resources类

? MyBatis中的一个类,主要负责读取主配置文件或资源文件等,其有很多方法通过加载并解析资源文件,可返回不同类型的 IO 流对象。

2.4.2 SqlSessionFactoryBuilder类

? 通过创建SqlSessionFactoryBuilder,使用SqlSessionFactoryBuilder对象的build() 方法,来进一步创建SqlSessionFactory对象。

? 由于SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将 该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。

2.4.3 SqlSessionFactory接口

? 重量级对象,重量级对象是创建对象耗时比较长,使用资源比较多,在整个项目中,有一个就够用了。

? SqlSessionFactory:本身是一个接口,接口的实现类 DefaultSqlSessionFactory

? SqlSessionFactory作用:通过openSession方法,获取SqlSession对象

openSession方法说明:

  1. openSession():无参数的,默认是false,获取的是非自动提交事务的SqlSession对象
  2. openSession(true):根据参数,获取能否自动提交事务的SqlSession对象

2.4.4 SqlSession接口

? 定义了操作数据的方法,例如selectOne() selectList() insert() update()

SqlSession接口的实现类:DefaultSqlSession

? 使用要求:SqlSession对象不是线程安全的,需要在方法内部使用, 在执行sql语句后需要执行SqlSession.close()来关闭它,避免线程不安全

2.5 创建工具类

? 可以从上文看出,在测试代码中很多代码是重复的,因此可以创建一个工具类,方便代码复用。

2.5.1 创建MyBatisUtil类

? 简而言之,就是将一些公共代码单独做成一个类:
在这里插入图片描述

创建一个utils包,在包下创建MyBatisUtils

public class MyBatisUtils {
  
    private static SqlSessionFactory sessionFactory = null;
    static { //静态代码块,先执行。 创建出sessionFactory
        String config = "mybatis.xml";
        try {
            InputStream in = Resources.getResourceAsStream(config);
            sessionFactory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //获取SqlSession的方法
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = null;
        if(sessionFactory != null){
            sqlSession = sessionFactory.openSession();
        }
        return sqlSession;
    }
}

2.5.1 使用MyBatisUtils类

? 在测试代码中:

    @Test
    public void selectStudents() throws IOException {
//        String config = "mybatis.xml";
//        InputStream in = Resources.getResourceAsStream(config);
//        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        SqlSessionFactory factory = builder.build(in);
        
        SqlSession sqlSession = MyBatisUtils.getSqlSession();  //使用一句即可

        String sqlId = "com.st.dao.StudentDao" + "." + "selectStudents";
        List<Student> studentList = sqlSession.selectList(sqlId);

        studentList.forEach(student -> System.out.println(student));
        sqlSession.close();
    }

第三章 MyBatis框架Dao代理

? 分析前文的代码执行流程,对于一个StudentDao接口中的方法,在测试类中需要先组装好sqlId(1),再通过sqlSession中对应的方法(2)来调用StudentDao.xml中写好的sql语句。

@Test
public void selectStudents() throws IOException 
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  String sqlId = "com.st.dao.StudentDao" + "." + "selectStudents";  //(1)
  List<Student> studentList = sqlSession.selectList(sqlId);        //(2)
  studentList.forEach(student -> System.out.println(student));
  sqlSession.close();
}

? 这个过程,使用者需要知道:①组装sqlid这个字符串 ②需要知道sqlSession中包含什么方法,将sqlid传入对应的方法中。 而我们期望的是,使用者通过StudentDao定义中的方法,并调用该方法就能实现对应的操作。

? 为了实现这个目的,一般传统的Dao开发方式如下文。

3.1 MyBatis使用传统的Dao开发方式

? 传统的开发方式步骤:

  1. 创建一个StudentDao接口
  2. 实现这个SudentDao类 --> StudentDaoImpl,通过SqlSession调用StudentDao.xml
  3. 编写StudentDao.xml方法

接下来,以selectStudents()方法为主:

(1)在StudentDao接口创建selectStudents()方法

public List<Student> selectStudents();

(2)在Dao中创建impl包,在impl包中实现Dao接口类 StudentDaoImpl

public class StudentDaoImpl implements StudentDao {
    @Override
    public List<Student> selectStudents() {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
      	//将test中的代码放入到impl类中
        String sqlId = "com.st.dao.StudentDao.selectStudents";
        List<Student> students = sqlSession.selectList(sqlId);
        sqlSession.close();
        return students;
    }
}

(3)StudentDao.xml是相同的

<mapper namespace="com.st.dao.StudentDao">
    <select id="selectStudents" resultType="com.st.domain.Student">
        select id, name, email, age from student order by  id;
    </select>

测试代码:

@Test
public void testSelect(){
  StudentDao studentDao = new StudentDaoImpl();
	//直接调用Dao接口中的方法即可
  List<Student> students = studentDao.selectStudents();
  students.forEach(student -> System.out.println(student));
}

3.2 传统的开发方式分析

? 在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。

? 所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对 DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。

MyBatis的动态代理:MyBatis根据dao的方法调用,获取执行sql语句的信息. MyBatis通过dao接口,创建一个dao接口的实现类,并创建这个类的对象,也就是MyBatis可以自动创建一个impl类,完成SqlSession的调用,访问数据库

3.3 MyBatis框架Dao代理方式

3.3.1 步骤

  1. 去掉Dao接口的实现类 —> StudentDaoImpl

  2. 通过MyBatis框架来获取代理类对象,也就是MyBatis根据接口,自动生成一个Impl实现类。

  3. 使用获取的Dao实现类来执行sql语句

举例:

(1)去掉Dao接口的实现类 —> StudentDaoImpl

在这里插入图片描述

(2)MyBatis框架中getMapper方法来获取代理类对象

(3)使用获取的Dao实现类来执行sql语句

@Test
public void testSelect(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);  //直接代替了impl类
    List<Student> students = studentDao.selectStudents();            //执行xml中的sql语句
    students.forEach(student -> System.out.println(student));
    sqlSession.close();
}

3.3.2 原理

? 通过Debug方式进行调试,分析原理:

MyBatis通过动态代理的方式试下获取impl类。
在这里插入图片描述

ps:由于本人没有找到文档中图片的源码,只在这里贴出文档代码:

MapperProxy 类定义:
在这里插入图片描述

invoke方法:

在这里插入图片描述

重点方法:

3.3 传入参数

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

3.3.1 parameterType

? 写在mapper文件中的一个属性,用来表示dao接口方法中的参数的数据类型。parameterType它的值是java的数据类型全限定名称或者是mybatis定义的别名。 在实际开发或使用中,使用该属性不多,了解即可

例如StudentDao接口:

public Student selectStudentById(Integer id)

在xml文件中改写:

<mapper namespace="com.st.dao.StudentDao">
    <select id="selectStudentById" parameterType="java.lang.Integer"   resultType="com.st.domain.Student">
        select id, name, email, age from student where id = #{id};
    </select>
</mapper>

? parameterType来告诉mybatis传入的 idInteger类型

3.3.2 传入一个简单类型参数

一个简单类型参数:基本数据类型和String叫做简单类型,注意这种方法的限定 ① 一个 ②简单类型参数

接口代码:

public Student selectStudentById(Integer id)

在mapper文件中获取简单类型的一个参数的值,使用#{任意字符},所以在xml文件中id改为其他字符也可以:

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, 1002);
  1. 执行sql 封装为resultType="com.st.domain.Student"这个对象
ResultSet rs = ps.executeQuery();
Student student = null
while(rs.next()){
  //从数据库取表的一行数据,存到java对象属性中
  Student student = new Student();
  student.setId(rs.getInt("id"));
  student.setName(rs.getInt("name"));
  student.setEmail(rs.getInt("email"));
  student.setAge(rs.getInt("age"));
}
return student; 

注意事项:

? 使用#号是占位符,能够避免sql注入,在 3.3.7 中有提到

3.3.3 多个参数-使用@Param

? 使用@Param命名参数,给参数起名字。

举例:

Dao接口:

public List<Student> selectMulitParam(String name, Integer age)

使用@Param(“参数名”) String name

public List<Student> selectMulitParam(@Param("myname")String name,@Param("myage")Integer age)

可以在mapper文件中:

select id, name, email, age from student where name = #{myname} or age= #{myage};

3.3.4 多个参数-使用对象

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

使用对象语法:

? #{属性名,javaType=类型名称,jdbcType=数据类型} <!--很少用-->

? - javaType:指java中的属性数据类型

? - jdbcType:在数据库中的数据类型

<!--#{paramName, javaType=java.lang.String, jdbcType="varchar"}-->
select id, name, email, age from student where
name = #{paramName, javaType = java.lang.String, jdbcType=VARCHAR} or
age =  #{paramAge, javaType = java.lang.Integer, jdbcType=INTEGER}

可以简化为:#{属性名}

select id, name, email, age from student where name=#{paramName} or age=#{paramAge};

使用对象进行参数传递有两种方式:1)新建类方式 2)实体类方式

第一种方法举例:

(1)新建一个QueryParam类,用于传递参数:

package com.st.vo;
@Data
public class QueryParam {
    private String paramName;
    private Integer paramAge;
}

(2)Dao接口:

//多个参数:使用java对象作为接口中方法的参数
public List<Student> selectMultiObject(QueryParam queryParam);

(3)xml文件:

<select id="selectMultiObject" resultType="com.st.domain.Student">
  select id, name, email, age from student where name=#{paramName} or age=#{paramAge}; <!--传入类中的属性-->
</select>

(4)测试代码:

@Test
public void selectMultiObject() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  //新建QueryParam类,并设置想要传递的参数
  QueryParam zs = new QueryParam();
  zs.setParamName("张三");
  zs.setParamAge(10);
  //将新建QueryParam类的实例,作为参数传入到方法中
  List<Student> studentList = mapper.selectMultiObject(zs);
  studentList.forEach(System.out::println);
  sqlSession.close();
}

(常用)第二种方法举例:

(1)使用已有的Student实体类,用于传递参数

(2)Dao接口:

//多个参数 使用对象:这种方式比较常用
public List<Student> selectMultiStudent(Student student);

(3)xml文件:

<select id="selectMultiStudent" resultType="com.st.domain.Student">
  select id, name, email, age from student where name=#{name} or age=#{age};
</select>

(4)测试代码:

@Test
public void selectMultiStudent() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
	//通过Student类实例完成参数传递
  Student zs = new Student();
  zs.setName("张三");
  zs.setAge(10);
  List<Student> studentList = mapper.selectMultiStudent(zs);
  studentList.forEach(System.out::println);
  sqlSession.close();
}

3.3.5 多个参数-按位置的

? 参数位置从 0 开始, 引用参数语法#{ arg 位置 } ,第一个参数是#{arg0}, 第二个是#{arg1}

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

举例:

(1)Dao接口

//多个参数-按位置
public List<Student> selectByIndex(String name,Integer age);

(2)xml文件:

<!--按位置的-->
  <select id="selectByIndex" resultType="com.st.domain.Student">
  select id, name, email, age from student where name=#{arg0} or age=#{arg1};
</select>

(3)测试代码:

@Test
public void selectByIndex() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  List<Student> studentList = mapper.selectByIndex("张飞", 15);
  studentList.forEach(System.out::println);
  sqlSession.close();
}

3.3.6 多个参数-使用Map

? 开发中,并不常用(了解即可)

(1)Dao接口:

//多个参数-按map
public List<Student> selectByMap(Map<String, Object> map);

(2)xml文件:

<select id="selectByMap" resultType="com.st.domain.Student">
  select id, name, email, age from student where name=#{myname} or age=#{myage};
</select>

(3)测试代码:

@Test
public void selectByMap() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  //在这里构建map, key是xml中的#{}中的名字
  //因此使用者需要知道xml中的源码,因此不常用使用
  Map<String, Object> map = new HashMap<String, Object>();
  map.put("myname", "张飞");
  map.put("myage",15);
  
  List<Student> studentList = mapper.selectByMap(map);
  studentList.forEach(System.out::println);
  sqlSession.close();
}

? 存在问题:

  1. 只能在测试类中,才能给map赋值的问题。

  2. 可读性差,从Dao中并不能获取需要传入什么信息。

3.3.7 #和$的区别

select id,name, email,age from student where id=#{studentId}

===> #号后的结果: select id,name, email,age from student where id=?

? #使用的是PreparedStatement执行sql

select id,name, email,age from student where id=#{studentId}

===> $号后的结果: select id,name, email,age from student where id=1001

? $使用的Statement对象执行sql, 效率比PreparedStatement低。

? : 可 以 替 换 表 名 或 者 列 名 , 你 能 确 定 数 据 是 安 全 的 。 可 以 使 用 :可以替换表名或者列名, 你能确定数据是安全的。可以使用 :使

#和 $区别总结:

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

3.4 封装MyBatis输出结果

3.4.1 resultType

? mybatis执行了sql语句,得到ResultSet转换的类型。

处理方式:

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

resultType结果类型的值可以是:

  1. 类型的全限定名称
  2. 类型的别名, 例如 java.lang.Integer别名是int

注意:

  • 如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
  • resultType可以返回不是一个实体类的对象, 但返回值需要和xml中resultType一样

①新建一个ViewStudent类:

@Data
@ToString
public class ViewStudent {
    private String name;
    private Integer age;
}

②向Dao中添加方法:

//resultType返回给不是一个实体类的对象, 返回值需要和xml中resultType一样
ViewStudent selectStudetnReturnViewStudent(@Param("sid") Integer id);

③xml文件

<select id="selectStudetnReturnViewStudent" resultType="com.st.vo.ViewStudent">
  select id, name, email, age from student where id=#{sid};
</select>

④测试代码

@Test
public void selectStudetnReturnViewStudent() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  ViewStudent student = mapper.selectStudetnReturnViewStudent(1002);
  System.out.println(student.toString());
  sqlSession.close();
}

⑤运行结果:这个类中包括的name 、age属性得到赋值
在这里插入图片描述

  • resultType 和 resultMap,不能同时使用。

  • 可以使用别名进行返回,分为MyBatis已经定义别名和自定义别名

? **别名:**全限定名可以使用mybatis自带的别名代替,或者自定义别名

1)使用MyBatis自带别名,举例:

(1)StudentDao接口中加入方法

public List<Student> selectResultByMyBatis(@Param("myname") String name,
  @Param("myage") Integer age);

(2)StudentDao.xml文件中加入对应的配置

使用全限定名:

<select id="selectResultByMyBatis" resultType="java.lang.Integer">
  select count(*) from student;
</select>

使用自带别名:

<!--<select id="selectResultByMyBatis" resultType="java.lang.Integer">-->
<select id="selectResultByMyBatis" resultType="int">
  select count(*) from student;
</select>

2)使用自定义别名第一种方式:

在主配置文件中定义,使用定义别名

举例:

(1)主配置文件加入:

<typeAliases>
  <typeAlias type="java.lang.Integer" alias="ThisAlias"/>
</typeAliases>

(2)在dao的xml文件中修改

<!--<select id="selectResultByMyBatis" resultType="int">-->
<select id="selectResultByMyBatis" resultType="ThisAlias">
  select count(*) from student;
</select>

3)使用自定义别名第二种方式

? name是包名,这个包中的所有类,类名就是别名(别名不区分大小写)

举例:

(1)主配置文件加入:

<typeAliases>
  <!--<typeAlias type="java.lang.Integer" alias="ThisAlias"/>-->
  <package name="java.lang"/>
</typeAliases>

(2)在dao的xml文件中修改

<select id="selectResultByMyBatis" resultType="Integer">
  select count(*) from student;
</select>

? 但还是建议不要用第二种别名,用全限定名更好,因为不同的包下的同一名字的类,会有歧义性

3.4.2 resultMap

? 结果映射,指定列名和java对象的属性对应关系。

resultMap使用方式:

? 1)先定义resultMap

? 2)在select标签,使用resultMap来引用1定义的

resultMap使用场景:

  1. 自定义列值赋值给指定的属性
  2. 当列名和属性名不一样时,一定要使用resultMap

举例 场景1:

(1)Dao中添加方法:

//使用resultMap定义映射关系
public List<Student> selectAllStudent();

(2)xml方法: 通过标签定义resultMap,将name 和 email互换

<resultMap id="studentMap" type="com.st.domain.Student">
  <!--
            column:列名
            property:java类型的属性名
        -->
  <id column="id" property="id"/>
  <!--非主键列, 使用result--> <!-- 互换一下name 和 email-->
  <result column="name" property="email"/>
  <result column="email" property="name"/>
  <result column="age" property="age"/>
</resultMap>

  <!--此处使用resultMap-->
<select id="selectAllStudent" resultMap="studentMap">
  select id, name, email, age from student
</select>

(3)测试代码:

@Test
public void selectAllStudent() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

  List<Student> studentList = mapper.selectAllStudent();
  studentList.forEach(System.out::println);
  sqlSession.close();
}

(4)运行结果:name 和 email完成互换

在这里插入图片描述

举例 场景2:当列名和属性名不一样时,一定要使用resultMap

(1)在domain中新建一个MyStudent类,属性和Student相同,但是属性名不同。制造出列名和属性名不一样的场景

@Data
public class MyStudent {
    private Integer stuid;
    private String stuname;
    private String stuemail;
    private Integer stuage;
  
    @Override
    public String toString() {
        return "MyStudent{" +
                "stuid=" + stuid +
                ", stuname='" + stuname + '\'' +
                ", stuemail='" + stuemail + '\'' +
                ", stuage=" + stuage +
                '}';
    }
}

(2)xml方法: 通过标签定义方法对应赋值

<resultMap id="myStudentMap" type="com.st.domain.MyStudent">
  <!--对应赋值, id是主键,  result是非主键-->
    <id column="id" property="stuid"/>
    <result column="name" property="stuname"/>
    <result column="email" property="stuemail"/>
    <result column="age" property="stuage"/>
</resultMap>
<!--列名和属性名不一样,第一种方法-->
<select id="selectMyStudent" resultMap="myStudentMap">
    select id, name, email, age from student
</select>

(3)测试代码:

@Test
public void selectMyStudent() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

  List<MyStudent> myStudents = mapper.selectMyStudent();
  myStudents.forEach(System.out::println);
  sqlSession.close();
}

(4)运行结果:

在这里插入图片描述

3.5 模糊查询like的使用

3.5.1 模糊查询第一种方式

? 在java代码中,执行like的内容, 将like的内容通过参数传递

(1)Dao接口:

List<Student> selectLinkeOne(String name);

(2)xml文件:

<!--第一种like-->
<select id="selectLinkeOne" resultType="com.st.domain.Student">
  select id, name, email, age from student where name like #{name}
</select>

(3)测试代码:

@Test
public void selectLinkeOne() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

  String name = "%张%";
  //将要查询的内容通过参数传递
  List<Student> studentList = mapper.selectLinkeOne(name);  
  studentList.forEach(System.out::println);
  sqlSession.close();
}

(4)运行结果:name中含有 张 的行记录被找到

在这里插入图片描述

3.5.2 模糊查询第二种方法

在mapper 文件中拼接 like的内容

(1)Dao接口:

List<Student> selectLinkeTwo(String name);

(2)xml代码:

<select id="selectLinkeTwo" resultType="com.st.domain.Student">
  select id, name, email, age from student where name like "%" #{name} "%" ;  <!--在这里将字符拼接-->
</select>

(3)测试代码:

    @Test
    public void selectLinkeTwo() {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao mapper = sqlSession.getMapper(StudentDao.class);

        String name = "剑";
        List<Student> studentList = mapper.selectLinkeTwo(name);
        studentList.forEach(System.out::println);
        sqlSession.close();
    }

第四章 动态SQL

? 动态sql: sql的内容是变化的,可以根据条件获取到不同的sql语句,主要是where部分发生变化。

? 动态sql的实现:使用的是mybatis提供的标签, ,,

4.1 if标签

是判断条件的,
语法
部分sql语句

举例:

(1)Dao接口:

//在查询中 可能name或者age 不存在 或者数据有错误,  可使用if
List<Student> selectStudentIf(Student student);

(2)xml代码:

<!--if-->
<select id="selectStudentIf"  resultType="com.st.domain.Student">
  <include refid="studentSql"></include>
  where 1 = 1      							<!--这句话要加上,否则如果第一个不满足,会报sql语法错误-->
  <if test="name != null and name != ''">
    and name = #{name}
  </if>
  <if test="age > 0">
    or age > #{age}
  </if>
</select>

(3)测试代码:

@Test
public void selectStudentIf() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  Student student1 = new Student();
  student1.setName("张飞");
  student1.setAge(15);
  List<Student> students = mapper.selectStudentIf(student1);
  students.forEach(student -> System.out.println(student));
  sqlSession.close();

}

(4)运行结果,满足条件的被查找到

在这里插入图片描述

4.2 where标签

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

? 语法 …

举例:

(1)Dao接口:

//where的使用
List<Student> selectStudentWhere(Student student);

(2)xml文件:

<!--where-->
<select id="selectStudentWhere"  resultType="com.st.domain.Student">
  select id, name, email, age from student
  <where>
    <if test="name != null and name != ''">
      and name = #{name}
    </if>
    <if test="age > 0">
      or age > #{age}
    </if>
  </where>
</select>

(3)测试代码:

@Test
public void selectStudentWhere() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);
  Student student1 = new Student();
  student1.setName("张飞");
  //        student1.setAge(15);
  List<Student> students = mapper.selectStudentWhere(student1);
  students.forEach(student -> System.out.println(student));
  sqlSession.close();
}

(4)运行结果:

在这里插入图片描述

4.3 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:集合成员之间的分隔符

举例1:传入的是id,Integer类

(1)Dao接口:

//foreach的使用1
public List<Student> selectForeach(List<Integer> idList);

(2)xml代码:

<!--foreach使用1-->
<select id="selectForeach"  resultType="com.st.domain.Student">
  select id, name, email, age from student where id in 
  <foreach collection="list" item="myid" open="(" close=")" separator=",">
    #{myid}
  </foreach>
</select>

(3)测试代码:

@Test
public void selectForeach() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

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

  List<Student> students = mapper.selectForeach(list);
  students.forEach(student -> System.out.println(student));
  sqlSession.close();
}

(4)运行结果:

在这里插入图片描述

举例2:传入的是类,Student类,用类中的id

(1)Dao接口:

//foreach的使用2
public List<Student> selectForeach2(List<Student> stuList);

(2)xml代码:

<!--foreach使用2-->
<select id="selectForeach2"  resultType="com.st.domain.Student">
  select id, name, email, age from student where id in
  <foreach collection="list" item="stu" open="(" close=")" separator=",">
    #{stu.id}
  </foreach>
</select>

(3)测试代码:

@Test
public void selectForeach2() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

  List<Student> list = new ArrayList<>();
  Student student1 = new Student();
  Student student2 = new Student();
  student1.setId(1003);
  student2.setId(1004);
  list.add(student1);
  list.add(student2);

  //传入的是List<Student>
  List<Student> students = mapper.selectForeach2(list); 
  students.forEach(student -> System.out.println(student));
  sqlSession.close();
}

(4)运行结果:

在这里插入图片描述

4.4 sql代码片段

? sql代码片段, 就是复用一些代码
步骤:

  1. 先定义 sql语句, 表名,字段等
  2. 再使用,

举例:

(1)在xml文件中标签里面,添加:

<!--定义sql片段-->
<sql id="studentSql">
  select id, name, email, age from student
</sql>

(2)标签里面语句,即可服用这些代码,以selectStudentIf()为例:

<!--if-->
  <select id="selectStudentIf"  resultType="com.st.domain.Student">
  <!--select id, name, email, age from student   实现复用-->
  <include refid="studentSql"></include>
  where 1 =1
  <if test="name != null and name != ''">
    and name = #{name}
</if>
  <if test="age > 0">
    or age > #{age}
</if>
  </select>

第五章 MyBatis 配置文件

5.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的主配置文件,使用 指定文件的位置
在需要使用值的地方, ${key}

5.2 主配置文件的一些标签

? 看一份主配置文件都有什么

<?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">

<configuration>

    <properties resource="jdbc.properties"/>
  
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <package name="java.lang"/>
    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
    
    <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>

    <mappers>
        <mapper resource="com/st/dao/StudentDao.xml"/>
    </mappers>
</configuration>
  1. xml文件,需要在头部使用约束文件
  2. 根元素
  3. 文件主要包含内容:
  • 定义别名
  • 数据源
  • mapper文件

5.2.1 transactionManager

MyBatis提交事务 回滚事务的方式

? type:事务的处理类型

? 1)JDBC:表示mybatis底层使用jdbc中Connection对象 commit rollback

? 2)MANAGED:把mybatis事务处理委托给其他的容器 (一个服务器软件 一个框架spring)

5.2.2 dataSource

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

? type:指定数据源的类型

? 1)POOLED:使用连接池,mybatis会创建PooledDataSource类

? 2)UPOOLED:不适用连接池,在每次执行sql语句,先创建连接,执行sql,再关闭连接

? mybatis会创建一个UnpooledDataSource来管理连接池

? 3)JNDI:java命名和目录服务(Windows注册表)

5.2.3 typeAliases 别名

Mybatis 支持默认别名,我们也可以采用自定义别名方式来开发,主要使用在<select resultType="别名"> mybatis.xml 主配置文件定义别名
<typeAliases>
		<!-- 第一种方式 -->
    <typeAlias type="java.lang.Integer" alias="ThisAlias"/>
  
    <!-- 第二种方式 -->
    <package name="java.lang"/>
</typeAliases>

5.3 指定多个mapper

第一种方式:

? 写多个

第二种方式:使用包名

? name : xml文件所在的包名

注意:

  1. mapper文件名称需要和接口名称一样,区分大小写

  2. mapper文件和dao接口需要在同一个目录

5.4 注意事项 !! 在xml写sql语句时候,没有结束的语句,别添加分号 不然可能会出错。

第六章 PageHelper

? PageHelper是一个通用的分页插件,支持多种数据库

  1. Oracle

  2. Mysql

  3. MariaDB

  4. SQLite

  5. Hsqldb

  6. PostgreSQL

  7. DB2

  8. SqlServer(2005,2008)

  9. Informix

  10. H2

  11. SqlServer2012

  12. Derby

  13. Phoenix

6.1 使用步骤

使用PageHelper实现分页步骤

(1)pom文件中,加入Maven坐标

<!--pageHelper-->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.3.0</version>
</dependency>

(2)主配置文件中,加入插件

<!--配置插件-->
<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

(3)调用PageHelper方法

@Test
public void selectAllByPageHelper() {
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudentDao mapper = sqlSession.getMapper(StudentDao.class);

  //加入pagehelper分页设置
  //pageNum : 第几页,从1开始
  //pageSize: 一页有多少行数据

  PageHelper.startPage(1, 3);
  List<Student> students = mapper.selectAllByPageHelper();
  students.forEach(student -> System.out.println(student));
  sqlSession.close();
}

(4)运行结果,结果只显示前3条信息

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-20 22:54:28  更:2022-06-20 22:57:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:00:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码