当前位置: 首页 > news >正文

MyBatis入门配置及CURD实现

目录

一、MyBatis简介

1. 什么是 MyBatis ? 

2. MyBatis的特性

3. 什么是持久层框架?

二、MyBatis环境配置

2.1 创建maven工程

2.2 导入相关pom依赖

2.3 导入jdbc配置文件

2.4 Mybatis相关插件安装

3.5 Mybatis-cfg.xml 核心配置

2.6 引入Log4j2日志文件

2.7 generatorConfig.xml 配置代码生成器

三、MyBatis实现增删改查

3.1 MyBatis自动生成代码

3.2 解读生成的配置文件和方法

3.3 编写业务逻辑层实现接口

3.4 编写工厂类

3.5 编写测试类测试


一、MyBatis简介

1. 什么是 MyBatis ? 

        MyBatis是一个开源的Java持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

2. MyBatis的特性

  1. 简单易用:MyBatis使用简单的XML或注解配置来映射Java对象和SQL语句,使得开发人员可以轻松地编写和维护数据库访问代码。

  2. 灵活性:MyBatis允许开发人员编写自定义的SQL语句,从而可以灵活地处理复杂的数据库操作。它还支持动态SQL,可以根据不同的条件生成不同的SQL语句。

  3. 高性能:MyBatis使用了一些优化技术,如预编译SQL语句、缓存等,以提高数据库访问的性能。

  4. 易于集成:MyBatis可以与各种流行的Java框架(如Spring)无缝集成,使得开发人员可以更方便地使用MyBatis进行数据库操作。

        MyBatis的主要作用是简化Java应用程序与关系型数据库之间的交互。通过使用MyBatis,开发人员可以通过简单的配置和编写SQL语句,实现对数据库的增删改查操作。同时,MyBatis还提供了一些高级特性,如分页查询、批量操作等,使得数据库访问更加灵活和高效。总之,MyBatis是一个功能强大、易于使用的持久层框架,被广泛应用于Java开发中。

3. 什么是持久层框架?

        持久层框架是一种软件框架,用于简化应用程序与数据库之间的交互和数据持久化操作。在软件开发中,应用程序通常需要与数据库进行交互,包括数据的读取、写入、更新和删除等操作。持久层框架的主要目的是提供一种简单、高效、可维护的方式来处理这些数据库操作。

        传统的数据库操作方式通常需要开发人员手动编写SQL语句,并处理数据库连接、事务管理等细节。这种方式存在一些问题,如代码冗余、易出错、难以维护等。持久层框架的出现解决了这些问题,它提供了一种抽象层,将数据库操作封装起来,使开发人员可以通过简单的API调用来进行数据库操作,而无需关注底层的数据库细节。

持久层框架通常提供以下功能:

  1. 对象关系映射(ORM):持久层框架可以将数据库表和Java对象之间建立映射关系,使得开发人员可以通过操作Java对象来实现对数据库的操作,而无需直接编写SQL语句。

  2. 数据库连接管理:持久层框架负责管理数据库连接的创建、释放和连接池的管理,以提高数据库访问的性能和效率。

  3. 事务管理:持久层框架可以提供事务管理的功能,确保数据库操作的一致性和完整性。

  4. 缓存管理:持久层框架可以提供缓存机制,将经常访问的数据缓存在内存中,以提高数据的读取性能。

        持久层框架的使用可以简化数据库操作的代码量,提高开发效率,降低开发难度,并且可以提供一些高级特性,如懒加载、分页查询、批量操作等,使得数据库操作更加灵活和高效。常见的持久层框架有Hibernate、MyBatis等。

二、MyBatis环境配置

2.1 创建maven工程

我使用的是idea2023版,其他版本创建Maven方式会有所不同,仅供参考:

2.2 导入相关pom依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mybatis_01</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>mybatis_01 Maven Webapp</name><url>http://maven.apache.org</url><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!-- ********************** junit单元测试依赖 ********************** --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- ********************** Java Servlet API  ********************** --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.0</version><scope>provided</scope></dependency><!-- ********************** Mybatis依赖 ********************** --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- ********************** Mysql JDBC驱动 ********************** --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.44</version></dependency><!-- **********************  日志配置  ********************** --><!--核心log4j2jar包--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.9.1</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.9.1</version></dependency><!--web工程需要包含log4j-web,非web工程不需要--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-web</artifactId><version>2.9.1</version></dependency></dependencies><build><finalName>mybatis_01</finalName><resources><!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题--><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题--><resource><directory>src/main/resources</directory><includes><include>jdbc.properties</include><include>*.xml</include></includes></resource></resources><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.7.0</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.2</version><dependencies><!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.44</version></dependency></dependencies><configuration><overwrite>true</overwrite></configuration></plugin></plugins></build>
</project>

