【MyBatis】| MyBatis概述、MyBatis⼊⻔程序

news2024/11/19 10:25:19

一、MyBatis概述

1. 框架

在⽂献中framework被翻译为框架。
Java常⽤框架:
SSM三⼤框架:Spring + SpringMVC + MyBatis
SpringBoot
SpringCloud等。。。。
框架其实就是对通⽤代码的封装,提前写好了⼀堆接⼝和类,我们可以在做项⽬的时候直接引⼊这些接⼝和类(引⼊框架),基于这些现有的接⼝和类进⾏开发,可以⼤⼤提⾼开发效率。
框架⼀般都以jar包的形式存在。(jar包中有class⽂件以及各种配置⽂件等)
SSM三⼤框架的学习顺序:MyBatis、Spring、SpringMVC(建议)

2. 三层架构

表现层(UI):直接跟前端打交互(⼀是接收前端ajax请求,⼆是返回json数据给前端)
业务逻辑层(BLL):⼀是处理表现层转发过来的前端请求(也就是具体业务),⼆是将从持久层获取的数据返回到表现层。
数据访问层(DAL):直接操作数据库完成CRUD,并将获得的数据返回到上⼀层(也就是业务逻辑层)。
注:MyBatis属于持久层的框架!

3. JDBC不⾜

案例一:我们在写JDBC代码时会发现:sql语句是写死的;并且如果对于一个很多字段的表进行insert操作,很有很多繁琐重复的代码
// sql语句写死在java程序中
String sql = "insert into t_user(id,idCard,username,password,birth,gender,
email,city,street,zipcode,phone,grade) values(?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);

// 繁琐的赋值:思考⼀下,这种有规律的代码能不能通过反射机制来做⾃动化。
ps.setString(1, "1");
ps.setString(2, "123456789");
ps.setString(3, "zhangsan");
ps.setString(4, "123456");
ps.setString(5, "1980-10-11");
ps.setString(6, "男");
ps.setString(7, "zhangsan@126.com");
ps.setString(8, "北京");
ps.setString(9, "⼤兴区凉⽔河⼆街");
ps.setString(10, "1000000");
ps.setString(11, "16398574152");
ps.setString(12, "A");
// 执⾏SQL
int count = ps.executeUpdate();
// ......
案例二:在执行查询语句时,对于结果集的数据遍历获取到过程是很繁琐的,并且我们如果还需要给获取到的数据封装到对象里,也是一个繁琐的过程
// sql语句写死在java程序中
String sql = "select id,idCard,username,password,birth,gender,email,city,s
treet,zipcode,phone,grade from t_user";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
List<User> userList = new ArrayList<>();

// 思考以下循环中的所有代码是否可以使⽤反射进⾏⾃动化封装。
while(rs.next()){
 // 获取数据
 String id = rs.getString("id");
 String idCard = rs.getString("idCard");
 String username = rs.getString("username");
 String password = rs.getString("password");
 String birth = rs.getString("birth");
 String gender = rs.getString("gender");
 String email = rs.getString("email");
 String city = rs.getString("city");
 String street = rs.getString("street");
 String zipcode = rs.getString("zipcode");
 String phone = rs.getString("phone");
 String grade = rs.getString("grade");
 // 创建对象

 User user = new User();
 // 给对象属性赋值
 user.setId(id);
 user.setIdCard(idCard);
 user.setUsername(username);
 user.setPassword(password);
 user.setBirth(birth);
 user.setGender(gender);
 user.setEmail(email);
 user.setCity(city);
 user.setStreet(street);
 user.setZipcode(zipcode);
 user.setPhone(phone);
 user.setGrade(grade);
 // 添加到集合

 userList.add(user);
}
// ......
总结JDBC不⾜:
①SQL语句写死在Java程序中,不灵活。改SQL的话就要改Java代码,违背开闭原则OCP。
②给?传值是很繁琐的,能不能⾃动化?
③将结果集封装成Java对象是繁琐的,能不能⾃动化?

