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

MyBatis从浅入深

目录

框架概述

MyBatis框架快速入门

​编辑

​编辑

​编辑

​编辑

MyBatis框架Dao代理

​编辑

MyBatis框架动态Sql

MyBatis配置文件

扩展

使用步骤


框架概述

  • 三层架构
    • 界面层(User Interface layer):和用户打交道的,接收用户的请求参数,显示处理结果的。(jsp,html,servlet)
    • 业务逻辑层(Business Logic layer):接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
    • 数据访问层(Data access layer):就是访问数据库,执行对数据的查询,修改,删除等等。

  • 三层对应的包
    • 界面层:controllerbao包(Servlet类)
    • 业务逻辑层:service包(Service类)
    • 数据访问层:dao包(Dao类)

  • 三层中类的交互
    • 用户使用界面层--->业务逻辑层--->数据访问层(持久层)--->数据库(MySql)

  • 三层对应的处理框架
    • 界面层---servlet---springmvc
    • 业务逻辑层---service类---spring
    • 数据访问层---dao类---mybatis

框架是一个舞台,一个模板

  • 模板
    • 规定好了一些条款,内容。
    • 加入自己的东西

  • 框架是一个模板
    • 框架中定义好了一些功能,这些功能是可用的。
    • 可以加入项目中自己的功能,这些功能可以利用框架中写好的功能。

框架是一个软件,半成品的软件,定义好了一些基础功能,需要加入你的功能就是完整的。

基础功能时可重复使用的,可升级的。

  • 框架特点:
    • 框架一般不是全能的,不能做所有事情
    • 框架是针对某一个领域有效。特长在某一个方面,比如mybatis做数据库操作强,但是他不能做其他的。
    • 框架是一个软件

  • 使用JDBC的缺陷
    • 代码比较多,开发效率低
    • 需要关注Connection,Statement,ResultSet对象创建和销毁
    • 对ResultSet查询的结果,需要自己封装为List
    • 重复的代码比较多些
    • 业务代码和数据库的操作混在一起

  • Mybatis框架
    • 一个框架,早起叫做iBatis,代码在github
    • MaBatis是 MyBatis SQL Mapper Frameword for Java (sql映射框架)
    • sql mapper :sql映射
      • 可以把数据库表中的一行数据,映射为一个java对象。
      • 一行数据可以看做是一个java对象,操作这个对象,就相当于操作表中的数据
    • Data Access Object (DAOs) :数据访问,对数据库执行增删改查

  • MyBatis提供了那些功能:
    • 1、提供了创建Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了
    • 2、提供了执行sql语句的能力,不用你执行sql
    • 3、提供了循环sql,把sql的结果转为java对象,List集合的能力
    • 4、提供了关闭资源的能力,不用你关闭Connection,Statement,ResultSet

开发人员做的是:提供sql语句

最后是:开发人员提供sql语句--MyBatis处理sql--开发人员得到List集合或Java对象(表中的数据)

  • 总结:
    • MyBatis是一个sql映射框架,提供的数据库的操作能力,增强的JDBC。
    • 使用MyBatis让开发人员集中精神写sql就行了,不必关心Connection,Statement,ResutSet的创建,销毁,sql的执行

MyBatis框架快速入门

  • 主要类的介绍
    • 1、Resources:mybatis中的一个类,负责读取主配置文件
      • InputStream in = Resources.getResourceAsStream("mybatis.xml");
    • 2、SqlSessionFactoryBuilder:创建SqlSessionFactory对象
      • SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
      • //创建SqlSessionFactory对象
      • SqlSessionFactory factory = builder.build(in);
    • 3、SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就够用了
      • SqlSessionFactory:接口,接口实现类:DefaultSqlSessionFactory
      • SqlSessionFactory作用:获取SqlSession对象。
      • SqlSession sqlSession = factory.openSession();
      • openSession()方法说明:
        • 1、openSession():无参数的,获取是非自动提交事务的SqlSession对象
        • 2、openSession(boolean):openSession(true) 获取自动提交事务的SqlSession

openSession(false) 获取非自动提交事务的SqlSession

  • 4、SqlSession:
    • SqlSession接口:定义了操作数据的方法 例如 seelctOne(), selectList(), insert(), update(), delete(), commit(), rollback()
    • SqlSession接口的实现类DefaultSqlSession
    • 使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象,在执行完sql语句后,需要关闭它,执行SqlSession.close(),这样能保证它的使用时线程安全的。

