Mybatis框架的集成使用

1_框架概述

框架是一个半成品,已经对基础的代码进行了封装并提供相应的API,开发者在使用框架时直接调用封装好的api可以省去很多代码编写,从而提高工作效率和开发速度,框架是一种经过校验、具有一定功能的半成品软件.

经过校验:指框架本身经过测试,且框架自身所具有的功能已经实现具有一定功能:指框架可以完成特定的功能,不同的框架功能不同

半成品软件:指框架自身是一个软件,但是该软件无法直接运行,需要配合其他的程序才可以完成指定的工作.

框架的工作模式:

开发工程师建立在框架的基础之上完成开发部分功能 加 框架自身完成部分功能组成一个完整的产品

2_MyBatis 基础

2.1_MyBatis的概述

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java  POJOPlain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

mybatis框架架构图:

我们把Mybatis的功能架构分为三层:

  1. API接口层:提供给外部使用的接口API开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
  2. 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
  3. 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

2.2_环境准备

需求: 向用户表中添加一条数据

  1. 添加项目需要的 jar
  2. lombok-1.16.6.jar(新的IDEA不用添加)

Lombok自动生成 getter/setter/toString 等方法使用的前提是已经在 idea 中安装了 lombok 插件

  1. mysql-connector-java-5.1.26-bin.jar

MySQL 数据库的 JDBC 驱动包,访问 MySQL 必须导入备 jar

  1. mybatis-3.4.5.jar MyBatis 框架的核心 jar
  2. 创建一张用户表:user

CREATE TABLE `user` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`name` varchar(255) DEFAULT NULL,

`age` int(255) DEFAULT NULL,

`salary` decimal(10,0) DEFAULT NULL

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

  1. 根据表结构创建实体类

@Getter@Setter@ToString

@NoArgsConstructor@AllArgsConstructor

public class User {

private Long id;

private String name;

private Integer age;

private BigDecimal salary;

private Date hiredate;

}

  1. mybatis主配置文件: mybatis-config.xml
  2. 在项目的resources(source folder)下创建mybatis-config.xml配置文件
  3. 拷贝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">

添加环境配置(事务管理器 / 连接池 / 映射文件)

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

<environment id="dev">

<!--

MyBatis 内置的事务管理器

JDBC:org.apache.ibatis.transaction.jdbc.JdbcTransaction的别名

-->

<transactionManager type="JDBC"/>

<!--

MyBatis 内置的连接池

POOLED:org.apache.ibatis.datasource.pooled.PooledDataSource的别

-->

<dataSource type="POOLED">

<!--

driver:这是POOLED连接池对象的驱动类的属性名,

Druid连接池对象的驱动类属性名是driverClassName

-->

<property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis"/

<property name="username" value="root"/>

<property name="password" value="admin"/>

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource="cn/UserMapper.xml"/> </mappers>

</configuration>

  1. mapper 映射文件: UserMapper.xml

mybatis,访问数据库的SQL语句是编写在mapper配置文件中的,程序员按照这个文件约定的格式进行配置即可

中创建配置文件: UserMapper.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">

在配置文件中添加 SQL 语句

<!--

一个项目可以操作多张表

每张表都需要一个mapper配置文件来编写SQL语句

每条SQL语句都需要有一个唯一的标识

这个唯一的标识由 namespace + sqlid 组成

使用下面的namespace+sqlid就得到了保存用户信息的唯一标识:

insert 接下来,我们就可以使用上面的标识找到这条SQL语句了

-->

<mapper namespace="cn.UserMapper"> <insert id="insert">

insert into user(name,age,salary,hiredate)