4. 了解MyBatis

(1)MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。
(2)MyBatis在三层架构中负责持久层的,属于持久层框架。
(3)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)。
(4)ORM:对象关系映射
O(Object):Java虚拟机中的 Java对象
R(Relational):关系型数据库
M(Mapping):将Java虚拟机中的Java对象 映射到数据库表中⼀⾏记录,或是将数据库表中⼀⾏记录映射成Java虚拟机中的⼀个Java对象。
(5)MyBatis框架就是一个ORM框架:
MyBatis是一个半自动化的ORM,因为MyBatis框架中SQL语句是需要程序员自己编写的
Hibernate框架是一个全自动化的ORM,使用Hibernate框架的时候不需要程序员手动编写SQL语句,SQL语句可以自动生成。
MyBatis框架特点:
①⽀持定制化 SQL、存储过程、基本映射以及⾼级映射
②避免了⼏乎所有的 JDBC 代码中⼿动设置参数以及获取结果集
③⽀持XML开发,也⽀持注解式开发。【为了保证sql语句的灵活,所以mybatis⼤部分是采⽤XML⽅式开发】
④将接⼝和 Java 的 POJOs(Plain Ordinary Java Object,简单普通的Java对象)映射成数据库中的记录
⑤体积⼩好学:两个jar包,两个XML配置⽂件。
⑥完全做到sql解耦合。
⑦提供了基本映射标签,提供了⾼级映射标签。
⑧提供了XML标签,⽀持动态SQL的编写。

二、MyBatis⼊⻔程序

    • MyBatis下载

从github上下载,地址:https://github.com/mybatis/mybatis-3
将框架以及框架的源码都下载下来,下载框架后解压,打开mybatis⽬录
通过以上解压可以看到,框架⼀般都是以jar包的形式存在,我们接下来学习mybatis使⽤maven,所以这个jar我们不需要。

2. MyBatis⼊⻔程序开发步骤

2.1 数据库表的设计

准备数据库表:汽⻋表t_car,字段包括:
①id:主键(⾃增)【bigint】
②car_num:汽⻋编号【varchar】
③brand:品牌【varchar】
④guide_price:⼚家指导价【decimal类型,专⻔为财务数据准备的类型】
⑤produce_time:⽣产时间【char,年⽉⽇即可,10个⻓度,例如:'2022-10-11'】
⑥car_type:汽⻋类型(燃油⻋、电⻋、氢能源)【varchar】

使⽤navicat for mysql⼯具建表

使⽤navicat for mysql⼯具向t_car表中插⼊两条数据,如下:

2.2 配置Maven环境

(1)选择JDK

File->Project Structure->Project

(2)设置自己的Maven

file--settings ---Build, Excution,Deployment--Build Tools--Maven

2.3 入门程序步骤

(1)resources目录

放在这个目录当中的,一般都是资源文件,配置文件。
直接放到resources目录下的资源,等同于放到了类的根路径下!

(2)开发步骤

第一步: 打包方式jar:<packaging>jar</packaging>
第二步: 引入依赖:mybatis依赖 和mysql驱动依赖,从远程仓库 mvnrepository.com中查找
<!--引入依赖-->
    <dependencies>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>
        <!--mysql驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.23</version>
        </dependency>
    </dependencies>
