01第一个Mybatis程序+引入Junit+引入日志文件logback

Mybatis

  • MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。
  • 而对于JDBC,SQL语句写死在Java程序中,不灵活。改SQL的话就要改Java代码。违背开闭原则OCP。
  • 对于事务机制,MyBatis支持 或managed模式,JDBC模式中MyBatis将事物委托给JDBC管理;managed模式中MyBatis不再管理事务,此时可以使用Spring框架等管理事务;否则,程序根本不支持事务,这是不推荐的。
  • MyBatis属于半自动化ORM框架,虽然不会全自动生成,但是可调行高,易于debug。
  • 在这里插入图片描述
  • 将接口和 Java 的 POJOs(Plain Ordinary Java Object,简单普通的Java对象)映射(Mapping)成关系型数据库(Relational)中的记录

1.新建Mybatis项目

●步骤1:pom.xml中声明打包方式:jar(不需要war,因为mybatis封装的是jdbc。)
●步骤2:引入依赖(mybatis依赖 + mysql驱动依赖)
●步骤3:在resources根目录下新建mybatis-config.xml配置文件(可以参考mybatis手册拷贝)
注意1:mybatis核心配置文件的文件名不一定是mybatis-config.xml,可以是其它名字。
注意2:mybatis核心配置文件存放的位置也可以随意。这里选择放在resources根下,相当于放到了类的根路径下。

●步骤4:在resources根目录下新建CarMapper.xml配置文件(可以参考mybatis手册拷贝)
注意1:sql语句最后结尾可以不写“;”
注意2:CarMapper.xml文件的名字不是固定的。可以使用其它名字。
注意3:CarMapper.xml文件的位置也是随意的。这里选择放在resources根下,相当于放到了类的根路径下。
注意4:将CarMapper.xml文件路径配置到mybatis-config.xml:

●步骤5:编写mybatis程序myBatisIntroductionTest代码
注意1:默认采用的事务管理器是:JDBC。JDBC事务默认是不提交的,需要手动提交。

注意2:在mybatis中,执行sql语句的对象叫做SqlSession,是Java程序和数据库之间的一次会话.

而要获取SqlSession对象–先获取SqlSessionFactory对象–通过SqlSessionFactoryBuilder对象的Build方法,获取一个SqlSessionFactory对象.

●步骤6:运行程序,查看运行结果,以及数据库表中的数据

结构为
在这里插入图片描述

新建一个空项目,然后新建一个空白模块

项目设置中更改默认Maven设置,setting.xml设置

pom.xml中添加打包方式,依赖(mybatis,mysql)

<packaging>jar</packaging><dependencies><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version></dependency><!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-java --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency>

在Main根目录下resources文件夹新建 mybatis-config.xml 文件(mybatis核心配置文件,只有一个)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//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/carreseller}"/><property name="username" value="${root}"/><property name="password" value="${Mysql998168}"/></dataSource></environment></environments><mappers>
<!--         说明欲执行的mapper文件的存放位置-->
<!--        从根目录下开始查找,因此如果mapper文件就放在根目录下,则不用写出具体路径--><mapper resource="CarMapper.xml"/></mappers>
</configuration>