values(#{name}, #{age}, #{salary}, #{hiredate})

</insert>

</mapper>

注意: 一定记得在 mybatis-config.xml 配置文件中关联映射文件

<mappers>

<!--

这里是mapper文件的路径,所以使用/分割

-->

<mapper resource="cn/UserMapper.xml"/> </mappers>

2.3_DAO层开发

  1. dao接口

创建 dao 接口: IUserDAO.java

public interface IUserDAO {

/**

  • user表中插入一条数据
  • @param u 要插入的数据

 */

void insert(User u);

}

  1. dao 接口实现类

创建 dao 的实现类: UserDAOImpl.java

按以下 API 实现数据的保存操作:

  1. SqlSessionFactory : 对连接池(DataSource)的封装

SqlSession openSession() : 获取SqlSession对象

  1. SqlSession,对连接(Connection)的封装

int insert(String statementid, Object param);

statementid: mapper配置文件中的namespace+sqlid组成 void commit(): 提交事务

void close() : 释放资源

  1. 调用 SqlSession 中的 insert 方法,执行指定的 SQL

public class UserDAOImpl implements IUserDAO { public void insert(User u) {

try {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac = new

SqlSessionFactoryBuilder().build(in);

SqlSession session = fac.openSession();

session.insert("UserMapper.insert",

);

session.commit();

session.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

在测试类中测试 insert 方法

public class UserDAOTest {

private IUserDAO dao = new UserDAOImpl();

@Test

public void testInsert() {

User u = new User(null,"张三",20,new BigDecimal(20000), new Date()); dao.insert(u);

}

}

2.4_MyBatis 执行流程

  • 加载主配置文件(mybatis-config.xml)到内存中,将数据封装成对象Configuration/Environment/TransactionManager/DataSource
  • 通过操作拿到访问数据库的基本信息,根据这些数据创建 SqlSessionFactory 对象
  •  SqlSessionFactory 对象中获取到 SqlSession 对象,然后执行SQL
  • INSERT INTO user(name,age,salary,hiredate) VALUES(#{name},#{age},#{salary},#{hiredate})

被翻译成

INSERT INTO user(name,age,salary,hiredate)

VALUES(?, ?, ?, ?)

  1. 使用 PreparedStatement 来执行指定的SQL

从传递进来的 User 对象中依次获取到 name/age/salary/hiredate这些属性的值这里需要使用到内省机制来访问对象中的属性

:

在加载完当前映射文件之后,会将SQL中的 #{} OGNL表达式翻译成对应的占位符?,

执行上面的SQL,需要将数据设置给当前的语句对象 ps.setObect(1, 从参数中获取到name属性的值); ps.setObect(2, 从参数中获取到age属性的值); ps.setObect(3, 从参数中获取到salary属性的值); ps.setObect(4, 从参数中获取到hiredate属性的值);

操作步骤回顾:

  1. 创建项目,导入jar
  2. 创建表和模型

3 创建 mybatis-config.xml 配置环境

4 创建 UserMapper.xml 文件 存在 mapper包中,配置sql语句

5 创建 dao 接口和实现类

6 启动 MyBatis 去执行插入操作

  1. 测试插入操作

3_获取插入数据生成的主键

在开发中,如果需要获取到数据库中自动生成的主键,那么使用 MyBatis 应该如何实现呢?

<insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> insert into user(name,age,salary,hiredate)

values(#{name}, #{age}, #{salary}, #{hiredate})

</insert>

useGeneratedKeys: 是否要获取自动生成的主键

keyColumn: 表中的主键列

keyProperties: 主键列对应的属性

表示从获取哪个列的值封装到哪个属性中

通过上面的配置,在执行了保存操作后,mybatis 会自动将主键值封装到传递进来的 User 对象的 id 属性

所以,此时的 User 对象的 id 属性就有值了(在保存之前是没有的)

parameterType : 参数类型,可以不用写,MyBatis自己通过用户传入的对象去推导.

4_更新和删除操作

和保存操作的开发流程一致,在完成了保存操作之后,更新和删除操作一样可以实现 dao 中更新的实现

@Overrid

public void update(User u) {

try {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(in);

SqlSession session = fac.openSession();

session.update("UserMapper.update", u);

session.commit();

session.close();

} catch (Exception e) { e.printStackTrace();

}

}

更新在 mapper 中的 SQL

<update id="insert">

update user

set name=#{name}, age = #{age}, salary = #{salary}, hiredate = #{hiredate} where

id = #{id}

</insert>

dao 中删除的实现

@Override

public void delete(long id) {

try {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(in);

SqlSession session = fac.openSession();

session.delete("UserMapper.delete", id);

session.commit();

session.close();

} catch (Exception e) { e.printStackTrace();

}

}

删除在 mapper 中的 SQL

<delete id="delete">

delete from user where id = #{id}

</delete>

注意:

1 当传入的只有一个普通类型(一个值)的时候#{} 中的名称可以随便写,但是建议见名知义

2 不管使用的是 insert 方法还是 delete 方法,底层调用的还是update方法,通过sql语句来区别dml操作

5_查询操作

根据 id 查询用户

dao 实现

@Override

public User selectOne(long id) {

User u = null;

try {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(in); SqlSession session = fac.openSession();

u = session.selectOne("cn.UserMapper.selectOne",

id);

session.close();

} catch (Exception e) {

e.printStackTrace();

}

return u;

}

mapper 中的 SQL

<select id="selectOne" resultType="cn.domain.User"> select * from user where id = #{id}

</select>

 DML 不一样的地方,查询操作需要指定把查询的结果集数据封装成什么类型的对象,resultType 属性就是这个作用

思考: resultType 可以不配置吗? 不可以,需要告诉 MyBatis 把一行数据封装成什么类型的对象

目前: 需要模型的属性和表的列需要一一匹配,如果不匹配,无法获取到数据.

查询所有用户

dao 实现

@Override

public List<User> selectList() {

List<User> users = null;

try {

InputStream in = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(in); SqlSession session = fac.openSession(); users =

session.selectList("cn.UserMapper.selectAll");

session.close();

} catch (Exception e) { e.printStackTrace();

}

return users;

}

mapper 中的 SQL

<select id="selectAll" resultType="cn.domain.User"> select * from user

</select>

6_细节处理

类型别名

在查询操作中, 我们需要使用result属性指定数据封装的类型, 这里的值类型的全限定名, 每次都编写的话比较麻烦,为了简化这里的配置,我们可以在主配置文件(mybatis-config.xml)中对指定的类型做别名的配置

<!-- 为指定包中的类来生成别名,默认是类的简单名称 -->

<typeAliases>

<package name="cn.domain"/> </typeAliases>

如此,我们在查询的SQL, 使用类的全限定名和使用别名是等价的修改前:

<select id="selectAll" resultType="cn.User"> select * from user

</select>

修改后:

<select id="selectAll" resultType="User">

select * from user

</select>

日志管理

在持久层的开发过程中,我们程序员需要随时观察SQL的执行情况,如果sql有问题,我们能够及时发现所以,如果能够在控制台中将我们执行的SQL全部打印出来,那么就可以方便的观察SQL的相关问题

配置日志文件监控MyBatis的运行.

  1. 将日志相关的jar包添加到项目中

​​​​​​​

2. resources(source folder)中创建配置文件, log4j.properties ,添加下面的内容(直接拷贝)

  1. Global logging configuration log4j.rootLogger=ERROR, stdout
  2. 配置要打印日志的包 log4j.loggr..mybatis=TRACE
  3. Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

将配置中的 包路径修改为项目中对应的路径,我们这里可以使用: cn.mybatis

到此,我们每执行一条 SQL, 都会在控制台中打印出来,这非常有助于我们对 SQL 的分析,特别是 SQL 不正确的时候

7_抽取 MyBatisUtil 工具类

 JDBC 中的连接池使用一样,在整个项目中,我们只需要一个SqlSessionFactory对象,而不需要每次都创建一个新的,

所以,我们将SqlSessionFactory的创建和SqlSession对象的获取都抽取到工具类中: MyBatisUtil

注意:

加载配置文件没有填写:

8_抽取db.properties

在主配置文件中配置的内容较多, 其中包括我们修改频率较高的数据库连接信息(driver/url/username/password),我们可以在修改这些信息的过程中误改或者误删到其他的配置,为了解决这个问题,我们仍然是将这些信息配置到db.propertie配置文件中,然后再合并到主配置文件即可,如下:

db.properties

driverClassName=com.mysql.jdbc.Driver

url=jdbc:mysql://localhost:3306/javaweb

username=root

password=admin

mybatis-cofnig.xml

<configuration>

<!-- 关联db.properties:为了把连接数据库的信息单独放到一个配置文件 --> <properties resource="db.properties" />

<!-- 为指定包中的类来生成别名 -->

<typeAliases>

<package name="cn.domain"/> </typeAliases>

<!-- 连接数据库的环境

default:指定使用哪一个环境的配置

-->

<environments default="dev">

<environment id="dev">

<transactionManager type="JDBC"/>

<dataSource type="POOLED">

<!--

使用${key}取出db.properties中配置的信息

keydb.properties文件中的可以一直即可

-->

<property name="driver" value="${driverClassName}"/> <property name="url" value="${url}"/>

<property name="username" value="${username}"/> <property name="password" value="${password}"/>

</dataSource>

</environment>

</environments>

<!-- 关联映射文件 -->

<mappers>

<mapper resource="cn\mapper\ProductMapper.xml"/> </mappers>

</configuration>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

零基础学习MySQL---库的相关操作

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、创建数据库 1.语法 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] .…

使用selenium定位input标签下的下拉框

先来看一下页面效果&#xff1a;是一个可输入的下拉列表 再来看一下下拉框的实现方式&#xff1a; 是用<ul>和<li>方式来实现的下拉框&#xff0c;不是select类型的&#xff0c;所以不能用传统的select定位方法。 在着手定位元素前一定一定要先弄清楚下拉列表…

CocoaPodsCmake

https://juejin.cn/post/7257048145233838141?searchId20240531171431E5868B41DC7B7016CCBA https://guides.cocoapods.org CocoaPods CocoaPods的作用 帮助程序员通过命令管理第三方库及更新&#xff0c;以达到扩展项目的目的。 CocoaPods的使用 在已有的工程目录下新增…

JAVA:文件防重设计指南

1、简述 在现代应用程序中&#xff0c;处理文件上传是一个常见的需求。为了保证文件存储的高效性和一致性&#xff0c;避免重复存储相同的文件是一个重要的优化点。本文将介绍一种基于哈希值的文件防重设计&#xff0c;并详细列出实现步骤。 2、设计原理 文件防重的基本思路…

智能家居安防系统教学解决方案

前言 随着科技的不断进步和智能家居概念的深入人心&#xff0c;智能家居安防系统作为智能家居领域的重要组成部分&#xff0c;其重要性日益凸显。智能家居安防系统不仅能够提供环境和人员的监测功能&#xff0c;还能够采取措施降低或避免人员伤亡及财产损失。因此&#xff0c;…

leetcode216.组合总和III、40.组合总和II、39.组合总和

216.组合总和III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9 每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输出…

百日筑基第十一天-看看SpringBoot

百日筑基第十一天-看看SpringBoot 创建项目 Spring 官方提供了 Spring Initializr 的方式来创建 Spring Boot 项目。网址如下&#xff1a; https://start.spring.io/ 打开后的界面如下&#xff1a; 可以将 Spring Initializr 看作是 Spring Boot 项目的初始化向导&#xff…

实训学习错误总结2

1、 "timestamp": "2024-07-04T08:43:07.15400:00", "status": 405, "error": "Method Not Allowed", "path": "/wuzi/insert" 简单的来说就是使用的方法与注释不匹配。 规定的是&#xff1a;Get&a…

第20章 Mac+VSCode配置C++环境

1. 下载VSCode VSCode下载地址在mac终端里输入xcode- select --install命令,根据提示安装xcode工具。2. 安装插件(4个) 打开VScode,点击应用右侧菜单栏 C/C++(必装) Code Runner(必装) CodeLLDB(代码调试),不安装这个插件程序调试时,无法在vscode自带的终端里输入参…

redis学习(002 安装redis和客户端)

黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第5p-第p7的内容 文章目录 安装redis启动启动方式1&#xff1a;可执行文件启动启动方式2 基于配置文件启动修改redis配置文件 …

第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪

文章目录 第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪Web 网关中的 HTTP 跟踪第三方追踪工具 第四十七章 解决 IRIS 中的 SOAP 问题 - Web 网关中的 HTTP 跟踪 Web 网关中的 HTTP 跟踪 Web 网关管理页面可让跟踪 HTTP 请求和响应。请参阅使用 HTTP 跟踪工…

项目管理所需资料【资料分享】

项目管理基础知识 项目管理可分为五大过程组&#xff08;启动、规划执行、监控、收尾&#xff09;十大知识领域&#xff0c;其中包含49个子过程 项目十大知识领域分为&#xff1a;项目整合管理、项目范围管理、项目进度管理、项目成本管理、项目质量管理、项目资源管理、项目…

【BUUCTF-PWN】11-ciscn_2019_c_1

64位&#xff0c;开启了NX保护 执行效果如下&#xff1a; main函数 encrypt()函数 gets()函数存在栈溢出&#xff0c;但是中间部分代码会对传入的字符串做加密处理 中间的部分是对字符串进行处理&#xff0c;strlen的作用是得知字符串的长度&#xff0c;但是遇到’\0‘就…

C#委托事件的实现

1、事件 在C#中事件是一种特殊的委托类型&#xff0c;用于在对象之间提供一种基于观察者模式的通知机制。 1.1、事件的发送方定义了一个委托&#xff0c;委托类型的声明包含了事件的签名&#xff0c;即事件处理器方法的签名。 1.2、事件的订阅者可以通过运算符来注册事件处理器…

欧拉筛法与埃氏拉筛

如果我们想知道从零到一个数有哪些质数&#xff0c;我们首先会想到运用枚举法&#xff0c;将小于这个数的每个数都相乘一遍&#xff0c;这样的做法会大大降低我们程序的质数&#xff0c;增加时间&#xff0c;事实上&#xff0c;在我们之前就有许多人尝试运用另外的思维&#xf…

2pc 3pc

2pc&3pc问题 本质&#xff1a; 2pcTM超时机制 3pc加入事务询问机制RM超时机制 事务询问机制&#xff1a;减少阻塞 RM超时机制&#xff1a;避免死锁 2pc 3pc 参考&#xff1a; https://juejin.im/post/5aa3c7736fb9a028bb189bca#heading-1 https://blog.csdn.net/xj1…

【笔记】在window上连接虚拟机中的redis

愚昧啊 困扰了我近两天的问题居然是因为是java代码写错地方了 在虚拟机中进入redis.conf文件 vim redis.conf /bind --斜杠搜索关键词 将值设置为 bind 0.0.0.0 保存 退出:wq 回到java中 添加redis依赖 刷新maven 就是在这一步出问题……………………………………自己在蓝…

RK3568平台(opencv篇)ubuntu18.04上安装opencv环境

一.什么是 OpenCV-Python OpenCV-Python 是一个 Python 绑定库&#xff0c;旨在解决计算机视觉问题。   Python 是一种由 Guido van Rossum 开发的通用编程语言&#xff0c;它很快就变得非常流行&#xff0c;主要是 因为它的简单性和代码可读性。它使程序员能够用更少的代码行…

【踩坑】修复报错Cannot find DGL libdgl_sparse_pytorch_2.2.0.so

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 错误复现 原因分析 解决方法 错误复现 import dgldataset dgl.data.CoraGraphDataset() graph dataset[0] graph.adjacency_matrix() 原因分…

MySQL第二次作业

一、数据库 1、登陆数据库 2、创建数据库zoo 3、修改数据库zoo字符集为gbk 4、选择当前数据库为zoo 5、查看创建数据库zoo信息 6、删除数据库zoo 二、创建表 1、创建一个名称为db_system的数据库 2、在该数据库下创建两张表&#xff0c;具体要求如下 员工表 user 字段 类型 约…