2.3 导入jdbc配置文件

我用的mysql8.0版本,需根据自身配置需求更改配置文件内容。

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=UTF-8
jdbc.username=mybatis_ssm
jdbc.password=ycxw320

2.4 Mybatis相关插件安装

Mybatis plugin插件主要功能有:

  1. 提供Mapper接口与配置文件中对应SQL的导航

  2. 编辑XML文件时自动补全

  3. 根据Mapper接口, 使用快捷键生成xml文件及SQL标签

  4. ResultMap中的property支持自动补全,支持级联(属性A.属性B.属性C)

  5. 快捷键生成@Param注解

  6. XML中编辑SQL时, 括号自动补全

  7. XML中编辑SQL时, 支持参数自动补全(基于@Param注解识别参数)

  8. 自动检查Mapper XML文件中ID冲突

  9. 自动检查Mapper XML文件中错误的属性值

  10. 支持Find Usage

  11. 支持重构从命名

  12. 支持别名

  13. 自动生成ResultMap属性

  14. 快捷键:   Option + Enter(Mac) | Alt + Enter(Windows)

3.5 Mybatis-cfg.xml 核心配置

MyBatis 的配置文件包含了MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  • configuration(配置)
  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
    • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)
<?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="LOG4J2"/></settings><!-- 别名 --><typeAliases><!--<typeAlias type="com.javaxl.model.Book" alias="Book"/>--></typeAliases><!-- 配置mybatis运行环境 --><environments default="development"><environment id="development"><!-- type="JDBC" 代表使用JDBC的提交和回滚来管理事务 --><transactionManager type="jdbc"/><!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI --><!-- POOLED 表示支持JDBC数据源连接池 --><!-- UNPOOLED 表示不支持数据源连接池 --><!-- JNDI 表示支持外部数据源连接池 --><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/ycxw/mapper/BookMapper.xml"/></mappers>
</configuration>

2.6 引入Log4j2日志文件

  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等
  • log4j可以控制每一条日志的输出格式
  • log4j可以通过一个配置文来灵活地进行配置,而不需要修改应用的代码。