MyBatis框架Dao代理

  • MyBatis动态代理
    • 使用SqlSession.getMapper(dao接口.class) 获取这个dao接口的对象

  • 传入参数:从java代码中把数据传入到mapper文件的sql语句中
    • parameterType:写在mapper文件中的一个属性。表示dao接口中方法的参数的数据类型。
    • 例如 StudentDao接口:Student selectStudentById(Integer id);
    • 对应的mapper文件中的parameterType: paramterType="java.lang.Integer"
    • parameterType:dao接口中方法参数的数据类型。
    • parameterType它的值是java的数据类型全限定名称或者是mybatis定义的别名
    • 例如:parameterType="java.lang.Integer"

    parameterType="int"

  • 注意parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型。所以可以没有,一般我们也不写。
  • 一个简单类型的参数
    • 简单类型:mybatis把java的基本数据类型和String都叫简单类型
    • 在mapper文件获取简单类型的一个参数的值,使用#{任意字符}
    • 接口: Student selectStudentById(Integer id)
    • mapper:select id,name,email,age from student where id = #{studentId}

  • 多个参数,使用@Param命名参数
    • 接口中的方法:List<Student> selectMultipleParam(@Param("myName") String name,@Param("myAge")  Integer age)
    • 在形参定义的前面加入  @Param("自定义参数名称") 
    • mapper 文件:
      • <select>
        • select * from student where name = #{myName}  or age = #{myAge}
      • </select>
  • 多个参数,使用java对象的属性值,作为参数实际值
    • 接口中的方法:List<Student> selectMultipleObject(Object object);
    • 使用对象语法:#{属性名,javaType=类型名称,jdbcType=数据类型}  很少用

javaType:指java中的属性数据类型

jdbcType:在数据库中的数据类型

例如:#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}

  • 我们使用的简化方式:#{属性名} ,javaType,jdbcType的值mybatis反射能获取。不用提供

  • 多个参数,简单类型的,按位置传值
    • mybatis.3.4之前,使用 #{0} ,#{1}
    • mybatis.3.4之后,使用 #{arg0} ,#{arg1}
    • 接口中的方法:List<Student> selectMultiplePosition(String name,Integer age);
    • mapper:
      • <select>
        • select id,name,email,age from student where name = #{arg0} or age = #{arg1}
      • </select>
  • 多个参数,使用Map存放多个值
    • 在mapper中使用map集合的key作为参数
    • 接口中的方法:List<Student> selectMultipleByMap(Map<String,Object> map);
    • mapper:
      • <select>
        • select id,name,email,age from student where name = #{myName} or age = {myAge}
      • </select>

  • 两个占位符 # 和 $
    • #:占位符,告诉mybatis使用实际的参数值代替。并使用PreparedStatement对象执行sql语句,#{…}代替sql语句的  '?'。这样做更安全,更迅速,通常也是首选做法。
    • $:字符串拼接,告诉mybatis使用$包含的字符串替换所在位置。使用Statement把sql语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。
    • select id,name,email,age from student where id = #{studentId}
    • # 的结果是:select id,name,email,age from student where id = ?
    • $ 的结果是:select id,name,email,age from student where id = 1001
    • String sql  = "select id,name,email,age from student where id = " + "1001";
    • 使用的Statement对象执行sql,效率比PreparedStatement低。
  • # 和 $的区别
    • #使用 ?在sql语句中做占位的,使用PreparedStatement执行sql,效率高。
    • #能够避免sql注入,更安全。
    • $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
    • $有sql注入的风险,缺乏安全性
    • $可以替换表名或者列名,你能确定数据是安全的,可以使用$

  • mybatis的输出结果,resultType
    • resultType的默认原则是 同名的列 值赋值给同名的属性
    • resultType:执行sql得到ResultSet转换的类型,使用类型的完全限定名或别名。注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap 不能同时使用。
    • resultType结果类型,指sql语句执行完毕后,数据转为的java对象,java类型是任意的。
    • resultType结果类型的值
      • 1、类型的全限定名称
      • 2、类型的别名  例如 java.lang.Integer  别名是 int
    • 处理方式:
      • 1、mybatis执行sql语句,然后mybatis调用类的无参数构造方法,创建对象。
      • 2、mybatis把ResultSet指定列值付给同名的属性。

  • 定义别名,在mybatis.xml 主配置文件中设置
    • 第一种方式
      • 可以指定一个类型一个自定义别名
      • type:自定义类型的全限定名称
      • alias:别名
      • <typeAliases>
        • <typeAlias type="com.li.domain.Student" alias="stu" />
      • </typeAliases>
    • 第二种方式
      • name是包名,这个包中的所有类,类名就是别名(类名不区分大小写)
      • <typeAliases>
        • <package name="com.li.domain" />
      • </typeAliases>

  • 当返回值为Map时,不建议返回Map
    • 列名是map的key,列值是map的value
    • 只能最多返回一行记录,多余一行就会报错
    • 接口中的方法: Map<Object,Object>  selectStudentById(@Param("stuId") Integer id);
    • mapper:
      • <select id="selectStudentById" resultType="map">
        • select id,name,email,age from student where id = #{stuId}
      • </select>

  • resultMap:结果映射,指定列名和java对象的属性对应关系。
    • 1、你自定义列值赋值给哪个属性
    • 2、当你的列名和属性名不一样时,一定使用resultMap
    • 也可以将查询后的列名改为别名,与java对象的属性相对应
  • resultMap的使用
    • 1、先定义resultMap
    • 2、在select标签,使用resultMap来引用定义好的resultMap
    • 定义resultMap
      • id:自定义名称,表示你定义的这个resultMap
      • type:java类型的全限定名称
      • <resultMap id="studentMap" type="com.li.domain.Student">
        • <!--列名和java属性的关系-->
        • <!-- column:列名,property:java类型的属性名 -->
        • <!--  id为主键列,result为非主键列 -->
        • <id column="id" property="id" />
        • <result column="name" property="name" />
        • <result column="email" property="email" />
        • <result column="age" property="age" />
      • </resultMap>
    • 使用resultMap
      • <select id="selectStudents" resultMap="studentMap">
        • select id,name,email,age from student
      • </select>

