[SSM]MyBatis基础

news2024/11/16 11:53:39

目录

一、MyBatis概述

1.1框架(framework)

1.2三层架构

1.3JDBC的不足

1.4了解MyBatis

二、MyBatis入门程序

2.1resources目录

2.2开发步骤

2.3从XML中构建SqlSessionFactory

2.4mybatis中有两个主要的配置文件

2.5关于第一个程序的细节

2.6关于mybatis的事务管理机制(深度剖析)

2.7单元测试

2.8关于mybatis集成日志组件,让我们调试起来更加方便

2.9MyBatis⼯具类SqlSessionUtil的封装

三、使用MyBatis完成CRUD

3.1什么是CRUD

3.2insert

3.3delete

3.4update

3.5select查询单条记录

3.6select查询所有记录

3.7关于SQL Mapper的namespace

四、MyBatis核心配置文件详解

一、MyBatis概述

1.1框架(framework)

  • Java常用框架:

    • SSM三大框架:Spring+SpringMVC+MyBatis

    • SpringBoot

    • SpringCloud

  • 框架其实就是对通用代码的封装,提前写好了一堆接口和类,我们可以在做项目的时候直接引用这些接口和类,基于这些现有的接口和类进行开发,可以大大提高开发效率。

  • 框架一般都以jar包的形式存在。(jar包中有class文件以及各种配置文件等)

1.2三层架构

  • 表现层(UI):直接跟前端交互(一是接收前端的ajax请求,二是返回json数据给前端)。

  • 业务逻辑层(BLL):一使处理表现层转发过来的前端请求(具体业务),二是将持久化层获取的数据返回到表现层。

  • 数据访问层(DAL):直接完成数据库的CRUD,并将获得的数据返回到上一层(也就是业务逻辑层)。

  • Java的持久层框架:

    • MyBatis

    • Hibernate(实现了JPA规范)

    • jOOQ

    • Guzz

    • Spring Data(实现了JPA规范)

    • Active JDBC

    • ......

1.3JDBC的不足

  • SQL语句写死在Java程序中,不灵活。改SQL的话就要改Java代码。违背了开闭原则OCP。

  • 给?传值是繁琐的,不能自动化。

  • 将结果集封装成Java对象是繁琐的,不能自动化。

1.4了解MyBatis

  • MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。

  • MyBatis在三层架构中复制持久化层,属于持久层框架。

  • ORM:对象关系映射

    • O(Object):Java虚拟机中的Java对象。

    • R(Relational):关系型数据库。

    • M(Mapping):将Java虚拟机中的Java对象映射到数据库表中一行记录,或是将数据库表中一行记录映射成Java虚拟机中的一个Java对象。

  •  

     

  • MyBatis属于半自动化ORM模型,Hibernate属于全自动化的ORM框架。

  • MyBatis框架特点:

    • 支持定制化SQL、存储过程、基本映射以及高级映射。

    • 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集。

    • 支持XML开发,也支持注解式开发。(为了保证sql语句的灵活,所以mybatis大部分是采用XML方式开发)

    • 将接口和Java的POJOs映射成数据库中的记录。

    • 体积小好学:两个jar包,两个XML配置文件。

    • 完全做到SQL解耦合。

    • 提供了基本映射标签、高级映射标签、XML标签,支持动态SQL的编写。

    • ......

二、MyBatis入门程序

2.1resources目录

放到这个目录中的一般都是资源文件、配置文件。

直接放到resources目录下的资源等同于放到了类的根路径下。

2.2开发步骤

  1. 打包方式jar

    <!--打包方式-->
        <packaging>jar</packaging>
  2. 引入依赖:

    • mybatis依赖

    • mysql依赖

      <dependencies>
              <!--mybatis依赖-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.5.11</version>
              </dependency>
      ​
              <!--mysql驱动依赖-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.29</version>
              </dependency>
          </dependencies>

  3. 编写mybatis核心配置文件: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">
<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/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="030522"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--执行XxxMapper.xml文件的路径-->
        <!--resources属性自动会从类的根路径下开始查找资源-->
        <mapper resource="CarMapper.xml"/>
    </mappers>
</configuration>
  1. 编写XxxxMapper.xml文件

    • 在这个文件中编写SQL语句,这个文件名和存放位置也不是固定的。

