目录
ORM思想(对象关系映射思想)
初识MyBatis
什么是MyBatis呢?
JDBC VS MyBatis代码
获取数据库连接对比
对表格查询操作:
JDBC弊端
MyBatis,JDBC对比
MyBatis进一步介绍以及本质分析
JDBC编程的劣势,MyBatis提供了以下解决方案
MyBatis环境搭建
配置依赖案例演示:
MyBatis环境搭建步骤
我的第一个MyBatis
项目树
mybatis-config.xml文件
UserMapper.xml文件
db.properties文件
pom.xml文件
ORM思想(对象关系映射思想)
ORM(对象关系映射)是一种编程思想和技术,用于将关系型数据库(也就是MySQL等数据库)中的表结构映射到面向对象编程语言中的对象模型。我们介绍的MyBatis框架也是实现了ORM思想的;
初学Java时,我们学过Java的主要思想,“万事万物皆对象”,呢么在这里,实际上就是将数据库中的表也抽象成一个对象,这样就避免了操作数据库中的表格繁琐的过程,直接通过Java对象调方法的操作表中的数据;比如User类对应t_user表如下图:
ORM思想图解(图来自动力节点课堂笔记)
ORM 的基本思想是通过定义对象和数据库表之间的映射关系,使得开发人员可以像操作对象一样操作数据库,而不需要直接编写SQL语句。
ORM 的优点包括:
-
简化开发:ORM 提供了一种易于理解和使用的编程模型,开发人员可以直接使用对象的方法和属性来操作数据库,从而免去了复杂的SQL语句和数据库细节。
-
提高可维护性:通过将数据库和应用程序的逻辑分离,使得代码更加模块化和可维护。当数据库结构改变时,只需更新映射定义,而不需要修改大量的业务逻辑代码。
-
提高可移植性:ORM 可以隐藏不同数据库之间的差异,使得应用程序可以比较容易地切换或同时支持多种数据库。
-
提供对象级的查询和持久化:ORM 不仅提供了方便的增删改查操作,还支持复杂的查询和关联操作,可以方便地处理对象之间的关系。
除MyBatis外常见的其他ORM框架包括Hibernate(Java)、Django ORM(Python)、Entity Framework(.NET)等。这些框架都提供了一套映射规则和API,使得开发人员可以更轻松地进行数据库操作,提高开发效率和代码质量。
初识MyBatis
什么是MyBatis呢?
我在之前学完java基础之后,学习了Javaweb,随后学习了使用java连接数据库的技术JDBC,JDBC就是连接数据库的一种工具,然而MyBatis实际上就是对JDBC的再一次封装,他大大的节约了代码的书写量,以及改进了JDBC在实际使用中的一些弊端;
简单来说什么是Mybatis呢?Java有个万事万物皆对象的说法,即将Java操作的事务都抽象出该事务为一个对象,该对象有关的一切操作(删除表中数据、加入一条数据等等),在Java中都被封装成一个一个的方法(到时只需对象调方法即可),呢么此处的操作数据库也是一样的,我们之间学过JDBC,所谓MyBatis就是将JDBC封装成一些对象和一大堆方法,然后将JDBC中的一些需要程序员自己书写的重复繁琐的代码封装成对象中的方法,比如连接数据库(获取connection对象)、调用preparedstatement执行sql语句、获取结果集时的繁琐步骤等等。
JDBC VS MyBatis代码
我们上面一直使用文字来描述mybatis的优点,节省代码量等等,这些都不直观,下面我们通过代码来对比出二者的优缺点:
获取数据库连接对比
public class DBUtil {//静态变量是类加载时运行,有顺序;private static ResourceBundle bundle=ResourceBundle.getBundle("resources.jdbc");private static String url = bundle.getString("url");private static String user = bundle.getString("user");private static String password = bundle.getString("password");private static String driverClass = bundle.getString("driverClass");static{//注册驱动//只需要进行一次,在类加载时执行//Class.forName("com.mysql.jdbc.Driver");方法的参数别写死,不然后期很难扩展;什么是OCP,在进行功能扩展的时候,不需要修改源代码;try {Class.forName(driverClass);} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {//获取连接Connection conn = DriverManager.getConnection(url, user, password);return conn;}public static void close(Connection conn, Statement ps, ResultSet rs){if(rs!=null){try {rs.close();}catch (Exception e){e.printStackTrace();}}if(ps!=null){try {ps.close();}catch (Exception e){e.printStackTrace();}}if(conn!=null){try {conn.close();}catch (Exception e){e.printStackTrace();}}}
}
然而在MyBatis中我们只需要在mybatis-config.xml文件中配置以下信息即可,具体细节我们不需要关心,MyBatis程序员已经在底层为我们做好了,如果需要对大量数据库操作,可见二者代码量的差距,很直观mybatis避免了繁琐的代码,以及繁琐的实现细节;
<properties resource="db.properties"/> <transactionManager type="JDBC"/> <property name="driver" value="${mysql.driver}"/><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.username}"/><property name="password" value="${mysql.password}"/>
对表格查询操作:
public Dept selectByno(int no) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;Dept dept =null;try {conn = DBUtil.getConnection();String sql = "select dname,loc from dept1 where deptno=? ";ps = conn.prepareStatement(sql);ps.setInt(1, no);rs = ps.executeQuery();dept = new Dept();while (rs.next()) {String dname = rs.getString("dname");String loc = rs.getString("loc");dept.setDeptno(no);dept.setDname(dname);dept.setLocation(loc);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(conn, ps, rs);}return dept;}
在mybatis中我们只需要在***Mapper.xml文件中配置标签和查询语句即可,避免了大量的创建对象和大量繁琐的过程,这一个操作不得已看出mybatis的优势,然而实际需求中当有数以万计的表格和操作之后,二者的代码量,可见mybatis的优势;
JDBC弊端
1、 连接数据库时需要频繁的创建连接,并释放连接;
2、 项目中的sql语句都是硬编码,违背了开闭原则,所谓开闭原则就是强调软件实体(类、模块、函数等)应该对扩展开放,对修改关闭;
3、 使用preparedstatement对象处理sql语句时(使用占位符来为参数占位,然而参数的个数是动态的),根据参数的个数不同,需要不时地的修改代码,或者书写很多冗余的代码;
4、 项目中一旦SQL语句变化,也要在底层改动很多地方(不同的SQL语句得到的结果集都会不同,因此处理结果集的代码就会有所不同);
5、 查询后得到的结果集,转换成对应的java类需要很负责的步骤;(处理结果集过程)
MyBatis,JDBC对比
相对于 MyBatis,JDBC 的一些缺点包括:
1、 冗余的代码:JDBC 需要手动编写大量的重复性代码,如数据库连接和关闭、SQL语句的拼接、结果集的处理等,使开发过程显得冗长而繁琐。
2、 容易出现安全问题:由于需要手动拼接 SQL 语句,存在 SQL 注入的风险。开发人员必须小心防范并处理 SQL 注入攻击,增加了安全风险。
3、 处理事务困难:JDBC 需要手动管理事务,包括事务的开启、提交和回滚。在复杂的业务操作中,需要编写大量的事务管理代码,容易出错且难以维护。
4、 面向细节:JDBC 是低层次的API,需要开发人员手动处理数据库的细节,如连接池管理、异常处理、批量操作等。这增加了开发的复杂性和难度,容易出现错误和性能问题。
相对于 JDBC,MyBatis 是一个优秀的 ORM 框架,它克服了上述问题,提供了更高级别的抽象和便利,具有以下优点:
1、 声明式的 SQL:MyBatis 使用 XML 或注解来定义 SQL 语句,并提供了强大的动态 SQL 功能,简化了 SQL 的编写和维护。
2、 简化的数据库操作:MyBatis 提供了简洁的 API,将数据库连接、SQL 执行、结果集映射等细节封装起来,减少了冗余的代码量。
3、 对象关系映射:MyBatis 支持对象关系映射,可以将查询结果直接映射为对象,方便了开发人员对数据库结果的操作和处理。
4、 缓存机制:MyBatis 内置了缓存机制,可以缓存查询结果,提高系统的性能和响应速度。
5、 声明式事务:MyBatis 提供了声明式事务管理的支持,通过配置和注解实现事务的开启、提交和回滚,简化了事务管理的操作。
综上所述,相对于 JDBC,MyBatis 提供了更高级别的抽象和便利,简化了数据库操作,提高了开发效率和代码的可维护性。
MyBatis进一步介绍以及本质分析
MyBatis作为一个优秀的持久层框架,它对JDBC操作数据率的过程进行了封装,使开发者只需要关注SQL本身,而不需要花费精力去处理注册驱动 创建Connertion对象、创建Statement对象、手动设置参数结果集检索等JDBC繁杂的过程代码。
JDBC编程的劣势,MyBatis提供了以下解决方案,具体如下。
问题一:频繁地创建、释放数据库连接会造成系统资源浪费,从而影响系统性能。
解决方案:在SqlMapConfig.xml 中配置数据连接池,使用数据库连接池管理数据库连接
问题二:代码中的SQL语句硬编码,会造成代码不易于维护。在实际应用的开发中,SOL变化的可能性较大。在传统JDBC编程中,01变动金发更改nva代码,违反了开闭原则。软件实体对打
解决方案:MyBatis将SQL语句配置在MyBatis的映射文件(***mapper.xml文件)中,实现了与Java代码的分离。
问题三:使用PreparedStatement向占位符传参数存在硬编码,因为SQL语句的where条件不确定,如果有修改SQL的需求,必须要修改代码,这样会导致系统难以维护。
解决方案:MyBatis自动将Java对象映射至SQL语句,通过Statement中的 parameterType定义输入参数的类型。
问题四:JDBC对结果集解析存在硬编码(查询列名),SQL变化导致解析代码变化,使得系统不易于维护
解决方案:MyBatis自动将SQL执行结果映射至Java对象,通过Statement中的resultType定义输出结果的类型。
MyBatis环境搭建
创建工程,引入依赖(因为学过Maven技术,所以无须自己下载MyBatis驱动jar包,只需要在配置文件(pom.xml)中配置即可)使用Maven仓库技术;
这里插入一个小知识点:工程(project)和模块(module)的关系是,一个工程(project)可以包含多个模块(module);
配置依赖案例演示:
MyBatis环境搭建步骤
1、 创建工程
2、 引入驱动jar包(Maven仓库技术)
3、 创建对应的数据库中的数据表格
4、 创建数据库连接信息配置文件,db.properties文件
5、 创建MyBatis的核心配置文件(mybatis——config.xml文件)这个文件一个模块中仅有一个
我的第一个MyBatis
具体实现步骤:
1、 创建数据库中的数据
2、 创建pojo实体、或者也可以称为Javabean或者dao
3、 创建映射文件***Mapper.xml文件(一个模块中可能会处理多张表格,其中一个表格对应一个Mapper.xml文件)
4、 将***Mapper.xml文件的路径配置到MyBatis-config.xml文件中
5、 在项目的test路径下编写测试代码
项目树
mybatis-config.xml文件
<?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><!-- 加载类路径下的属性配置文件 --><properties resource="db.properties"/><!-- 默认使用的环境 ID(比如:default="development")也就是说我们可以配置多套<environment>环境--><environments default="development"><!--每个 environment 元素定义的环境 ID--><environment id="development"><!--transactionManager 事务管理器type的值有JDBC和MANAGEDJDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。--><transactionManager type="JDBC"/><!--dataSourcedataSource 数据源 dbcp c3p0 druidtype="[UNPOOLED|POOLED|JNDI]"POOLED意思有连接池的连接UNPOOLED意思没有连接池的连接--><dataSource type="POOLED"><!-- JDBC 驱动--><property name="driver" value="${mysql.driver}"/><!-- url数据库的 JDBC URL地址。--><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.username}"/><property name="password" value="${mysql.password}"/><!-- defaultTransactionIsolationLevel – 默认的连接事务隔离级别。–>--><!-- <property name="defaultTransactionIsolationLevel" value=""/>--><!-- defaultNetworkTimeout – 等待数据库操作完成的默认网络超时时间(单位:毫秒)–>--><!-- <property name="efaultNetworkTimeout" value=""/>--></dataSource></environment></environments><mappers><!-- 使用相对于类路径的资源引用 --><mapper resource="mapper/UserMapper.xml"/><!-- 使用完全限定资源定位符(URL)不推荐使用<mapper url="E:\JetBrains\mybatis学习\Mybatis-study\Mybatis-03\src\main\java\asia\xiaojiang\mybatis03\dao\UserMapper.xml"/>--><!-- 使用映射器接口实现类的完全限定类名使用注意点:接口和其配置文件必须同名, 必须在同一个包下-->
<!-- <mapper class="asia.xiaojiang.mybatis03.dao.UserMapper"/>--><!-- 将包内的映射器接口实现全部注册为映射器使用包扫描注意点:接口和其配置文件必须同名, 必须在同一个包下--><!-- <package name="asia.xiaojiang.mybatis03.dao"/>--></mappers></configuration>
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指定Dao接口的完整类名,mybatis会根据这个接口动态的创建一个实现类去实现这个接口,而这个实现类是一个Mapper对象-->
<mapper namespace="com.lyp.pojo.User"><!--定义接口方法对应的 SQL 语句--><select id="findById"parameterType="int" resultType="com.lyp.pojo.User">select * from users where uid=#{id}</select></mapper>
db.properties文件
mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&\characterEncoding=utf8&useUnicode=true&useSSL=false
mysql.username=root
mysql.password=123456
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>MyBatis</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>18</maven.compiler.source><maven.compiler.target>18</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><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.11</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>