查看中文文档 https://mybatis.net.cn/ ,了解接下来的步骤;从 XML 中构建 SqlSessionFactory,通过阅读官方文档这句话,可以得到:
①在MyBatis中一定是有一个很重要的对象,这个对象是:SqlSessionFactory对象。
②SqlSessionFactory对象的创建需要XML(一个配置文件,从官方文档复制)。
第三步:编写mybatis核心配置文件:mybatis-config.xml
注意:①这个文件名不是必须叫做mybatis-config.xml,只是大家都采用这个名字。
②这个文件存放的位置可以随意,但一般情况下,会放到类的根路径下(resources目录下)。
<?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.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
mybatis中实际上有两个主要的配置文件:
其中一个是:mybatis-config.xml,这是核心配置文件,主要配置连接数据库的信息等。(一个)
另一个是:XxxxMapper.xml,这个文件是专门用来编写SQL语句的配置文件。(一个表一个)
例如:t_user表,一般会对应一个UserMapper.xml
t_student表,一般会对应一个StudentMapper.xml
第四步:编写XxxxMapper.xml文件,在这个配置文件当中编写SQL语句!
这个文件放的位置也不是固定,这里给它起个名字,叫做:CarMapper.xml,把它暂时放到类的根路径下。
<?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">

<!--namesapce先随便写一个名字-->
<mapper namespace="first">
    <!--编写sql语句,id是这条sql语句的唯一表示-->
    <insert id="insertCar">
      insert into t_car(id,car_num,id,guide_price,produce,car_type)
      values(null,'1003','丰田',30.0,'2020-10-11','燃油车')
    </insert>
</mapper>
第五步:在核心配置文件mybatis-config.xml文件中指定XxxxMapper.xml文件的路径:
<mapper resource="CarMapper.xml"/>
注意:resource属性会自动从类的根路径下开始查找资源!
<?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.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--关联CarMapper.xml配置文件-->
        <mapper resource="CarMapper.xml"/>
    </mappers>
</configuration>
第六步:编写Mybatis程序(使用mybatis的类库,编写mybatis程序,连接数据库,做增删改查)
①在MyBatis当中,负责执行SQL语句的那个对象叫做 SqlSession,SqlSession是专门用来执行SQL语句的,是一个Java程序和数据库之间的一次会话。
②要想获取SqlSession对象,需要先获取SqlSessionFactory对象,通过SqlSessionFactory工厂来生产SqlSession对象。
③怎么获取SqlSessionFactory对象呢?需要首先获取SqlSessionFactoryBuilder对象。
通过SqlSessionFactoryBuilder对象的build()方法,来获取一个SqlSessionFactory对象。
④总结mybatis的核心对象包括:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession
SqlSessionFactoryBuilder --> 创建出SqlSessionFactory --> 创建出SqlSession
package com.bjpowernode.mybatis.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 javax.annotation.Resource;
import java.io.InputStream;

public class MyBatisIntroductionTest {
    public static void main(String[] args) throws Exception{
        // 1、获取SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 2、获取SqlSessionFactory对象
        // 需要一个指向核心配置文件mybatis-config.xml的io流
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        // 一般情况下:一个数据库对应一个SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        // 3、获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 4、执行sql语句
        // 参数是sql语句的id
        int count = sqlSession.insert("insertCar");
        System.out.println("插入了"+count+"数据");
        // 5、需要手动提交
        sqlSession.commit();
    }
}

执行结果:正常插入数据

细节总结:
①mybatis中sql语句的结尾";"可以省略。
②Resources.getResourceAsStream,以后凡是遇到resource这个单词,大部分情况下,这种加载资源的方式就是从类的根路径下开始加载。(开始查找)
优点:采用这种方式,从类路径当中加载资源,项目的移植性很强。项目从windows移植到linux,代码不需要修改,因为这个资源文件一直都在类路径当中。
③通过自己new的方式InputStream is = new FileInputStream("d:\\mybatis-config.xml");这种方式获取IO流。
缺点:可移植性太差,程序不够健壮;可能会移植到其他的操作系统当中,导致以上路径无效,还需要修改java代码中的路径,这样违背了OCP原则。
mybatis核心配置文件的名字,不一定是:mybatis-config.xml,可以是其它名字。mybatis核心配置文件存放的路径,也不一定是在类的根路径下,可以放到其它位置。但为了项目的移植性,健壮性,最好将这个配置文件放到类路径下面。
⑤InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");也可以通过这种方式获取IO流,ClassLoader.getSystemClassLoader() 是获取系统的类加载器;通过源代码分析发现:InputStream is = Resources.getResourceAsStream("mybatis-config.xml");底层的源代码其实就是:InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
CarMapper.xml文件的名字和CarMapper.xml文件的路径都不是固定的。
<mapper resource="CarMapper.xml"/> resource属性:这种方式是从类路径当中加载资源。
也可以使用url属性表示从绝对路径当中加载资源,语法格式:fille:///绝对路径,例如:
<mapper url="file:///d:/CarMapper.xml"/> 。