<?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">
​
<mapper namespace="abc">
    <!--insert语句,id是这条sql语句的唯一标识,这个id就代表了这条sql语句-->
    <insert id="insertCar">
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,'1003','丰田霸道',30.0,'2020-10-10','燃油车')
    </insert>
​
</mapper>
  1. 在mybatis-config.xml文件中指定XxxxMapper.xml文件的路径:<mapper resource="CarMapper.xml"/>

    • 注意:resource属性会自动从类的根路径下开始查找资源。

  2. 编写mybatis程序。(使用mybatis的类库,编写mybatis程序,连接数据库,做crud)

    • 在mybatis当中,负责执行SQL语句的那个对象是SqlSession。

    • SqlSession是专门用来执行SQL语句的,是一个Java程序和数据库之间的一次会话。

    • 要想先获取SqlSession对象,需要先获取SqlSessionFactory对象,通过SqlSessionFactory工厂来生产SqlSession对象。

    • 要想获取SqlSessionFactory对象,需要先获取SqlSessionFactoryBuilder对象,通过SqlSessionFactoryBuilder对象的bulid方法,来获取一个SqlSessionFactory对象。

    • mybatis核心包括:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession

    • SqlSessionFactoryBuilder--->SqlSessionFactory--->SqlSession

2.3从XML中构建SqlSessionFactory

在mybatis中有一个很重要的对象SqlSessionFactory,SqlSessionFactory对象的创建需要XML(配置文件)。

2.4mybatis中有两个主要的配置文件

  • mybatis-config.xml,这个是核心配置文件,主要配置连接数据库的信息等。(只要一个)

  • XxxxMapper.xml,这个文件是专门用来编写SQL语句的配置文件。(一个表对应一个)

2.5关于第一个程序的细节

  • mybatis中的SQL语句的结尾";"可以省略。

  • Resources.getResourceAsStream

    • 以后凡是遇到resource这个单词,大部分情况下,这种加载资源的方式就是从类的根路径下开始加载(查找)。

    • 优点:采用这种方式,从类路径当中加载资源,项目的移植性很强。例如:项目从windows移植到linux,代码不需要修改,因为这个资源文件一直都在类路径当中。

  • InputStream is = new FileInputStream("d:\\mybatis-config.xml");

    • 采用这种方式也可以。

    • 缺点:可移植性太差,程序不够健壮,当移植到其它系统当中,可能导致路径失效,还需要修改java代码中的路径,违背了OCP原则。

  • InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");

    • ClassLoader.getSystemClassLoader() 获取系统的类加载器。

    • 系统的类加载器中有一个方法:getResourceAsStream,它就是从类路径当中加载资源的。

    • InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
      底层就是:InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
  • CarMapper.xml文件的名字和位置不是固定的。

    • <mapper resource="CarMapper.xml"/> resource属性:这种方式是从类路径当中加载资源的。

    • <mapper url="file:///d:/CarMapper.xml"/> url属性:这种方式是从绝对路径当中加载资源的。

2.6关于mybatis的事务管理机制(深度剖析)

  • 在mybtais-config.xml文件中,可以通过<transactionManager type="JDBC">的配置进行mybatis事务的管理。

  • type属性的值包含两个(不包含大小写):JDBC、MANAGED

  • 在mybatis中提供了两种事务管理机制:JDBC事务管理机制、MANAGED事务管理机制

  • JDBC事务管理机制

    • mybatis框架自己管理事务,自己采用原生的JDBC代码去管理事务。

    • conn.setAutoCommit(false);//开启事务
      //...业务处理...
      conn.commit();//手动提交事务
    • 使用JDBC事务管理器的话,底层创建的事务管理器对象:JdbcTransaction

    • SqlSession sqlSession = sqlSessionFactory.openSession(true);
      表示没有开启事务,因为这种方式不会执行:conn.setAutoCommit(false);
      在JDBC事务中,没有执行conn.setAutoCommit(false),那么autoCommit就是true。
      如果autoCommit是true,就表示没有开启事务,只要执行任意一条DML语句就提交一次。
  • MANAGED事务管理器

    • mybatis不再负责事务的管理,事务的管理交给其它容器类执行,例如:spring。

    • 对于目前只有mybatis的情况下,如果配置MANAGED,那么事务就没有人管,没有人管说明事务根本没有开启。

  • 重点:只要autoCommit是true,就表示没有开启事务。只要autoCommit是false,就表示开启了事务。