<?xml version="1.0" encoding="UTF-8"?><!-- status : 指定log4j本身的打印日志的级别.ALL< Trace < DEBUG < INFO < WARN < ERROR < FATAL < OFF。 monitorInterval : 用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s. -->
<Configuration status="WARN" monitorInterval="30"><Properties><!-- 配置日志文件输出目录 ${sys:user.home} --><Property name="LOG_HOME">/root/workspace/lucenedemo/logs</Property><property name="ERROR_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/error</property><property name="WARN_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/warn</property><property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n</property></Properties><Appenders><!--这个输出控制台的配置 --><Console name="Console" target="SYSTEM_OUT"><!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --><ThresholdFilter level="trace" onMatch="ACCEPT"onMismatch="DENY" /><!-- 输出日志的格式 --><!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 %m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M : 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 --><PatternLayout pattern="${PATTERN}" /></Console><!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 --><!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true --><File name="log" fileName="logs/test.log" append="false"><PatternLayoutpattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /></File><!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size, 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 --><RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"><!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --><ThresholdFilter level="info" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayoutpattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /><Policies><!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。 modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am. --><!-- 关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval, 日期格式精确到哪一位,interval也精确到哪一个单位 --><!-- log4j2的按天分日志文件 : info-%d{yyyy-MM-dd}-%i.log --><TimeBasedTriggeringPolicy interval="1"modulate="true" /><!-- SizeBasedTriggeringPolicy:Policies子节点, 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小. --><!-- <SizeBasedTriggeringPolicy size="2 kB" /> --></Policies></RollingFile><RollingFile name="RollingFileWarn" fileName="${WARN_LOG_FILE_NAME}/warn.log"filePattern="${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"><ThresholdFilter level="warn" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayoutpattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /><Policies><TimeBasedTriggeringPolicy /><SizeBasedTriggeringPolicy size="2 kB" /></Policies><!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --><DefaultRolloverStrategy max="20" /></RollingFile><RollingFile name="RollingFileError" fileName="${ERROR_LOG_FILE_NAME}/error.log"filePattern="${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.log"><ThresholdFilter level="error" onMatch="ACCEPT"onMismatch="DENY" /><PatternLayoutpattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /><Policies><!-- log4j2的按分钟 分日志文件 : warn-%d{yyyy-MM-dd-HH-mm}-%i.log --><TimeBasedTriggeringPolicy interval="1"modulate="true" /><!-- <SizeBasedTriggeringPolicy size="10 MB" /> --></Policies></RollingFile></Appenders><!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 --><Loggers><!--过滤掉spring和mybatis的一些无用的DEBUG信息 --><logger name="org.springframework" level="INFO"></logger><logger name="org.mybatis" level="INFO"></logger><!-- 第三方日志系统 --><logger name="org.springframework" level="ERROR" /><logger name="org.hibernate" level="ERROR" /><logger name="org.apache.struts2" level="ERROR" /><logger name="com.opensymphony.xwork2" level="ERROR" /><logger name="org.jboss" level="ERROR" /><!-- 配置日志的根节点 --><root level="all"><appender-ref ref="Console" /><appender-ref ref="RollingFileInfo" /><appender-ref ref="RollingFileWarn" /><appender-ref ref="RollingFileError" /></root></Loggers></Configuration>

2.7 generatorConfig.xml 配置代码生成器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" ><generatorConfiguration><!-- 引入配置文件 --><properties resource="jdbc.properties"/><!--指定数据库jdbc驱动jar包的位置--><classPathEntry location="D:\\Tools\\MavenHouse\\mvn_repository\\mysql\\mysql-connector-java\\5.1.44\\mysql-connector-java-5.1.44.jar"/><!-- 一个数据库一个context --><context id="infoGuardian"><!-- 注释 --><commentGenerator><property name="suppressAllComments" value="true"/><!-- 是否取消注释 --><property name="suppressDate" value="true"/> <!-- 是否生成注释代时间戳 --></commentGenerator><!-- jdbc连接 --><jdbcConnection driverClass="${jdbc.driver}"connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/><!-- 类型转换 --><javaTypeResolver><!-- 是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.) --><property name="forceBigDecimals" value="false"/></javaTypeResolver><!-- 01 指定javaBean生成的位置 --><!-- targetPackage:指定生成的model生成所在的包名 --><!-- targetProject:指定在该项目下所在的路径  --><javaModelGenerator targetPackage="com.ycxw.model"targetProject="src/main/java"><!-- 是否允许子包,即targetPackage.schemaName.tableName --><property name="enableSubPackages" value="false"/><!-- 是否对model添加构造函数 --><property name="constructorBased" value="true"/><!-- 是否针对string类型的字段在set的时候进行trim调用 --><property name="trimStrings" value="false"/><!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 --><property name="immutable" value="false"/></javaModelGenerator><!-- 02 指定sql映射文件生成的位置 --><sqlMapGenerator targetPackage="com.ycxw.mapper"targetProject="src/main/java"><!-- 是否允许子包,即targetPackage.schemaName.tableName --><property name="enableSubPackages" value="false"/></sqlMapGenerator><!-- 03 生成XxxMapper接口 --><!-- type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 --><!-- type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 --><!-- type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 --><javaClientGenerator targetPackage="com.ycxw.mapper"targetProject="src/main/java" type="XMLMAPPER"><!-- 是否在当前路径下新加一层schema,false路径com.oop.eksp.user.model, true:com.oop.eksp.user.model.[schemaName] --><property name="enableSubPackages" value="false"/></javaClientGenerator><!-- 配置表信息 --><!-- schema即为数据库名 --><!-- tableName为对应的数据库表 --><!-- domainObjectName是要生成的实体类 --><!-- enable*ByExample是否生成 example类 --><!--<table schema="" tableName="t_book" domainObjectName="Book"--><!--enableCountByExample="false" enableDeleteByExample="false"--><!--enableSelectByExample="false" enableUpdateByExample="false">--><!--&lt;!&ndash; 忽略列,不生成bean 字段 &ndash;&gt;--><!--&lt;!&ndash; <ignoreColumn column="FRED" /> &ndash;&gt;--><!--&lt;!&ndash; 指定列的java数据类型 &ndash;&gt;--><!--&lt;!&ndash; <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> &ndash;&gt;--><!--</table>--><table schema="" tableName="t_mvc_Book" domainObjectName="Book"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false"><!-- 忽略列,不生成bean 字段 --><!-- <ignoreColumn column="FRED" /> --><!-- 指定列的java数据类型 --><!-- <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> --></table></context>
</generatorConfiguration>

注意:

1.修改本地路径的jdbc驱动jar包位置 

<!--指定数据库jdbc驱动jar包的位置-->
<classPathEntry location="D:\\Tools\\MavenHouse\\mvn_repository\\mysql\\mysql-connector-java\\5.1.44\\mysql-connector-java-5.1.44.jar"/>

2. 修改指定javaBean生成的位置

<javaModelGenerator targetPackage="com.ycxw.model"targetProject="src/main/java">......
</javaModelGenerator>

3. 修改指定sql映射文件生成的位置

<sqlMapGenerator targetPackage="com.ycxw.mapper"targetProject="src/main/java">......
</sqlMapGenerator>

 4. 修改指定生成mapper接口文件位置

<javaClientGenerator targetPackage="com.ycxw.mapper"targetProject="src/main/java" type="XMLMAPPER">......
</javaClientGenerator>

5. 修改需要引用的数据库表名

<table schema="" tableName="t_mvc_Book" domainObjectName="Book"enableCountByExample="false" enableDeleteByExample="false"enableSelectByExample="false" enableUpdateByExample="false">......
</table>

三、MyBatis实现增删改查

3.1 MyBatis自动生成代码

1. 找到配置的MyBatis插件启动mybatis-general

2. 然后就会生成实体和增删改查接口和实现的配置文夹:

3.2 解读生成的配置文件和方法

  • ​ id:对应的接口中的方法名
  • ​ resultType: sql语句执行的返回值类型
  • ​ parameterType:参数类型

3.3 编写业务逻辑层实现接口

1. 编写BookBiz接口类

package com.ycxw.biz;import com.ycxw.model.Book;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-20 17:52*/
public interface BookBiz {int deleteByPrimaryKey(Integer bid);int insert(Book record);int insertSelective(Book record);Book selectByPrimaryKey(Integer bid);int updateByPrimaryKeySelective(Book record);int updateByPrimaryKey(Book record);
}

2. 编写BookBizImpl接口实现类

package com.ycxw.biz.impl;import com.ycxw.biz.BookBiz;
import com.ycxw.mapper.BookMapper;
import com.ycxw.model.Book;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-20 17:52*/
public class BookBizImpl implements BookBiz {//引入生成的接口private BookMapper bookMapper;public BookMapper getBookMapper() {return bookMapper;}public void setBookMapper(BookMapper bookMapper) {this.bookMapper = bookMapper;}@Overridepublic int deleteByPrimaryKey(Integer bid) {return bookMapper.deleteByPrimaryKey(bid);}@Overridepublic int insert(Book record) {return bookMapper.insert(record);}@Overridepublic int insertSelective(Book record) {return bookMapper.insertSelective(record);}@Overridepublic Book selectByPrimaryKey(Integer bid) {return bookMapper.selectByPrimaryKey(bid);}@Overridepublic int updateByPrimaryKeySelective(Book record) {return bookMapper.updateByPrimaryKeySelective(record);}@Overridepublic int updateByPrimaryKey(Book record) {return bookMapper.updateByPrimaryKey(record);}
}

3.4 编写工厂类

        该类主要为了实现了一个简单的MyBatis的SqlSession管理工具类,通过openSession()方法可以获取到当前线程的SqlSession对象,方便进行数据库操作。

package com.ycxw.utils;import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;/*** 工厂类* @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-20 17:58*/
public class SessionUtil {private static SqlSessionFactory sessionFactory;private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();static {sessionFactory = new SqlSessionFactoryBuilder().build(SessionUtil.class.getResourceAsStream("/mybatis.cfg.xml"));}public static SqlSession openSession() {SqlSession session = threadLocal.get();if (null == session) {session = sessionFactory.openSession();threadLocal.set(session);}return session;}public static void main(String[] args) {SqlSession session = openSession();System.out.println(session.getConnection());session.close();
//        System.out.println(session.getConnection());}}

3.5 编写测试类测试

package com.ycxw.demo;import com.ycxw.biz.BookBiz;
import com.ycxw.biz.impl.BookBizImpl;
import com.ycxw.mapper.BookMapper;
import com.ycxw.model.Book;
import com.ycxw.utils.SessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;/*** @author 云村小威* @site blog.csdn.net/Justw320* @create 2023-08-20 18:05*/
public class CURDTest {private BookBiz bookBiz;private SqlSession sqlSession;@Beforepublic void before(){System.out.println("执行测试方法之前会执行的初始化代码块方法");//获取一个数据库会话对象,并将其赋值给sqlSession变量this.sqlSession = SessionUtil.openSession();//实例化业务逻辑层BookBizImpl book = new BookBizImpl();//获取接口实例BookMapper mapper = this.sqlSession.getMapper(BookMapper.class);book.setBookMapper(mapper);//最后赋值给bookBiz接口,便于对数据库进行增删改查操作this.bookBiz = book;}@Afterpublic void after(){System.out.println("执行测试方法之后的后执行的方法");//提交事务this.sqlSession.commit();}@Testpublic void text1(){System.out.println("测试查询方法方法..");Book book = bookBiz.selectByPrimaryKey(25);System.out.println(book);}@Testpublic void text2(){System.out.println("测试新增方法");int insert = bookBiz.insert(new Book(1,"Mybatis宝典",9.9f));System.out.println("所影响的行数"+insert);}
}

运行测试: 

 数据库验证:

相关文章:

MyBatis入门配置及CURD实现

目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架&#xff1f; 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…...

《游戏编程模式》学习笔记(五)原型模式 Prototype Pattern

原型的定义 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 举个例子 假设我现在要做一款游戏&#xff0c;这个游戏里有许多不同种类的怪物&#xff0c;鬼魂&#xff0c;恶魔和巫师。这些怪物通过“生产者”进入这片区域&#xff0c;每种敌人…...

ansible案列之LNMP分布式剧本

LNMP分布式剧本 一&#xff1a;环境设置二&#xff1a;编写Nginx剧本准备nginx下载源准备配置文件并开放PHP的访问路径准备php测试页面编写nginx剧本 三&#xff1a;编写Mysql剧本编写密码获取脚本准备Mysql的yum源编写mysql剧本 四&#xff1a;准备PHP剧本准备两个配置文件编写…...

React2023电商项目实战 - 1.项目搭建

古人学问无遗力&#xff0c;少壮工夫老始成。 纸上得来终觉浅&#xff0c;绝知此事要躬行。 —— 陆游《《冬夜读书示子聿》》 系列文章目录 项目搭建App登录及网关App文章自媒体平台&#xff08;博主后台&#xff09;内容审核(自动) 文章目录 系列文章目录一、项目介绍1.页面…...

数据库连接池(c3p0和德鲁伊)

目录 连接池介绍 c3p0连接池 传统方法引入jar包 配置文件 德鲁伊连接池 德鲁伊工具类 传统jdbc数据库使用DriverManger来获取&#xff0c;每次向数据库建立连接需要将Connection加载到内存中&#xff0c;频繁的操作会造成占用很多系统资源&#xff0c;造成服务器崩溃&…...

ARM--day6(实现字符、字符串收发的代码和现象,分析RCC、GPIO、UART章节)

uart4.h #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h"//RCC/GPIO/UART4章节初始化 void hal_uart4_init();//发送一个字符函数 void hal_put_char(const c…...

2023牛客暑期多校训练营9 B.Semi-Puzzle: Brain Storm

文章目录 题目大意题解求解回溯 参考代码 题目大意 给定两个数 a , m a,m a,m &#xff0c;求满足 a u ≡ u ( m o d m ) a^u \equiv u (mod\ \ m) au≡u(mod m) 的一个解。 ( 1 ≤ a , m ≤ 1 0 9 , 0 ≤ u ≤ 1 0 18 ) (1\leq a,m \leq10^9 ,0\leq u\leq 10^{18}) (1≤a…...

mysql中的窗口函数

MySQL中的窗口函数&#xff08;Window Functions&#xff09;是一种用于在查询结果集内执行计算的功能。窗口函数可以在查询中进行分析和聚合操作&#xff0c;而无需将查询结果分组。它们可以用于计算排名、行号、累积值等各种分析操作。窗口函数通常与OVER子句一起使用&#x…...

【双指针】经典数组双指针题LeetCode

文章目录 27. 移除元素 简单283. 移动零 简单&#x1f525;167. 两数之和 II - 输入有序数组 中等11. 盛最多水的容器 中等&#x1f525;15. 三数之和 中等&#xff08;N数之和&#xff09;中等&#x1f525;42. 接雨水 困难 &#x1f525;26. 删除有序数组中的重复项 简单5. 最…...

极智嘉x吉利汽车 x京东物流,引领汽车行业智慧物流新变革!

近日&#xff0c;中国领先的汽车制造商吉利汽车携手中国领先的技术驱动的供应链解决方案及物流服务商京东物流、全球仓储机器人引领者极智嘉(Geek)&#xff0c;在西安吉利汽车制造基地RDC仓库率先落地SkyPick上存下拣解决方案&#xff0c;实现了全物流链精益化、智能化、一体化…...

RK3588平台开发系列讲解(AI 篇)RKNN C API 详细说明

文章目录 一、API 硬件平台支持说明二、API 函数介绍2.1、rknn_init2.2、rknn_destroy2.3、rknn_query2.4、rknn_inputs_set2.5、rknn_run2.6、rknn_outputs_get2.7、rknn_outputs_release沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解 RKNN C API 详细…...

【基础】Android Handler

一、博客参考 Handler机制详解【重点】&#xff1a;https://www.jianshu.com/p/b4d745c7ff7a Handler Thread工作线程操作UI范例【重点】&#xff1a;https://www.cnblogs.com/net168/p/4075126.html 二、内存泄漏的解决&#xff1a;静态内部类弱引用 关于 Handler&#xf…...

c语言实现MD5算法

MD5加密 文章目录 MD5加密MD5介绍应用场景代码分析 &#xff08;基于qt5.14.2&#xff09;测试记录 MD5介绍 1。 一种单向加密算法&#xff0c;即对明文加密&#xff0c;而不能通过密文得到明文。对原数据的任何改动&#xff0c;哪怕是1字节&#xff0c;得到的MD5值都有很大的区…...

Apache Doris 2.0.0 特性分析

1、存算分离 所谓存算分离是指查询外表时&#xff0c;使用一种专门做计算的BE节点&#xff0c;但对于存储在BE上的内部表&#xff0c;目前还不能做到存储分离。 doris可以查询外部表&#xff0c;包括&#xff1a; Hive、Iceberg、Hudi、Elasticsearch、JDBC、Paimon 早期版本中…...

如何做H5性能测试?

提起H5性能测试&#xff0c;可能许多同学有所耳闻&#xff0c;但是不知道该如何对H5做性能测试&#xff0c;或者不知道H5应该关注哪些性能指标。今天我们就来看下&#xff0c;希望阅读本文后&#xff0c;能够有所了解。 常用指标 1、H5性能相关参数介绍 白屏时间&#xff1a;…...

【Docker】Docker Desktop配置资源:cpu、内存等(windows环境下)

Docker Desktop配置资源&#xff1a;cpu、内存等&#xff08;windows环境下&#xff09; 一、WSL2 以及 hyper-v区别&#xff0c;二者安装docker desktop1.WSL2和hyper-v区别2.安装Docker Desktop 二、docker desktop限额配置&#xff0c;资源配置方法 Docker 是指容器化技术&a…...

8.2.tensorRT高级(3)封装系列-内存管理的封装,内存的复用

目录 前言1. 内存管理封装2. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-内存管理的封装&…...

Keepalived入门指南:实现故障转移和负载均衡

文章目录 一、简介1. Keepalived概述2. 高可用性和负载均衡的重要性 二、故障转移1. 什么是故障转移2. Keepalived的故障转移原理a) VRRP协议b) 虚拟路由器ID和优先级 3. 配置Keepalived实现故障转移a) 主备服务器的设置b) 监控网络接口c) 虚拟IP的配置d) 备份服务器接管流程 三…...

cuOSD(CUDA On-Screen Display Library)库的学习

目录 前言1. cuOSD1.1 Description1.2 Getting started1.3 For Python Interface1.4 Demo1.5 Performance Table 2. cuOSD案例2.1 环境配置2.2 simple案例2.3 segment案例2.4 segment2案例2.5 polyline案例2.6 comp案例2.7 perf案例 3. cuOSD浅析3.1 simple_draw函数 4. 补充知…...

c++函数指针基本用法

将函数像变量一样传递&#xff0c;实际上拿到的是函数的地址&#xff0c;由于函数类型的多样&#xff0c;可以使用auto关键字&#xff0c;可以使用 void(*function2)() &#xff0c;不过它太繁琐&#xff0c;因此使用typedef 起个名字 typedef void(*HelloWorldFunction)(); 叫…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序&#xff0c;无论是测试应用程序、搜寻漏洞还是收集情报&#xff0c;它们都能提升工作流程。 FoxyProxy 代理管理工具&#xff0c;此扩展简化了使用代理&#xff08;如 Burp…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...