(3)Mybatis的事务管理机制深度剖析

①在mybatis-config.xml文件中,可以通过以下的配置进行mybatis的事务管理
<transactionManager type="JDBC"/>
type属性的值包括两个:JDBC(jdbc)、MANAGED(managed),不区分大小写。
②在mybatis中提供了两种事务管理机制:
第一种:JDBC事务管理器
第二种:MANAGED事务管理器
③JDBC事务管理器:
mybatis框架自己管理事务,自己采用原生的JDBC代码去管理事务;
获取SqlSession对象时,SqlSession sqlSession = sqlSessionFactory.openSession(); 如果使用事务管理器JDBC,底层实际上会执行:conn.setAutoCommit(false);
手动提交sqlSession.commit(); 如果使用事务管理器JDBC,底层实际上会执行conn.commit()
④使用JDBC事务管理器的话,底层创建的事务管理器对象:JdbcTransaction对象。但是如果编写代码:SqlSession sqlSession = sqlSessionFactory.openSession(true);传了参数true表示没有开启事务;因为这种方式压根不会执行:conn.setAutoCommit(false)!
⑤在JDBC事务中,如果没有执行conn.setAutoCommit(false);那么autoCommit就是true。如果autoCommit是true,就表示没有开启事务,只要执行任意一条DML语句就提交一次!
⑥MANAGED事务管理器:
mybatis不再负责事务的管理了,事务管理交给其它容器来负责,例如:spring。对于我们当前的单纯的只有mybatis的情况下,如果配置为:MANAGED,那么表示事务这块是没人管的,没有人管理事务表示事务压根没有开启,自己执行一条语句就会自动提交。
注意:只要你的autoCommit是true,就表示没有开启事务;只有你的autoCommit是false的时候,才表示开启了事务!

(4)第一个完整的MyBatis程序

package com.bjpowernode.mybatis.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 java.io.IOException;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.mybatis.test
 * @Project:mybatis
 * @name:MybatisCompleteTest
 * @Date:2022/12/28 20:36
 */