2.7单元测试

package com.hhb.junit.service;
​
/**
 * 数学业务类
 */
public class MathService {
    /**
     * 求和的业务方法
     *
     * @param a
     * @param b
     * @return
     */
    public int sum(int a, int b) {
        return a + b;
    }
​
    /**
     * 相减的业务方法
     *
     * @param a
     * @param b
     * @return
     */
    public int sub(int a, int b) {
        return a - b;
    }
}
​
package com.hhb.junit.service;
​
import org.junit.Assert;
import org.junit.Test;
​
/**
 * 单元测试类
 */
public class MathServiceTest {//名字规范:类名+Test
​
    //单元测试方法一般一个业务方法对应一个测试方法
    //测试方法规范:public void testXxxx(){}
    //测试方法的方法名:以test开始,testXxx
    //@Test注解非常重要,被这个注解标注的方法就是一个单元测试方法
    @Test
    public void testSum() {
        //单元测试中有两个重要的概念
        //一个是实际值(被测试的业务方法的真正执行结果)
        //一个是期望值(执行了这个业务方法之后,期望的执行结果是多少)
        MathService mathService = new MathService();
        //获取实际值
        int actual = mathService.sum(1, 2);
        //期望值
        int expected = 3;
        //加断言进行测试
        Assert.assertEquals(expected, actual);
    }
​
    @Test
    public void testSub() {
        int actual = new MathService().sub(10, 5);
        int expected = 5;
        Assert.assertEquals(expected, actual);
    }
}
 

2.8关于mybatis集成日志组件,让我们调试起来更加方便

  • mybatis常见的集成的日志组件有哪些?

    • SLF4J(沙拉风):沙拉风是一个日志标准,其中有一个框架叫做logback,它实现了沙拉风规范。

    • LOG4J

    • LOG4J2

    • STDOUT_LOGGING

    • ...

    • 注意:log4j log4j2 logback都是同一个作者开发的。

  • STDOUT_LOGGING是标准日志,mybatis已经实现了这种标准日志,mybatis框架本身已经实现了这种标准,只要开启即可。

    • 在mybatis-config.xml文件中使用settings标签进行配置开启

      <settings>
          <setting name="logImpl" value="STDOUT_LOGGING"/>
      </settings>
    • 这个标签在编写的时候要注意,它应该出现在environments标签之前。

    • 这种实现是可以的,可以看到一些信息,比如:连接对象什么时候创建、什么时候关闭、sql语句是怎样的。但是没有详细的日期、线程名称等,如果想要使用更加丰富的配置,可以集成第三方的log组件。

  • 集成logback日志框架

    • logback日志框架实现了slf4j规范

    • 第一步:引入logback的依赖。

      <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.2.3</version>
      </dependency>
    • 第二步:引入logback所必须的xml配置文件

      • 这个配置文件的名字必须叫做:logback.xml或者logback-test.xml,不能是其它的名字。

      • 这个配置文件必须放到类的根路径下,不能在其它位置。

      • 主要配置日志输出相关的级别以及日志具体的格式。

      <?xml version="1.0" encoding="UTF-8"?>
      ​
      <configuration debug="false">
          <!-- 控制台输出 -->
          <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
              <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                  <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                  <pattern>[%thread] %-5level %logger{50} - %msg%n</pattern>
              </encoder>
          </appender>
      ​
          <!--mybatis log configure-->
          <logger name="com.apache.ibatis" level="TRACE"/>
          <logger name="java.sql.Connection" level="DEBUG"/>
          <logger name="java.sql.Statement" level="DEBUG"/>
          <logger name="java.sql.PreparedStatement" level="DEBUG"/>
      ​
          <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
          <root level="DEBUG">
              <appender-ref ref="STDOUT"/>
              <appender-ref ref="FILE"/>
          </root>
      ​
      </configuration>

2.9MyBatis⼯具类SqlSessionUtil的封装

  • 每一次获取SqlSession对象代码太繁琐,封装一个工具类

package com.hhb.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;
​
/**
 * MyBatis工具类
 */