编写xxxMapper.xml(mybatis配置文件,多个,每个mapper文件对应一个表)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="TBD"><insert id="">insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)values(null,'1003','toyota',30.00,'2000-10-11','燃油车')</insert>
</mapper>
package com.sunsplanter.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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class MyBatisIntroductionTest {public static void main(String[] args) throws IOException {SqlSession sqlSession = null;try {// 获取对象的顺序为:SqlSessionFactoryBuilder-》SqlSessionFactory-》SqlSession//每个数据库中,这三者的关系是:1:1:nSqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//MyBatis包含了一个Resources类,用Resources类调方法,默认从类的根目录下开始找,因此如果mybatis-config.xml就放在Resources目录下,直接写名字就可以InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");//mybatis核心配置文件的路径SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);sqlSession = sqlSessionFactory.openSession();//执行SQL语句,执行的语句在xxxMapper.xml中,并且并非一次执行完一个Mapper的全部代码// 因此通过id为参数,定位要执行的具体SQL代码块//insert可选返回值,返回值代表影响数据库中表项的个数.int count = sqlSession.insert("insertCar");System.out.println(count);//当mybatis-config.xml中<transactionManager type="JDBC"/>时,即将事务机制交给JDBC管理//而JDBC的autoCommit是false的,因此必须要sqlSession.commit手动提交,因此说此时sqlSession对象不支持自动提交。sqlSession.commit();} catch (Exception e) {// 回滚if (sqlSession != null) {sqlSession.rollback();}e.printStackTrace();} finally {// 6.关闭if (sqlSession != null) {sqlSession.close();}}}
}

引入Junit

引入Junit是为了替代main方法,可以单独测试各个单元。

● 使用JUnit步骤:
○ 第一步:引入依赖

<!-- junit依赖 -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>

○ 第二步:编写单元测试类【测试用例】,测试用例中每一个测试方法上使用@Test注解进行标注。
■ 测试用例的名字以及每个测试方法的定义都是有规范的:
● 测试用例(类)的名字:XxxTest
● 测试方法声明格式:public void test业务方法名(){}
// 测试用例
public class CarMapperTest{

// 测试方法
@Test
public void testInsert(){}@Test
public void testUpdate(){}

}
○ 第三步:可以在类上执行,也可以在方法上执行
■ 在类上执行时,该类中所有的测试方法都会执行。
■ 在方法上执行时,只执行当前的测试方法。

引入日志文件

在mybatis-config.xml中的environments 标签前,可添加settings标签(若有,则相对位置必须要settings在前),是否开启日志,开启何种日志,就是其中一种setting。
在这里插入图片描述
logback作为一个框架,实现了SLF4J标准,因此,尽管setting中选择的日志是SLF4J,等会导入依赖还是导入logback。

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

使用logback,先添加依赖

        <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.11</version><scope>test</scope></dependency>

logback实现(包含了SLF4J),从依赖的关系中就可以看出来:
在这里插入图片描述

第二步:引入logback相关配置文件(文件名必须叫做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>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory></rollingPolicy><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><!--日志文件最大的大小--><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"><MaxFileSize>100MB</MaxFileSize></triggeringPolicy></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>

此时再次执行代码,控制台会输出更详细的反馈,包括执行了哪条SQL语句。

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

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

相关文章

基于SSM图书管理系统【源码】【最详细运行文档】

SSM图书管理系统【源码】【最详细运行文档】 系统简介系统涉及系统运行系统演示源码获取 系统简介 以往的图书馆管理事务处理主要使用的是传统的人工管理方式&#xff0c;这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点&#xff0c;长期的人工管理模式会产生大量…

2023秋电子科大信软 程算I 机考真题

基本情况 对应课程&#xff1a;程序设计与算法基础I 考试时间&#xff1a;2小时 题型&#xff1a;函数题编程题 函数题只需要完成期中一些&#xff08;个&#xff09;函数即可 编程题需要自己手动写main函数 提示&#xff1a;本次考试为全年级机考&#xff0c;分上下午场&am…

Timsort:最快排序算法

Timsort&#xff08;泰姆排序&#xff09;是一种混合排序算法&#xff0c;结合了合并排序&#xff08;Merge Sort&#xff09;和插入排序&#xff08;Insertion Sort&#xff09;的特性。它由Tim Peters在2002年为Python的排序算法而设计&#xff0c;并在Python 2.3版本中首次实…

05.构造程序逻辑

构造程序逻辑 学完前面的几个章节后&#xff0c;我觉得有必要在这里带大家做一些练习来巩固之前所学的知识&#xff0c;虽然迄今为止我们学习的内容只是Python的冰山一角&#xff0c;但是这些内容已经足够我们来构建程序中的逻辑。对于编程语言的初学者来说&#xff0c;在学习…

Looper如何通过ThreadLocal保证的线程独有

ThreadLocalMap 每个线程Thread都会维护一个threadLocals变量&#xff1a;ThreadLocalMap。这个类是ThreadLocal的静态内部类。当进行ThreadLocal的set()和get()时都会去获取线程里面的这个threadLocals进行设值和取值操作。所以ThreadLocal可以做到各个线程间数据互不干扰 T…

python 写自动点击爬取数据

今天来点不一样的&#xff01;哥们 提示&#xff1a; 这里只是用于自己学习的 &#xff0c;请勿用违法地方 效果图 会进行点击下一页 进行抓取 需要其他操作也可以自己写 文章目录 今天来点不一样的&#xff01;哥们前言一、上代码&#xff1f;总结 前言 爬虫是指通过编程自动…

Spark基础原理

Spark On Yarn Spark On Yarn的本质 Spark专注于分布式计算,Yarn专注于资源管理,Spark将资源管理的工作交给了Yarn来负责 Spark On Yarn两种部署方式 Spark中有两种部署方式&#xff0c;Client和Cluster方式&#xff0c;默认是Client方式。这两种方式的本质区别&#xff0c…

[C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测

【官方框架地址】 https://github.com/ViewFaceCore/ViewFaceCore 【算法介绍】 SeetaFace6是由中国科技公司自主研发的一款人脸识别技术&#xff0c;它基于深度学习算法&#xff0c;能够快速、准确地识别出人脸&#xff0c;并且支持多种应用场景&#xff0c;如门禁系统、移动…

智慧校园电子班牌管理系统源码 Java Android原生

智慧校园电子班牌系统源码是一种智能化的教育管理解决方案&#xff0c;它可以在学校内实现信息共享、教学管理、学生管理、家校互通等各个方面的协调与配合&#xff0c;帮助教师、学生和家长更加高效地开展教学活动、管理学生、协同合作&#xff0c;从而推动学校教育水平的提高…

【设计模式之美】 SOLID 原则之四:接口隔离原则有哪三种应用?原则中的“接口”该如何理解?

文章目录 一. 如何理解“接口隔离原则”&#xff1f;二. 接口隔离的三个情况1. 把“接口”理解为一组 API 接口集合2. 把“接口”理解为单个 API 接口或函数 ing&#xff08;能够使用的场景并未理解&#xff09;3. 把“接口”理解为 OOP 中的接口概念 一. 如何理解“接口隔离原…

Redis内存策略:「过期Key删除策略」+ 「内存淘汰策略」

Redis之所以性能强&#xff0c;最主要的原因就是基于内存存储&#xff0c;然而单节点的Redis其内存大小不宜过大&#xff0c;否则会影响持久化或主从同步的性能。 Redis内存满了&#xff0c;会发生什么&#xff1f; 在Redis的运行内存达到了某个阈值&#xff0c;就会触发内存…

图神经网络入门

图神经网络&#xff08;GNN&#xff09;是一组在图领域工作的深度学习方法。 这些网络最近已应用于多个领域&#xff0c;包括&#xff1a; 组合优化、推荐系统、计算机视觉—仅举几例。 这些网络还可用于对大型系统进行建模&#xff0c;例如社交网络、蛋白质-蛋白质相互作用网络…

Python 数据类型有哪些?

Python 数据类型 Python 数据类型用于定义变量的类型。它定义了我们将在变量中存储哪种类型的数据。存储在内存中的数据可以有很多种类型。例如&#xff0c;一个人的年龄被存储为数值&#xff0c;他或她的地址被存储为字母数字字符。 Python 有各种内置数据类型&#xff0c;主…

软件测试方法分类-按测试对象划分

接上一篇,下来我们再细讲,第四个维度的分类, 软件测试方法分类-按测试对象划分 本章节重点介绍非功能测试的相关知识,因为功能测试的基本在之前的分类都是有涉及的。 一、非功能测试 1,性能测试(Performance Testing) 检查系统是否满足需求规格说明书中规定的性能。 …

pytorch07:损失函数与优化器

目录 一、损失函数是什么二、常见的损失函数2.1 nn.CrossEntropyLoss交叉熵损失函数2.1.1 交叉熵的概念2.2.2 交叉熵代码实现2.2.3 加权重损失 2.2 nn.NLLLoss2.2.1 代码实现 2.3 nn.BCELoss2.3.1 代码实现 2.4 nn.BCEWithLogitsLoss2.4.1 代码实现 三、优化器Optimizer3.1 什么…

android常用方法

获取应用安装来源 private String getAppInstaller(Context context, String packageName) {return context.getPackageManager().getInstallerPackageName(packageName);}判断是否系统应用 在/system/app 或者 /system/priv-app目录下的应用。 public boolean isSystem(Conte…

Redis入门-五种数据类型

大家好我是苏麟 , 今天来说说Reids五种基本数据类型 . 五种常用数据类型介绍 大纲 字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用命令 Redis存储的是key-value结构的数据&#xff0c;其中key是字符串类型&#xff0c;value有5种常用的数据类型&…

导入导出(excel格式/压缩包格式导出至response、excel导入)

目录 导出一、excel格式导出至response1、List<对象>导出2、json对象不固定列导出 二、压缩包格式导出至response使用Hutool工具简化代码 导入一、对象导入二、不固定列导入 导出 一、excel格式导出至response 1、List<对象>导出 Map<String, String> hea…

零基础学Python网络爬虫案例实战全流程详解(入门与提高篇)

零基础学Python网络爬虫案例实战 全流程详解 入门与提高篇 零基础学Python网络爬虫案例实战 全流程详解 高级进阶篇 内容简介 在大数据时代的今天&#xff0c;无论是产品开始还是精准化营销越来越离不开大数据的支持&#xff0c;如何从浩瀚的网络中获取自己想要的大数据&…

用 Socket.D 替代原生 WebSocket 做前端开发

socket.d.js 是基于 websocket 包装的 socket.d 协议的实现。就是用 ws 传输数据&#xff0c;但功能更强大。 功能原生 websocketsocket.d说明listen有有监听消息send有有发消息sendAndRequest无有发消息并接收一个响应&#xff08;类似于 http&#xff09;sendAndSubscribe无…