public class MybatisCompleteTest {
    public static void main(String[] args) {
        SqlSession sqlSession = null;
        try {
            // SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            // 获取SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsReader("mybatis-config.xml"));
            // 获取SqlSession对象(开启事务)
            sqlSession = sqlSessionFactory.openSession();
            // 执行sql
            int count = sqlSession.insert("insertCar");
            if (count == 1){
                System.out.println("成功插入数据");
            }
            // 提交事务(事务提交)
            sqlSession.commit();
        } catch (IOException e) {
            // 回滚事务
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            e.printStackTrace();
        } finally {
            // 关闭会话
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}

(5)使用junit插件进行单元测试

①先在pom.xml当中引入单元测试的依赖
②测试的类名:测试的类名+Test
③测试方法的方法名:以test开始;假设测试的方法是sum,这个测试方法名:testSum
④加上@Test注解,@Test注解非常重要,被这个注解标注的方法就是一个单元测试方。
⑤单元测试中有两个重要的概念:
一个是:实际值(被测试的业务方法的真正执行结果)
一个是:期望值(执行了这个业务方法之后,你期望的执行结果是多少)
⑥加断言进行测试,Assert.assertEquals(期望值, 实际值);
<dependencies>   
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
</dependencies>
⑦当我们有多个类要测试的话,如果使用上述main方法的形式,就需要写很多个类,多个main方法,比较麻烦!所以我们可以使用junit单元测试的形式,只写一个类(在test/java下),通过定义方法来测试,不需要写mian方法也能执行!
package com.bjpowernode.mybatis.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 CarMapperTest {
    @Test
    public void testInsert(){
        SqlSession sqlSession = null;
        try {
            // SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            // 获取SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsReader("mybatis-config.xml"));
            // 获取SqlSession对象(开启事务)
            sqlSession = sqlSessionFactory.openSession();
            // 执行sql
            int count = sqlSession.insert("insertCar");
            if (count == 1){
                System.out.println("成功插入数据");
            }
            // 提交事务(事务提交)
            sqlSession.commit();
        } catch (IOException e) {
            // 回滚事务
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            e.printStackTrace();
        } finally {
            // 关闭会话
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}

2.4 Mybatis集成日志框架logback

(1)mybatis常见的集成的日志组件有哪些呢?
SLF4J(沙拉风):沙拉风是一个日志标准,有一个框架叫做logback,它实现了沙拉风规范。
LOG4J
LOG4J2
STDOUT_LOGGING
....
(2)其中STDOUT_LOGGING是标准日志,mybatis已经实现了这种标准日志;不需要引入任何的依赖,只要开启即可。怎么开启呢?在mybatis-config.xml文件中使用settings标签进行配置开启。
①这个标签在编写的时候要注意,它应该出现在environments标签之前;注意顺序!因为有dtd文件进行约束,我们只要参考dtd约束的范围即可。
②这种实现方式可以看到一些信息,比如:连接对象什么时候创建,什么时候关闭,sql语句是怎样的;但是没有详细的日期,线程名字等。如果想使用更加丰富的配置,可以集成第三方的log组件。
<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
(3)集成logback日志框架。
logback日志框架实现了SLF4J标准。(沙拉风:日志文件,日志标准)
①第一步:mybatis-config.xml文件中使用settings标签进行配置SLF4J
注意:也可以不用配,只有使用mybatis内置的日志文件STDOUT_LOGGING,这个才必须要配置!
<settings>
        <setting name="logImpl" value="SLF4J"/>
</settings>
②第二步:引入logback的依赖。
<dependency>
     <groupId>ch.qos.logback</groupId>
     <artifactId>logback-classic</artifactId>
     <version>1.2.11</version>
</dependency>
③第三步:引入logback所必须的xml配置文件。
这个配置文件的名字必须叫做:logback.xml或者logback-test.xml,不能是其它的名字。
这个配置文件必须放到类的根路径下,不能是其他位置。
这个配置文件主要配置日志输出相关的级别以及日志具体的格式。
<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="false">
    <!--定义⽇志⽂件的存储地址-->
    <property name="LOG_HOME" value="/home"/>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示⽇期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:⽇志消息,%n是换⾏符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%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.5 MyBatis⼯具类SqlSessionUtil的封装

(1) 工具类的构造方法一般都是私有化的,防止创建对象。
(2)对于SqlSessionFactory对象,一个SqlSessionFactory对应一个environment,一个environment对应一个数据库,所以我们不需要把它放到方法里,应该放到静态代码块里,类加载时获取到qlSessionFactory对象。
package com.bjpowernode.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;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.mybatis.utils
 * @Project:mybatis
 * @name:SqlSessionUtils
 * @Date:2022/12/29 14:11
 */
public class SqlSessionUtils {
    // 防止创建对象
    public SqlSessionUtils() {
    }
    // 在静态代码块里获取SqlSessionFactory对象
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 定义一个方法,获取会话对象
    public static SqlSession openSession(){
        return sqlSessionFactory.openSession();
    }
}
(3)使用自己编写的工具类,进行测试
package com.bjpowernode.mybatis.test;

import com.bjpowernode.mybatis.utils.SqlSessionUtils;
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 CarMapperTest {
    @Test
    public void testInsertCarByUtil(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        int count = sqlSession.insert("insertCar");
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }   

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

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

相关文章

Frida零基础入门教程

阅读这篇文章,不仅能了解frida是什么,还能知道如何搭建Frida运行换以及学会用frida进行简单的java/native hook实战。 Xposed大家不陌生,在手机上运行的Hook框架,Xposed插件编写完成并在手机上通过hook框架加载,打开指定应用就能实现代码注入,也就是说Xposed插件的代码是…

FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务,展示在浏览器上。

0、本文中所用软件下载包 1、前置工作 1.1 下载 ffmpeg&#xff0c;Download FFmpeg&#xff0c; 1.1.1配置ffmpeg如下图 1.1.2测试ffmpeg 安装成功&#xff1a;ffmpeg -version 1.1.3 使用FFmpeg获取本地摄像头设备 ffmpeg -list_devices true -f dshow -i dummy video和aud…

【JavaSE】Java到底是值传递还是引用传递?

【JavaSE】Java到底是值传递还是引用传递&#xff1f; 文章目录【JavaSE】Java到底是值传递还是引用传递&#xff1f;一&#xff1a;基本数据类型和引用数据类型区别二&#xff1a;案例1&#xff1a;传递基本类型2&#xff1a;传递引用类型三&#xff1a;引用传递是怎么样的&am…

【Linux】进程信号万字详解(下)

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…

搞账号登录限制?我直接用Python自制软件

前言 一个账号只能登录一台设备&#xff1f;涨价就涨价&#xff0c;至少还能借借朋友的&#xff0c;谁还没几个朋友&#xff0c;搞限制登录这一出&#xff0c;瞬间不稀罕了 这个年头谁还不会点技术了&#xff0c;直接拿python自制一个可以看视频的软件… 话不多说&#xff0…

【尚硅谷】Java数据结构与算法笔记05 -递归

文章目录一、应用场景二、递归的概念三、递归能解决的问题四、递归需要遵守的重要规则五、递归-迷宫问题六、递归-八皇后问题&#xff08;回溯算法&#xff09;6.1 问题介绍6.2 思路分析5.3 Java代码实现一、应用场景 二、递归的概念 简单的说: 递归就是方法自己调用自己, 每次…

[机器视觉]目标检测评价指标及其实现

一、模型分类目标 数据的分类情况为两类正例(Postive)和负例(Negtive)&#xff0c;分别取P和N表示。 同时在预测情况下&#xff0c;分类正确表示为T(True)&#xff0c;错误表示为F(False);便有了以下四类表示&#xff1a; TP:(True Positive 正确的判断为正例 …

投入式水位计工作原理及应用介绍

1、设备介绍&#xff1a; 投入式水位计采用国外进口传感器芯体&#xff0c;将液位压力信号转换成对应的数字信号&#xff0c;再通过数字电路处理&#xff0c;输出 RS485 两线制的标准信号。一体式设计是将隔离式传感器和数字处理电路封装在探头内&#xff0c;通过特种电缆直接…

前端性能优化(八):性能优化问题指南

目录 一&#xff1a;从输入 URL 到页面加载显示完成都发生了什么 二&#xff1a;首屏加载优化 三&#xff1a;JavaScript 内存管理 一&#xff1a;从输入 URL 到页面加载显示完成都发生了什么 UI 线程会判断输入的地址地址是搜索的关键词还是访问站点的 URL 接下来 UI 线程…

[数据结构] 详解链表(超详细)

链表可是很重要的知识,是面试时常考的知识点,这次让我们系统的学习一下吧 文章目录1. 链表的定义2. 链表的创建2.1 基础创建2.2 尾插法创建头节点2.3 头插法3. 链表的基础方法3.1 获取链表长度3.2 是否包含某个节点3.3 在任意坐标处插入节点3.4 删除第一个值为key的节点3.5 删除…

【qsort函数实现】

前言&#xff1a; 首先在进行讲解之前&#xff0c;我们先进行对函数的一些相关介绍&#xff0c;方便大家更好的理解它。 目录函数介绍函数实现函数介绍 第一步&#xff1a; 我们可以先查询知道函数的使用方法&#xff1a; void qsort (void* base, size_t num, size_t size,i…

二级路由器的设置上网

设置步骤 &#xff08;简单记录一下&#xff09; 前提条件&#xff1a;一级路由器网络正常&#xff0c;这里主要是使用 lan 口&#xff0c;需要确保各个 lan 口正常&#xff0c;我家里是移动公司的路由器&#xff0c;有一个 lan 端口专门给电视用的&#xff0c;选择它来接二级…

ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-5-01:片上资源详解

【源码、文档、软件、硬件、技术交流、技术支持&#xff0c;入口见文末】 【所有相关IDE、SDK和例程源码均可从群文件免费获取&#xff0c;免安装&#xff0c;解压即用】 持续更新中&#xff0c;欢迎关注&#xff01; 前面《ZigBee 3.0实战教程-Silicon Labs EFR32EmberZnet-2…

一个无线鼠标的HID Report Desc

HID设备是USB规范定义的设备类型之一&#xff0c;其分类号为0x03. 关于USB设备类型定义&#xff0c;可参见本站&#xff1a;USB设备类型定义 - USB中文网 HID设备除了用于专门的输入输出设备外&#xff0c;有时也与其它的设备类型组合成一个复杂的设备。如对于UVC摄像头设备&a…

干货!数据智能作为先进生产力,如何助力销售效能提升?

存量竞争市场中&#xff0c;企业需要通过精细化运营提升客户价值与 ROI。数据智能作为先进生产力&#xff0c;在搜索、广告、推荐业务方面已经足够成熟&#xff0c;那么它是如何助力销售提升效能呢&#xff1f;本文将详细介绍。点击文末“阅读原文”即可观看完整版直播回放&…

中科大2007年复试机试题

中科大2007年复试机试题 文章目录中科大2007年复试机试题第一题问题描述解题思路及代码第二题问题描述解题思路及代码第三题问题描述解题思路及代码第四题问题描述解题思路及代码第一题 问题描述 编写程序&#xff0c;判断给定数字是否是回文数。 示例 1 输入&#xff1a;12…

博主的心肝宝贝

写的不错的文档 Sql(Structured Query Language)语句笔记_sky wide的博客-CSDN博客常用sql语句总结https://blog.csdn.net/qq_44652591/article/details/127545318Linux samba服务配置_sky wide的博客-CSDN博客_linux samba配置但是&#xff0c;注意后面公司的需求&#xff0c;…

Docker部署Jenkins

系列文章目录 Docker部署 registry Docker搭建 svn Docker部署 Harbor Docker 部署SQL Server 2017 Docker 安装 MS SqlServer Docker部署 Oracle12c Docker部署Jenkins Docker部署Jenkins系列文章目录前言一、启动docker&#xff0c;下载Jenkins镜像文件二、创建Jenkins挂载目…

fastjson 1.2.24漏洞复现

原理 fastjson由于没有对type进行安全性验证&#xff0c;使攻击者传入危险的类&#xff0c;通过rmi服务指定的攻击机上的恶意class文件&#xff0c;导致命令执行。 版本 1.2.24 环境准备 靶机&#xff1a;ubuntu&#xff0c;192.168.52.129 攻击机&#xff1a;kali&#…

数组的定义和使用

一、一维数组的定义、初始化 1. 一维数组的定义 元素类型 数组名[常量表达式]&#xff1b; &#xff08;1&#xff09;一维数组是由元素类型、数组名和长度组成的构造类型。 &#xff08;2&#xff09;数组名必须符合C标识符规则。 &#xff08;3&#xff09;常量表…