public class SqlSessionUtil {
    //工具类的构造方法一般都是私有话的
    //工具类中所有的方法都是静态的,直接采用类名即可调用,不需要new对象
    //为了防止new对象,构造方法私有化
    private SqlSessionUtil() {
    }
​
    private static SqlSessionFactory sqlSessionFactory;
​
    //类加载时执行
    //SqlSessionUtil工具类在进行第一次加载的时候,解析mybatis-config.xml文件,创建SqlSessionFactory对象。
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    /**
     * 获取会话对象
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }
}
 
  • 测试工具类

@Test
public void testInsertCar(){
 SqlSession sqlSession = SqlSessionUtil.openSession();
 // 执⾏SQL
 int count = sqlSession.insert("insertCar");
 System.out.println("插⼊了⼏条记录:" + count);
 sqlSession.close();
}

三、使用MyBatis完成CRUD

3.1什么是CRUD

  • C:Create增

  • R:Retrieve查(检索)

  • U:Update改

  • D:Delete删

3.2insert

<insert id="insertCar">
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车');
</insert>
  • 这样写的问题是:值显然写死在配置文件中的,这个在实际开发中是不存在的,一定是前端的form表单提交过来数据,然后将值传给sql语句。

  • 在JDBC中占位符采用的是?,在mybatis中用到是#{},不能使用?占位符。

  • java程序中使用Map可以给SQL语句的占位符传值,一般map集合的key起名的时候要见名知意。

  • #{写map集合的key,如果key不存在,获取的是null}

Map<String,Object> map = new HashMap<>();
map.put("carNum", "1111");
map.put("brand", "比亚迪汉2");
map.put("guidePrice", 10.0);
map.put("produceTime", "2020-11-11");
map.put("carType", "电车");
​
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType});

Java程序中使用POJO类给SQL语句的占位符传值

  • Car car = new Car(null,"3333","比亚迪秦",30.0,"2020-11-13","新能源");
  • 注意:占位符#{},大括号里面写pojo类的属性名

insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
  • 将sql语句换为这种:

    • insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
      values(null,#{xyz},#{brand},#{guidePrice},#{produceTime},#{carType})
    • 会出现的问题:There is no getter for property named 'xyz' in 'class com.hhb.pojo.Car',mybatis去找Car类中的getXyz()方法去了,没有找到就报错。

    • 解决方法:在Car类提供一个getXyz()方法,这样问题就解决了。

  • 通过测试得出结论:严格意义上说,如果POJO对象传递值的话,#{}这个大括号中写的是get方法的方法名去掉get,然后将剩下的单词首字母小写。例如:getUsername()-->#{username}

3.3delete

  • 需求:根据id删除数据

  • 实现:

    • 注意:如果占位符只有一个,那么#{}的大括号里可以随意,但最好是见名知意。

    int count = sqlSession.delete("deleteById", 59);
    <delete id="deleteById">
        delete from t_car where id = #{fdsfd}
    </delete>

3.4update

  • 需求:根据id修改某条记录

  • 实现:

    <update id="updateById">
        update t_car set
             car_num=#{carNum},
             brand=#{brand},
             guide_price=#{guidePrice},
             produce_time=#{produceTime},
             car_type=#{carType}
        where
            id = #{id}
    </update>
        
    Car car = new Car(5L, "9999", "奥迪A7", 60.50, "2021-05-06", "燃油车");
    SqlSession sqlSession = SqlSessionUtil.openSession();
    int count = sqlSession.update("updateById", car);
    System.out.println(count);
    sqlSession.commit();
    sqlSession.close();

3.5select查询单条记录

  • 需求:根据id查询单条记录

  • 实现:

    <select id="selectById" resultType="com.hhb.pojo.Car">
        select * from t_car where id = #{id}
    </select>
    ​
    Object car = sqlSession.selectOne("selectById", 1);
    • 需要特别注意的是:select标签中resultType属性,这个属性告诉mybatis,查询结果集封装成什么类型的java对象。resultType通常写的是全限定类名。

    • 输出结果不完整:

    Car{id=1, carNum='null', brand='宝马520Li', guidePrice=null, produceTime='null', carType='null'}
    • null的原因是:car_num、guide_price、produce_time、car_type这是查询结果的列名。这些列名和Car类中的属性名对不上,Car类的属性名:carNum、guidePrice、produceTime、carType。

    • 解决方案:select语句查询的时候,查询结果集的列名是可以使用as关键字起别名的。

    <select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
        select
            id,car_num as carNum,brand,guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        where
            id = #{id}
    </select>

3.6select查询所有记录

  • 需求:查询所有记录

  • 实现:

    <select id="selectAll" resultType="com.hhb.pojo.Car">
        select
            id,car_num as carNum,brand,guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
    </select>
    @Test
        public void testSelectAll() {
            SqlSession sqlSession = SqlSessionUtil.openSession();
            //List<Object> cars = sqlSession.selectList("selectAll");
            List<Car> cars = sqlSession.selectList("selectAll");
            cars.forEach(car -> System.out.println(car));
            sqlSession.close();
        }
    • 注意:resultType还是指定要封装的结果集的类型。不是指定list类型,是指定list集合中元素的类型。selectList方法:mybatis通过这个方法就可以得知你需要一个List集合,它会自动给你返回一个List集合。

3.7关于SQL Mapper的namespace

  • 在sql mapper.xml文件当中有一个namespace,这个属性是用来指定命名空间的,防止id重复。

  • 在xml文件中:

<mapper namespace="abcdef">
​
    <select id="selectAll" resultType="com.hhb.pojo.Car">
        select id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType from t_car;
    </select>
​
</mapper>
  • 在java程序中:

@Test
    public void testNamespace() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        //正确完整的写法:namespace.id
        List<Car> cars = sqlSession.selectList("abcdef.selectAll");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

四、MyBatis核心配置文件详解

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">
<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/po
wernode"/>
 <property name="username" value="root"/>
 <property name="password" value="root"/>
 </dataSource>
 </environment>
 </environments>
 <mappers>
 <mapper resource="CarMapper.xml"/>
 <mapper resource="CarMapper2.xml"/>
 </mappers>
</configuration>
  • configuration:根标签,表示配置信息

  • environments:环境(多个),以"s"结尾表示复数,也就是说mybatis的环境可以配置多个数据源。

    • default属性:表示默认使用的是哪个环境,default后面填写的是environment的id。default的值只需要和environment的id值一致即可。

  • environment:具体的环境配置(主要包括:事务管理器的配置+数据源的配置)

    • id:给当前环境一个唯一的标识,该标识用在environments的default后面,用来指定默认的环境选择。

  • transactionManager:配置事务管理器

    • type属性:指定事务管理器具体使用什么方式,可选值有两个

      • JDBC:使用JDBC原生的事务管理机制。底层原理:事务开启。

        conn.setAutoCommit(false); ...处理业务...事务提交conn.commit();
      • MANAGED:交给其它容器来管理事务,比如WebLogic、JBOSS等。如果没有管理事务的容器,则没有事务。没有事务的含义:只要执行一条DML语句,则提交一次。

  • dataSource:指定数据源

    • type属性:用来指定具体使用的数据库连接池的策略,可选值包含三个

      • UNPOOLED:采用传统的获取连接的方式,虽然也实现了Javax.sql.DataSource接口,但是没有使用池的思想。

        • property可以是:

          • driver

          • url

          • username

          • password

          • defaultTransactionIsolationLevel 默认的连接事务隔离级别。

          • defaultNetworkTimeout 等待数据库操作完成的默认网络超时时间(单位:毫秒)

      • POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。

        • property可以是(除了包含UNPOOLED中之外):

          • poolMaximumActiveConnections 在任意时间内可存在的活动(正在使用)连接数量,默认值:10

          • poolMaximumIdleConnections 任意时间可能存在的空闲连接数。

          • ......

      • JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。如果不是web或者maven的war工程,JNDI是不能使用的。

        • property可以是(最多只包含以下两个属性):

          • initial_context 这个属性用来在 InitialContext 中寻找上下文

          • data_source 这是引⽤数据源实例位置的上下⽂路径。

  • mappers:在mappers标签中可以配置多个sql映射文件的路径。

  • mapper:配置某个sql映射文件的路径

    • resource属性:使用相对于类路径的资源引用方式

    • url属性:使用完全限定资源定位符(URL)方式

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">
<configuration>
    <!--java.util.Properties类,是一个map集合,key和value都是String类型-->
    <!--在properties标签中可以配置很多属性-->
    <!--<properties>
        <property name="jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis"/>
        <property name="jdbc.username" value="root"/>
        <property name="jdbc.password" value="030522"/>
    </properties>-->
    <!--resource,一定是从类路径下开始查找资源-->
    <properties resource="jdbc.properties" />
​
    <!--从绝对路径当中加载资源-->
    <!--<properties resource="file:///d:/jdbc.properties"/>-->
​
    <!--default表示默认使用的环境-->
    <environments default="mybatis">
​
        <!--其中的一个环境连接的数据库是mybatis-->
        <!--一般一个数据库会对应一个SqlSessionFactory对象-->
        <!--一个环境environment会对应一个SqlSessionFactory对象-->
        <environment id="mybatis">
​
            <!--transactionManager标签:
                1.作用:配置事务管理器,指定mybatis具体使用什么方式来管理事务
                2.type属性有两个值:
                    JDBC:使用原生的JDBC代码来管理事务
                        conn.setAutoCommit(false);
                        ...
                        conn.commit();
                    MANAGED:mybatis不再负责事务的管理,将事务管理交给其它的JEE(Java EE)容器来管理,例如:spring
                3.不区分大小写,只能二选一,不能写其它的值
                4.再mybatis中提供了一个事务管理器接口:transaction
                    该接口下有两个实现类:
                        JdbcTransaction
                        ManagedTransaction
                    如果type="JDBC",那么底层实现JdbcTransaction对象
                    如果type="MANAGED",那么底层实现ManagedTransaction对象
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource配置:
                    1.dataSource被称为数据源
                    2.dataSource作用:为程序提供Connection对象。(只要给程序员提供Connection对象的,都叫做数据源)
                    3.数据源实际上是一套规范,JDK中有这套规范:javax.sql.DataSource
                    4.我们自己也可以编写数据源组件,只要实现javax.sql.DataSource接口中的所有方法就行了。
                    5.常见的数据源组件(数据库连接池):
                        druid、c3p0、dbcp...
                    6.type属性用来指定数据源的类型,就是指定具体使用什么方式来获取Connection对象
                        type属性有三个值,必须是三选一
                        UNPOOLED:不使用数据库连接池技术,每一次请求过来之后,都是创建新的Connection对象。
                        POOLED:使用mybatis自己实现的数据库连接池
                        JNDI:集成其它第三方的数据库连接池
​
                        JNDI是一套规范,大部分的web容器都实现了JNDI规范,例如:Tomcat、Jetty、WebLogic、WebSphere
                        ...这些服务器(容器)都实现了JNDI规范
                        JNDI是java命名目录接口,Tomcat容器实现了这个规范
                        <dataSource type="JNDI">
                            <property name="initial_context" value="..."/>
                            <property name="data_source" value="...."/>
                        </dataSource>
​
            -->
            <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}"/>
                <!--提醒:正常使用连接池的话,池中有很多参数是需要设置的,设置好参数,可以让连接池发挥的更好-->
                <!--具体连接池当中的参数如何配置呢?需要反复的根据当前业务情况进行测试-->
                <!--poolMaximumActiveConnections:连接池当中最多的正在使用的连接对象的数量上限,最多有多少个连接可以活动,默认值是10-->
                <property name="poolMaximumActiveConnections" value="10"/>
                <!--每隔2秒打印日志,并且尝试获取连接对象-->
                <property name="poolTimeToWait" value="2000"/>
                <!--强行让某个连接空闲,超时时间的设置-->
                <property name="poolMaximumCheckoutTime" value="10000"/>
                <!--最多的空闲数量-->
                <property name="poolMaximumIdleConnections" value="5"/>
​
            </dataSource>
        </environment>
​
        <!--这个mybatis的另一个环境,也就是连接的数据库是另一个数据库mybatis02-->
        <environment id="mybatis02">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis02"/>
                <property name="username" value="root"/>
                <property name="password" value="030522"/>
            </dataSource>
        </environment>
        
    </environments>
    <mappers>
        <mapper resource="CarMapper.xml"/>
    </mappers>
</configuration>

configTest.java

package com.hhb.test;
​
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;
​
public class ConfigTest {
​
    @Test
    public void testDataSource() throws IOException {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //sqlSessionFactory对象:一个数据一个,不要频繁创建该对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
​
        /*//通过sqlSessionFactory对象可以频繁开启多个对话
        //会话一
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("car.insertCar");
        sqlSession.commit();
        sqlSession.close();
​
        //会话二
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        sqlSession1.insert("car.insertCar");
        sqlSession1.commit();
        sqlSession1.close();*/
        for (int i=1;i<=4;i++){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            sqlSession.insert("car.insertCar");
        }
    }