MyBatis框架动态Sql

  • 动态sql:
    • 使用java对象作为参数
    • sql的内容是变化的,可以根据条件获取到不同的sql语句。
    • 主要是where部分发生变化

动态sql的实现,使用的是mybatis提供的标签,<if>,<where>,<foreach>

  • <if>是判断条件的
    • <if test="使用参数java对象的属性值作为判断条件">
      • 部分sql语句
    • </if>
    • 例如:
      • <select id="selectStudentIf" resultType="com.li.domain.Student">
        • select id,name,email,age from student where
        • <if test="name != null and name != '' ">
          • name = #{name}
        • </if>
        • <if test="age > 0">
          • or age > #{age}
        • </if>
      • </select>

  • <where>标签
    • 用来包含多个<if>的,当多个if有一个成立的,<where>会自动增加一个where关键字,并去掉if中多余的 and ,or等。
    • 例如:
      • <select id="selectStudentWhere" resultType="com.li.domain.Student">
        • select id,name.email,age from student
        • <where>
          • <if  test="name != null and name != '' ">

name = #{name}

  • </if>
  • <if test="age > 0">
    • or age > #{age}
  • </if>
  • </where>
  • </select>

  • <foreach>标签
    • 循环java中的数组,list集合。主要用在sql的in语句中。
    • select * from student where id in (1001,1002,1003);
    • 语法:
      • collection:表示接口中的方法参数的类型,如果是数据使用array,如果是List集合使用list
      • item:自定义的,表示数组和集合成员的变量
      • open:循环开始时的字符
      • close:循环结束时的字符
      • separator:集合成员之间的分隔符
      • <foreach collection="" item="" open="" close="" separator="">
      • </foreach>
    • 基本数据类型例子:
      • <select id="selectStudentForeach" resultType="com.li.domain.Student">
        • select id,name,email,age from student where id in
        • <foreach collection="list" item="myId" open="(" close=")" separator=",">
          • #{myId}
        • </foreach>
      • </select>
    • 引用数据类型例子:
      • <select id="selectStudentForeach" resultType="com.li.domain.Student">
        • select id,name,email,age from student where id in
        • <foreach collection="list" item="stu" open="(" close=")" separator=",">
          • #{stu.id}
        • </foreach>
      • </select>

  • 代码片段
    • <sql>标签用于定义sql片段,以便其他sql标签复用。而其他标签使用该sql片段,需要使用<include>字标签。该<sql>标签可以定义sql语句中的任何部分,所以<include>子标签可以放在动态sql的任何位置。
    • 就是复用一些语句
    • 使用步骤
      • 1、先定义<sql id="自定义名称唯一" >   sql语句  </sql>
      • 2、在使用,<include refid="id的值" />
    • 例如:
      • <sql id="studentSql">
        • select id,name,email,age from student
      • </sql>
      • <select id="selectStudentSqlFragment" resultType="com.li.domain.Student">
        • <include refid="studentSql" />  where name = #{myName}
      • </select>

