教小师妹快速入门Mybatis,看这篇就够了
wptr33 2025-01-10 17:38 16 浏览
本文主要内容:
传统JDBC
传统JDBC编码格式
public class DataBaseUtil {
public static final String URL = "jdbc:mysql://localhost:3306/mblog";
public static final String USER = "root";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//2.
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.
Statement stmt = conn.createStatement();
//4.
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");
//如果有数据,rs.next()返回true
while(rs.next()){
System.out.println("name: "+rs.getString("name")+" 年龄:"+rs.getInt("age"));
}
}
}
上面代码中知识为了展示JDBC整个过程(异常和资源是简单粗暴的处理了,我们关注的点不在这两个)。
大致可以分为六个步骤:
- 加载驱动程序
- 获得数据库连接
- 创建一个Statement对象
- 操作数据库,实现增删改查
- 获取结果集
- 关闭资源
从使用层面来说,采用原生态的JDBC在项目中使用起来成本还是很高的。如果我们的项目中的业务相对比较复杂,数据库表也相对较多,各种操作数据库的增删改查的方法也会随之多起来,那么这样的代码重复次数会非常之多。
传统JDBC的问题
- 创建数据库的连接存在大量的硬编码,
- 执行statement时存在硬编码.
- 频繁的开启和关闭数据库连接,会严重影响数据库的性能,浪费数据库的资源.
- 存在大量的重复性编码
为了解决以上问题,就诞生了各种各样替换JDBC的产品。即就是ORM框架。
什么是ORM?
全称为Object Relational Mapping。对象-映射-关系型数据库。对象关系映射(,简称ORM,或O/RM,或O/R mapping),用于实现面向对象编程语言里不同类型系统的数据之间的转换。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射。
ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。
我们的项目中是这样的:
比如说:Apache DbUtils、Spring JDBC、 Hibernate、Ibatis(Mybatis的前生)、Spring Data Jpa等等。
目前最为流行的Mybatis和Spring Data Jpa。本系列我们先讲解Mybatis,Jpa后面再讲。
ORM的优缺点
优点1.提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。
缺点牺牲程序的执行效率和会固定思维模式,降低了开发的灵活性。
从系统结构上来看,采用ORM的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。在我们开发系统时,一般都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。ORM所生成的代码一般不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体现在对持久对象的提取和和数据的加工处理上,如果用上了ORM,程序员很有可能将全部的数据提取到内存对象中,然后再进行过滤和加工处理,这样就容易产生性能问题。在对对象做持久化时,ORM一般会持久化所有的属性,有时,这是不希望的。但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。但我们不能指望工具能一劳永逸的解决所有问题,有些问题还是需要特殊处理的,但需要特殊处理的部分对绝大多数的系统,应该是很少的。
MyBatis 是什么?
如果在面试的时候被问到,只要你说出下面三种即可。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
来自官网。
MyBatis的优点和缺点
优点:
(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(4)能够与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点
(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
Mybatis环境搭建及简单实例
创建一张数据库表
创建一张m_user表使用MySQL数据库。
CREATE TABLE `m_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
添加依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
</dependencies>
项目结构如下:
创建一个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/mblog?useUnicode=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
实体类User
ublic class User {
private Integer id;
private String name;
private Integer age;
//set get
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
创建UserMapper.java
import com.tian.mybatis.entity.User;
public interface UserMapper {
User selectUserById(Integer id);
}
创建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">
<mapper namespace="com.tian.mybatis.mapper.UserMapper">
<select id="selectUserById" resultType="com.tian.mybatis.entity.User">
select * from m_user where id = #{id}
</select>
</mapper>
创建一个测试类
import com.tian.mybatis.entity.User;
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;
import java.io.InputStream;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
SqlSession sqlSession =null;
try {
inputStream = Resources.getResourceAsStream(resource);
//工厂模式
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//sql操作会话
sqlSession = sqlSessionFactory.openSession();
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
sqlSession.close();
}
}
}
输出结果:
User{id=1, name='tian', age=22}
整体步骤:
另外一种启动方式
import com.tian.mybatis.entity.User;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//解析xml文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null, null);
//构建一个SqlSessionFactory工厂类
SqlSessionFactory sqlSessionFactory = build(parser.parse());
//创建一个SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
}
public static SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
输出和上面一样。还可以直接使用Java代码而不用mybatis-config.xml。
//创建数据源
DataSource dataSource = getDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
小总结
从上面这个案例中我们大致能猜到,Mybatis中最主要几个组件:
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
Mapper
SqlSessionFactoryBuilder这个类可以被初始、使用和丢弃,如果你已经创建好了一个 SqlSessionFactory后就不用再保留它。因此 ,SqlSessionFactoryBuilder 的最好作用域是方法体内,比如说定义一个方法变量。
你可以重复使用SqlSessionFactoryBuilder 生成多个 SqlSessionFactory 实例,但是最好不要强行保留,因为 XML 的解析资源要用来做其它更重要的事。
SqlSessionFactory一旦创建,SqlSessionFactory就会在整个应用过程中始终存在。所以没有理由去销毁和再创建它,一个 应用运行中也不建议多次创建 SqlSessionFactory。如果真的那样做,会显得很拙劣。
因此 SqlSessionFactory最好的作用域是 Application。可以有多种方法实现。最简单的方法是单例模式或者是静态单例模式。然而这既不是广泛赞成和好用的。反而,使用 Google Guice 或 Spring 来进行依赖反射会更好。这些框架允 许你生成管理器来管理 SqlSessionFactory的单例生命周期
SqlSession每个线程都有自己的 SqlSession 实例,SqlSession 实例是不能被共享,也是不是线程安全的。因此最好 使用 Request 作用域或者方法体作用域。
不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变更来引用。永远不要在一个被管理域中引用 SqlSession,比如说在 Servlet 中的HttpSession 中。如果你正在使用 WEB 框架,应该让 SqlSession 跟随 HTTP 请求的相似作用域。
也就是说,在收到一个 HTTP 请求过后,打开 SqlSession,等返回一个回应以后,立马关掉这个 SqlSession。关闭 SqlSession 是非常重要的。你必须要确保 SqlSession 在 finally 方法体中正常关闭。
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
使用这种模式来贯穿你的所有代码,以确保所有数据库资源都被完全关闭。
Mapper
Mapper 是一种你创建的用于绑定映射语句的接口。Mapper 接口的实例是用 SqlSession 来获得的。同样 , 从技术上来说,最广泛的 Mapper 实例作用域像 SqlSession 一样,使用请求作用域。确切地说,在方法 被调用的时候调用 Mapper 实例,然后使用后,就自动销毁掉。不需要使用明确的注销。当一个请求执 行正确无误的时候,像 SqlSession 一样,你可以轻而易举地操控这一切。保持简单性,保持 Mapper 在 方法体作用域内。
//获取数据并解析成User对象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
这里映射涉及到四个主体:
- 实体类User。
- 接口UaerMapper。
- xml配置文件UserMapper。
- 数据库表m_user
Mybatis的五部曲:
总结
回顾JDBC的demo,JDBC中的问题,创建一个Mybatis示例,总结出重要的四个组件,以及每个组件的作用。
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见!答案获取方式:已赞 已评 已关~
学习更多JAVA知识与技巧,关注与私信博主(03)
相关推荐
- 如果手机显示无SIM卡,到底是什么意思呢?
-
一般手机显示无可用SIM卡,可能是如下原因造成的,大家可以了解下,并且进行解决。第一个,SIM卡未正确插入:我们需要检查SIM卡是否已正确插入手机。如果SIM卡没有完全插入,或者插反了,手机可能会显...
- 赶紧设置!工信部提醒设置手机SIM卡密码
-
【赶紧设置!工信部提醒设置手机SIM卡密码】平安法治2020近日,针对网友反映的手机失窃导致信息泄露事件,国家工信部立即组织核查处理,要求电信企业加强安全防护,并提醒手机用户设置SIM卡密码。...
- 手机突然显示无SIM卡?这样做就能恢复~
-
大家有没经历过明明SIM卡在卡槽里放得好好的,手机却突然显示无SIM卡的状况?没有了SIM卡手机就失去了灵魂,打电话、上网的功能都不能用了。这到底是怎么一回事儿?让小翼帮你来解答~什么是SIM卡?SI...
- SK电讯首尔门店遭“围攻”,SIM卡更换服务陷混乱
-
据yna.co.kr网4月28日报道,28日,韩国SK电讯推出免费SIM卡更换服务以应对网络安全风险,首尔光化门店门前清晨8点便已排起长队。原定于上午10点开始的服务因企业员工需求激增,提前至9点启动...
- Springboot特性、快速创建SpringBoot应用、Starter简介
-
SpringBoot基础本章我们将揭开SpringBoot的神秘面纱。...
- Springboot2的熔断、限流和降级讲解
-
高可用的三大利器是熔断、限流和降级。它们都是在分布式系统中用于保障系统稳定性和可用性的重要策略。熔断(CircuitBreaker):熔断是一种防止故障扩散的机制。当一个服务出现故障或超时,熔断器会...
- Spring Cloud 全面解析:分布式系统开发的魔法工具包
-
SpringCloud全面解析:分布式系统开发的魔法工具包SpringCloud是Java开发者构建分布式系统的得力助手。它基于SpringBoot,为开发者提供了强大的微服务架构支持...
- 真香!GitHub开源SpringCloud Alibaba全解(全彩版)先到先得!
-
SpringCloudAliababa简介SpringCloudAlibaba是阿里巴巴集团开源的一套微服务架构解决方案。...
- 聊聊langchain4j-spring的1.0.0-beta版本的更新
-
序本文主要研究一下langchain4j-spring的1.0.0-beta版本的更新1.0.0-beta1...
- Java异步编程(5种异步实现方式详解)
-
Java面试经常会问到:异步操作?什么是异步?与同步有什么区别?Java异步的是如何实现?有哪些异步实现方式?下面我一一来详解异步@mikechen什么是异步?...
- 全部开源的快速开发平台-开源字节
-
《硕宇精选》专注于探索、发现、分享开源技术应用和优质开源项目。本期推荐的优质项目是开源字节是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。该平台基于SpringBoot+MyBat...
- Trip.com launches 700 products in 15 countries
-
OnlinetravelagencyTrip.comhasofferedmorethan700newoverseasproducts,visiting15countries...
- Spring事务
-
使用Spring事务Spring事务介绍Spring事务的特点:1.多种事务API,Spring事务都可兼容;2.程序接入简单;3.与已有的Spring框架集成。...
- 牛刀小试——五分钟入门Spring Boot
-
万物皆可HelloWorld在一个程序员的眼里,万物皆可HelloWorld。SpringBoot当然也不例外。下面一起来完成我们的第一个SpringBoot程序。...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
-
- 如果手机显示无SIM卡,到底是什么意思呢?
- 赶紧设置!工信部提醒设置手机SIM卡密码
- 手机突然显示无SIM卡?这样做就能恢复~
- SK电讯首尔门店遭“围攻”,SIM卡更换服务陷混乱
- Spring新闻汇总:Framework、Data、Security、Integration和Modulith发布里程碑版本
- Springboot特性、快速创建SpringBoot应用、Starter简介
- Springboot2的熔断、限流和降级讲解
- Spring Cloud 全面解析:分布式系统开发的魔法工具包
- 真香!GitHub开源SpringCloud Alibaba全解(全彩版)先到先得!
- 聊聊langchain4j-spring的1.0.0-beta版本的更新
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mysql max (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)