​
    @Test
    public void testEnvironment() throws Exception {
        //获取SqlSessionFactory对象(采用默认的方式获取)
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsReader("mybatis-config.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("car.insertCar");
        sqlSession.commit();
        sqlSession.close();
​
        //通过环境id来使用指定的环境
        SqlSessionFactory sqlSessionFactory1 = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "mybatis02");
        SqlSession sqlSession1 = sqlSessionFactory1.openSession();
        int insert = sqlSession1.insert("car.insertCar");
        sqlSession1.commit();
        sqlSession1.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/712023.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux read的核心函数generic_file_buffered_read

内核&#xff1a;5.9.0 流程图 generic_file_buffered_read一种调用路径&#xff08;cat某个文件触发&#xff09;&#xff1a; #0 ondemand_readahead (mapping0xffff888005c61340, ra0xffff888005927598, filp0xffff888005927500, hit_readahead_markerfalse, index0, req…

Linux历史及环境搭建(VMware搭建CentOS7环境以及使用XShell连接Vmware)

Linux历史及环境搭建 1.Linux历史1.1 UNIX发展的历史1.2 Linux发展历史1.2.1 开源1.2.2 官网1.2.3 发行版本 2.VMware配置CentOS7环境2.1 CentOS下载2.2 配置环境2.3 切换国内阿里源2.4 无图形化界面开机2.5 使用XShell连接VMware 结语 1.Linux历史 在这里简要介绍Linux的发展…

全局配置cnpm淘宝镜像

node是一个非常好用的项目管理工具 但这是一个国外的工具 我们直接执行npm命令因为是用的国外的镜像 会比较慢 那么 我们就可以用cnpm来处理 但前提是你要搭建好环境 我们先打开终端 安装 淘宝镜像 输入 npm install -g cnpm --registryhttps://registry.npm.taobao.org然后 n…

最强DETR+YOLO,三阶段目标检测器DEYOv2正式发布,性能炸裂!

导读 目标检测算法是CV领域非常重要的算法,去年二阶段DEYO的发布,提出了很多的创新点,而本文端到端的 论文链接:https://arxiv.org/pdf/2306.09165.pdf 本文提出了一种称为DEYOv2的新型目标检测器,这是第一版DEYO(DETR with YOLO)模型的改进版本。与前代类似,DEYOv2采…

企企通创始人CEO徐辉:数字生态与数字化供应链如何连通

6月16日&#xff0c;2023年华映资本年度大会在杭州成功举办。 2023年华映资本年度大会以“无限新成皆繁星”为主题。在为期一天的峰会中&#xff0c;华映资本合伙人团队、投资团队、华映资本被投企业创始人以及行业嘉宾等50位嘉宾汇聚一堂&#xff0c;既探讨行业当下科技强共识…

硬件可信方案-EVITA HSM

信息安全中的HSM 和 SHE 两个概念有什么区别和相同的地方&#xff1f; HSM&#xff0c;硬件安全模块&#xff0c;Hardware Security ModuleSHE&#xff0c;安全硬件扩展&#xff0c;Secure Hardware Extension EVITA研究项目的目标是为汽车车载网络设计、验证一个体系架构&am…

STM32单片机双通道FM调频数字音量收音机可存台音量可调TEA5767

实践制作DIY- GC0148---双通道FM调频数字音量收音机 基于STM32单片机设计---双通道FM调频数字音量收音机 二、功能介绍&#xff1a; STM32F103C系列最小系统板TEA5767 收音机模块LCD1602显示器喇叭功放模块数字电位器多个按键&#xff08;存储、S1、S2、S3、频率-0.1MHz、频率…

【AUTOSAR】VCU开发实际项目讲解(二)----VCU软件与结构描述

VCU软件描述 VCU软件架构主要分为底层软件驱动和应用层控制策略&#xff0c;其中应用层控制策略通过基于模型的开发&#xff0c;自动生成代码并可与底层驱动软件实现无缝连接。 VCU软件通过BOOTLOADER和CAN总线进行更新刷写。 标定及诊断 支持CCP/XCP标定协议支持UDS诊断协议及…

聊一聊分布式会话的解决方案

1、传统Session 1、传统session的概述 1、认证过程 1、用户向服务器发送用户名和密码。 2、服务器验证通过后&#xff0c;在当前对话&#xff08;session&#xff09;里面保存相关数据&#xff0c;比如用户角色、登录时间等等。 3、服务器向用户返回一个 session_id&#xff…

电子会议桌卡

一、产品描述 采用电子墨水显示屏作为显示屏&#xff0c;取代传统的纸质或LCD铭牌&#xff0c;高科技的外观设计和节能的显示解决方案&#xff0c;结合网络和移动APP&#xff0c;为用户提供更便捷的会议工作服务。 电子铭牌具有环保、节能、操作方便、实用范围广等特点。 本…

MAMP 无法启动 servers 问题

如果你是window10系统,在下载MAMP安装这个软件后,启动,报错,如下所示 [Tue Dec 01 00:52:15 2020] [warn] Init: Session Cache is not configured [hint: SSLSessionCache] [Tue Dec 01 00:52:16 2020] [warn] pid file D:/software/MAMP/bin/apache/logs/httpd.pid overwritt…

深度学习与神经网络

文章目录 引言1. 神经网络1.1 什么是神经网络1.2 神经元1.3 多层神经网络 2. 激活函数2.1 什么是激活函数2.2 激活函数的作用2.3 常用激活函数解析2.4 神经元稀疏 3. 设计神经网络3.1 设计思路3.2 对隐含层的感性认识 4. 深度学习4.1 什么是深度学习4.2 推理和训练4.3 训练的相…

chatgpt赋能python:用Python实现冒泡排序:提高排序算法效率

用Python实现冒泡排序&#xff1a;提高排序算法效率 在计算机科学中&#xff0c;排序算法是一项重要而基础的任务。其中&#xff0c;冒泡排序是最简单、最基础的算法之一。它的思路很简单&#xff1a;将数组中相邻的两个元素进行比较&#xff0c;并根据大小交换位置。通过多次…

篇章十二 Vue3开发

文章目录 Vue3.0Vue带来了什么一、创建Vue3.0工程1、使用 vue-cli 创建2、使用 vite 创建1、创建工程2、分析工程结构2.1、main.js文件中2.2、App.vue文件中 二、常用 Composition API1、Options API 存在的问题2、Composition API 的优势3、常用的Composition API① 拉开序幕的…

Nvidia jetson TX2挂载256gSD卡

ps:在开始之前要做一点儿准备工作&#xff1a;把SD卡插进去&#xff0c;如果插进去了&#xff0c;ubuntu桌面上会显示SD卡&#xff1a; 1. 查看256G硬盘信息 sudo fdisk -lu一般显示的应该是下面这种内容&#xff1a; 2.修改sd卡的模式 sudo mkfs -t ext4 /dev/mmcblk1p1…

Spring Boot 中的负载均衡

Spring Boot 中的负载均衡 负载均衡是分布式系统中非常重要的一个概念&#xff0c;它可以帮助我们将请求分摊到多个服务实例中&#xff0c;从而提高系统的可用性和性能。在 Spring Boot 中&#xff0c;负载均衡通常是通过 Ribbon 实现的。本文将深入探讨 Spring Boot 中的负载…

机器学习第二课(KNN算法)

文章目录 一、介绍KNN1.1 定义1.2 工作流程 二、自实现KNN2.1 问题2.2 步骤 一、介绍KNN 1.1 定义 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别&#xff0c;则该样本也属于这个类别。 涉及到距离的计算&#xff08;欧式距离&…

(43)绞盘

文章目录 前言 43.1 在哪里购买 43.2 连接和配置 43.3 任务期间的控制 43.4 视频 前言 Daiwa winch 是专门为无人机配送设计的高质量绞盘。该绞盘包括一个"线端检测开关"&#xff0c;可防止将线拉得太紧&#xff0c;从而使设备拉伤或断线。绞盘包括一个弹簧装置…

从流处理来深入理解消息队列

大家好&#xff0c;我是 方圆。在《数据密集型应用系统设计》这本书中关于流处理的部分提到了消息队列相关的知识&#xff0c;我觉得它对理解和之后使用消息队列中间件有很大的帮助&#xff0c;遂将其中重要的部分总结出来&#xff0c;但也更推荐大家去看原书&#xff0c;原文收…

一文了解Python中的运算符

目录 &#x1f969;1.1.算数运算符 &#x1f969;1.2.赋值运算符 &#x1f969;1.3.复合赋值运算符 &#x1f969;1.4.比较运算符 &#x1f969;1.5.逻辑运算符 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;Python从入门到精通专栏 P…