MyBatis配置文件

  • transactionManager
    • type:事务的处理的类型
      • JDBC:表示mybatis底层是调用JDBC中的Connection对象的,commie,rollback
      • MANAGED:把mybatis的事务处理委托为其他的容易(一个服务器软件,spring)

  • dataSource
    • 表示数据源,java体系中,规定了实现javax.sql.DataSource接口的都是数据源。
    • 数据源表示Connection对象的。
    • type:指定数据源的类型
      • POOLED:使用连接池,mybatis会创建PooledDataSource类
      • UPOOLED:不使用连接池,在每次执行sql语句,先创建连接,执行sql,再关闭连接,mybatis会创建一个UnPooledDataSource,管理Connection对象的使用
      • JNDI:java命令和目录服务(windows注册表)
  • 数据库的属性配置文件:
    • 把数据库连接信息放到一个单独的文件中,和mybatis主配置文件分开。
    • 目的是便于修改,保存,处理多个数据库的信息。
    • 在resources目录下定义一个属性配置文件,xxxx.properties
      • 在属性配置文件中,定义数据,格式是 key=value
      • key:一般使用 . 作为多级目录的
      • 例如:
        • jdbc.driver=com.mysql.jdbc.Driver
        • jdbc.url=jdbc:mysql://localhost:3306/myabtis
        • jdbc.username=root
        • jdbc.password=1212
    • 在mybatis的主配置文件,使用<properties> 指定文件的位置
      • <!--指定properties文件的位置,从类路径根开始找文件-->
      • <properties  resource="jdbc.properties" />
      • 在需要使用值的地方,使用 ${key}
  • mapper的位置
    • 第一种方式:指定多个mapper文件
      • <mappers>
        • <mapper resource="com/li/dao/StudentDao.xml" />
        • <mapper resource="com/li/dao/OrderDao.xml" />
      • </mappers>
    • 第二种方式:使用包名
      • name:xml文件所在的包名,这个包中所有的xml文件一次都能加载给mybatis
      • 使用package的要求:
        • 1、mapper文件名称需要和接口名称一样,区分大小写
        • 2、mapper文件和dao接口需要在同一目录下
      • <mappers>
        • <package name="com.li.dao" />
        • <package name="com.li.dao2" />
      • </mappers>

扩展

  • PageHelper:做数据分页的,不是mybatis框架的,是一个牛人写的组件
    • 在pom.xml文件中加入
      • <dependency>
        • <groupId>com.github.pagehelper</groupId>
        • <artifactId>pagehelper</artifactId>
        • <version>5.1.10</version>
      • </denpendency>
    • 在主配置文件mybatis.xml的  <environments> 之前加入
      • <plugins>
        • <plugin interceptor="com.github.pagehelper.PageInterceptor" />
      • </plugins>

使用步骤

http://www.lryc.cn/news/594465.html

相关文章:

  • day24——Java高级技术深度解析:单元测试、反射、注解与动态代理
  • 高性能熔断限流实现:Spring Cloud Gateway 在电商系统的实战优化
  • `SearchTransportService` 是 **协调节点与数据节点之间“搜索子请求”通信的运输层**
  • 4种快速创建SpringBoot项目的方法
  • Claude Code 逆向工程分析,探索最新Agent设计
  • JavaScript 中Object、Array 和 String的常用方法
  • 金融工程、金融与经济学知识点
  • 数据结构与算法汇总
  • 连接语言大模型(LLM)服务进行对话
  • GaussDB select into和insert into的用法
  • 机器学习基础:从数据到智能的入门指南
  • python生成密钥
  • Self-Consistency:跨学科一致性的理论与AI推理的可靠性基石
  • An End-to-End Attention-Based Approach for Learning on Graphs NC 2025
  • JAVA面试宝典 -《API设计:RESTful 与 GraphQL 对比实践》
  • 《通信原理》学习笔记——第五章
  • 【1】YOLOv13 AI大模型-可视化图形用户(GUI)界面系统开发
  • Openlayers 面试题及答案180道(121-140)
  • 让不符合要求的任何电脑升级Windows11
  • 【LeetCode数据结构】单链表的应用——环形链表问题详解
  • WireShark抓包分析TCP数据传输过程与内容详解
  • 使用Qt6 QML/C++ 和CMake构建海康威视摄像头应用(代码开源)
  • 【GameMaker】GML v3 的现行提案
  • FreeRTOS任务创建与删除
  • Python 图片爬取入门:从手动下载到自动批量获取
  • Selenium 处理动态网页与等待机制详解
  • 复杂度优先:基于推理链复杂性的提示工程新范式
  • AUTOSAR进阶图解==>AUTOSAR_SWS_CryptoInterface
  • 【Java学习|黑马笔记|Day18】Stream流|获取、中间方法、终结方法、收集方法及其练习
  • 扩散模型与强化学习(12):RLHF中的Reward hacking现象