mybatis —— ORM框架

article/2025/10/19 7:49:33

一、什么是框架

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

二、什么是ORM

        ORM,即 Object-Relational Mapping (对象关系映射),它的作用是在关系型数据库和业务实体 对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的 SQL 语句打交 道,只需简单的操作对象的属性和方法。

三、什么是mybatis框架? 

        MyBatis 是支持普通 SQL 查询存储过程高级映射的优秀==ORM框架==。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索封装。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录. 半自动化框架。必须写sql语句。

        mybatis可以向PreparedStatement中输入参数自动进行输入映射,将查询结果集灵活的映射成Java对象(输出映射),输入映射和输出映射这是mybatis的核心

        用一句话来说, mybatis就是封装与数据库交互的半成品。

1、如何使用mybatis

        准备条件就是需要先建一个数据

                create database mybatis;
                use mybatis;
                CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, NAME
                VARCHAR(20), age INT);
                INSERT INTO users(NAME, age) VALUES('Tom', 12);
                INSERT INTO users(NAME, age) VALUES('Jack', 11);

        (1)创建一个maven的java工程

         (2)引入mybatis的jar包和 mysql的驱动jar包

         (3)创建相应的实体类

         (4)配置mybatis的配置文件---mybatis会读取该文件的内容完成连接数据库的功能

        (5)编写相应的映射(mapper)文件  -----sql语句 实体类与表的映射

        (6)把映射文件引入到mybatis配置文件中

         (7)测试是否成功

        (8)CRUD操作 (增删改查)测试

2、实际开发中使用Dao

        (1)定义一个相关的Dao接口

         (2)映射文件(mapper)

 注意: namespace必须和接口所在的路径对应。id必须和方法名一致

        (3)测试

         (4)注意红框位置(mybatis03)

3、传递多个参数

        图中非注释区域对应的是自定义参数名 @Param("参数名")

4、特殊字符

        (1)常见的特殊字符

         (2)解决方式有两种

                        ①是转义字符,如上图所示                  

                       ②是使用<![CDATA[ 特殊字符或SQL语句 ]]>

5、mybatis的优化

        (1)引入db属性文件。

                ①定义一个数据库属性文件   . properties

                ②在mybatis配置文件中引入属性文件并使用相应的key

         (2)引入日志文件 ——更好的显示sql语句

                        ①引入日志jar包

                         ②引入日志的配置文件 log4j.properties

               输出到日志文件

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

        (3)解决列名和属性名不一致

                        ①为查询的列起别名;让别名和属性名一致

<select id="selectById" resultType="com.ykq.entity.Order">select order_id id,order_no no,order_price price from orders where order_id=#{id}
</select>

                        ②使用resultMap标签 来完成属性和列的映射关系

<!--id:唯一标识type:类型;表与哪个实体类的映射<id 主键的映射关系  column="列名" property="属性名"/><result 普通字段/>autoMapping = true 表示自动映射  默认一般为true--><resultMap id="l" type="com.ljm.entity.Book_info"><!--id必须写--><id property="id" column="book_id"/><result property="name" column="book_name"/><result property="author" column="book_author"/><result property="price" column="book_price"/><result property="pub" column="book_pub"/></resultMap><select id="selectById" resultMap="l">select * from book_info where book_id=#{id}</select>

        追加:事务

        什么是事务:事务是由一系列动作组成,这些动作要么都完成,要么都不完成。

                              jdbc默认事务是自动提交。现在mybatis事务需要手动提交。      

//转账问题
Connection connection=null;
try {Class.forName("com.mysql.cj.jdbc.Driver");connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai","root","root");connection.setAutoCommit(false);PreparedStatement ps=connection.prepareStatement("update users set age=age-10 where name='张天龙'");ps.executeUpdate();ps=connection.prepareStatement("update users set age=age+10 where name='汪伟宁'");ps.executeUpdate();//connection.commit();//提交
}catch (Exception e){try {connection.rollback();//回滚} catch (SQLException throwables) {throwables.printStackTrace();}e.printStackTrace();
}finally {}

6、链表查询

          (1)多对一  ①链表查询  ②嵌套查询

<!--链表查询-->
<resultMap id="ljm01" type="com.ljm.entity.Emp"><id property="eno" column="empno"/><result property="name" column="name"/><result property="job" column="job"/><result property="sal" column="sal"/><!--association 表示多对一property 表示对象属性名     javaType 表示该对象所属的类型--><association property="dept" javaType="com.ljm.entity.Dept" autoMapping="true"><!--Dept和Dept表的对应关系--><id property="dno" column="deptno"/></association></resultMap><select id="selectById" resultMap="ljm01">select * from emp e join dept d on e.depton=d.deptno where e.empno=#{eno}</select>
<!--嵌套查询      两次查询--><resultMap id="ljm01" type="com.ljm.entity.Dept" autoMapping="true"><id property="dno" column="deptno"/></resultMap><select id="selectById" resultMap="ljm01">select * from dept where deptno=#{depton}</select><resultMap id="ljm02" type="com.ljm.entity.Emp"><id property="eno" column="empno"/><result property="name" column="name"/><result property="job" column="job"/><result property="sal" column="sal"/><!--column 把查询的哪一列作为另一个查询的条件值select 表示引用另一个查询--><association property="dept" javaType="com.ljm.entity.Dept" autoMapping="true">column="depton" select="com.ljm.dao.DeptDao.selectById"                                                  <!--Dept和Dept表的对应关系--></association></resultMap><select id="selectById02" resultMap="ljm02">select * from emp where empno=#{eno}</select>

         (2)一对多

<--链表查询-->
<resultMap id="ljm03" type="com.ljm.entity.Clazz" autoMapping="true"><id property="cid" column="cid"/><!--collection: 集合的意思 多的意思property:集合对象名ofType 集合的泛型--><!--若属性名和数据库的列名一直,则不需要在写,直接autoMapping即可,但是id必须写--><collection property="students" ofType="com.ljm.entity.Student" autoMapping="true"><id property="sid" column="sid"/></collection></resultMap><select id="findById" resultMap="ljm03">select * from class c join student s on c.cid=s.classid where cid=#{cid}</select>

 7、动态sql语句

sql语句根据条件而发生改变
元素作用描述
if条件判断单条件判断
choose(when、otherwise)条件选择,相当于java when多条件分支判断
where、set辅助处理sql拼接语句
foreach循环循环
<resultMap id="book" type="com.ljm.entity.Book"><id property="id" column="book_id"/><result property="name" column="book_name"/><result property="author" column="book_author"/><result property="price" column="book_price"/><result property="pub" column="book_pub"/></resultMap>

                (1)if和where一起用

<!--如果传入书名 按书名进行查询 如果没有传入书名 则查询所有where 可以添加where关键字,并把第一个and或者or去除--><!--if+where--><select id="findByCondition" resultMap="book">select * from book_info<where><if test="bookname!=null and bookname!=''">and book_name=#{bookname}</if><if test="author!=null and author!=''">and book_author=#{author}</if></where></select><--测试-->
@Testpublic void test(){BookDao bookDao = session.getMapper(BookDao.class);HashMap<String, Object> map = new HashMap<String, Object>();map.put("bookname","西游记");map.put("author","吴承恩");List<Book> list = bookDao.findByCondition(map);//System.out.println(list);}

                 (2)[choose when otherwise] 和where

<!--choose+wherewhen 条件满足时不会执行下面的when和otherwise    都不满足执行otherwise满足第一个条件后面就不再进行了,不满足第一个条件就进行第二个,否则就进行第三个--><select id="findByCondition02" resultMap="book">select * from book_info<where><choose><when test="bookname!=null and bookname!=''">and book_name=#{bookname}</when><when test="author!=null and author!=''">and book_author=#{author}</when><otherwise>and book_price>35</otherwise></choose></where></select><--测试-->
@Testpublic void test1(){BookDao bookDao = session.getMapper(BookDao.class);HashMap<String, Object> map = new HashMap<String, Object>();map.put("bookname","西游记");map.put("author","吴承恩");List<Book> list = bookDao.findByCondition(map);//System.out.println(list);}

                (3)set标签    修改部分字段

<!--set  修改部分列的值可以添加set关键字 并去除最后的逗号--><update id="update">update book_info<set><if test="name!=null and name!=''">book_name=#{name},</if><if test="author!=null and author!=''">book_author=#{author},</if><if test="pub!=null and pub!=''">book_pub=#{pub},</if><if test="price!=null">book_price=#{price},</if></set>where book_id=#{id}</update><--测试-->
@Testpublic void testUpdate(){BookDao bookDao = session.getMapper(BookDao.class);Book book = new Book();book.setAuthor("罗贯中");book.setName("三国");book.setId(1010);bookDao.update(book);session.commit();}

                (4)foreach 批量删除

<!--foreach collection 变量的集合    item 每次遍历时赋值的元素变量名open 以什么开始  close 以什么结束  separator 分隔符--><delete id="batchDelete">delete from book_info where book_id in<foreach collection="ids" item="id" open="(" close=")" separator=",">#{id}</foreach></delete><--测试-->
@Testpublic void batchDelete(){BookDao bookDao = session.getMapper(BookDao.class);int[] ids = {1001,1002,1003};bookDao.batchDelete(ids);session.commit();}

8、模糊查询

<!--模糊查询--><select id="findAll01" resultMap="ljm01">select<include refid="sql01"/>from emp e join dept d on e.depton=d.deptno<where><if test="name!=null and name!=''">name like concat('%',#{name},'%')</if></where></select><--测试-->
//模糊查询@Testpublic void testFindAll(){EmpDao empDao = session.getMapper(EmpDao.class);List<Emp> list = empDao.findAll01("老");System.out.println(list);//session.commit();}

9、分页插件

        (1) 引入相关的pageHelper依赖 pom

<!--分页插件的依赖--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.11</version></dependency>

        (2) 加入拦截  mybatis

<!--分页拦截--><plugins><!-- com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor="com.github.pagehelper.PageInterceptor"><!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --><property name="param1" value="value1"/></plugin></plugins>

        (3)测试

//测试分页@Testpublic void testFindAll1(){EmpDao empDao = session.getMapper(EmpDao.class);//使用分页功能PageHelper.startPage(2,8);List<Emp> list = empDao.findAll01("老");//可以把查询的结果封装到PageInfo类中,包含总条数//PageInfo<Emp> pageInfo = new PageInfo<Emp>(list);//System.out.println("总数:"+pageInfo.getTotal());System.out.println(list);}


http://chatgpt.dhexx.cn/article/wHpZXfgv.shtml

相关文章

ORM框架——SqlSugar

目录 一、ORM框架 二、SqlSugar现状 三、SqlSugar的优点 四、SqlSugar的使用 五、主要函数 六、传参 五、读写分离 一、ORM框架 常用的ORM框架有Dapper、EF/EF Core、FreeSql、Dos.ORM、SqlSugar等&#xff0c;SqlSugar是国产的 二、SqlSugar现状 SqlSugar ORM 5.X 官…

很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)

大家好&#xff0c;我是冰河~~ 最近很多小伙伴对ORM框架的实现很感兴趣&#xff0c;不少读者在冰河的微信上问&#xff1a;冰河&#xff0c;你知道ORM框架是如何实现的吗&#xff1f;比如像MyBatis和Hibernate这种ORM框架&#xff0c;它们是如何实现的呢&#xff1f; 为了能够…

.Net Core ORM 框架

我的.net core orm 框架 一个简单的orm框架支持的数据库版本新的版本项目地址使用方式实现方式高级特性扩展函数性能bug 一个简单的orm框架 作者在使用很多orm框架的时候觉得查询语句写法似乎不是很好用&#xff0c;例如sqlSugar,EF,sqlSugar呢链接的时候必须注意表的别称&…

SQLAlchemy ORM框架

ORM简介 ORM 全称 Object Relational Mapping, 叫对象关系映射。简单的说&#xff0c;ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系。这样&#xff0c;我们要操作数据库&#xff0c;数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成。 对于…

ORM框架

ORM框架 一、什么是ORM框架 对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术 ORM框架是连接数据库的桥梁&#xff0c;只要提供了持久化类与表的映射关系&#xff0c;OR…

ORM框架使用优缺点

1. 什么是ORM? 对象-关系映射&#xff08;Object-Relational Mapping&#xff0c;简称ORM&#xff09;&#xff0c;面向对象的开发方法是当今企业级应用开发环境中的主流开发方法&#xff0c;关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业…

Redis I/O 多路复用

引出IO多路复用 为什么 Redis 中要使用 I/O 多路复用这种技术呢&#xff1f; 首先&#xff0c;Redis 是跑在单线程中的&#xff0c;所有的操作都是按照顺序线性执行的&#xff0c;但是由于读写操作等待用户输入或输出都是阻塞的&#xff0c;所以 I/O 操作在一般情况下往往不能…

IO多路复用—由Redis的IO多路复用yinch

linux IO多路复用有epoll&#xff0c; poll, select&#xff0c;epoll性能比其他几者要好。 名词比较绕口&#xff0c;理解涵义就好。一个epoll场景&#xff1a;一个酒吧服务员&#xff08;一个线程&#xff09;&#xff0c;前面趴了一群醉汉&#xff0c;突然一个吼一声“倒酒”…

什么是IO多路复用?用来解决什么问题?如何实现?

白话IO多路复用 这里引述知乎大佬对于IO多路复用的机场空管的比喻和理解&#xff1a; 假设你是一个机场的空管&#xff0c; 你需要管理到你机场的所有的航线&#xff0c; 包括进港&#xff0c;出港&#xff0c; 有些航班需要放到停机坪等待&#xff0c;有些航班需要去登机口接…

I/O多路复用

https://blog.csdn.net/baixiaoshi/article/details/48708347 https://blog.csdn.net/z69183787/article/details/52943917 select&#xff0c;poll&#xff0c;epoll都是IO多路复用的机制。所谓I/O多路复用机制&#xff0c;就是说通过一种机制&#xff0c;可以监视多个描述符…

概念 多路复用 到底是个啥?通俗易懂的理解

前言&#xff1a;教育的公平才是最大的公平&#xff0c;本科和专科还是有点差别的。时间长点学方面会充实些。 先给个结论&#xff1a;I/O多路复用技术&#xff08;就是大家经常说的事件循环&#xff09;实际上&#xff0c;事件驱动模型还有另外一个名字&#xff0c;而且更加出…

Redis的IO多路复用原理

什么是阻塞&#xff0c;非阻塞&#xff0c;异步同步&#xff0c;select&#xff0c;poll&#xff0c;epoll&#xff1f;今天我们用一遍文章解开这多年的迷惑。 首先我们想要通过网络接收消息&#xff0c;是这样的一个步骤。 用户空间向内核空间请求网络数据内核空间把网卡数据…

什么是IO多路复用,理解IO多路复用

什么是IO多路复用&#xff1f; IO 多路复用是一种同步IO模型&#xff0c;实现一个线程可以监视多个文件句柄&#xff1b;一旦某个文件句柄就绪&#xff0c;就能够通知应用程序进行相应的读写操作&#xff1b;没有文件句柄就绪就会阻塞应用程序&#xff0c;交出CPU。 多路是指网…

多路复用与多路分用

从现在开始&#xff0c;我们开始传输层的学习&#xff0c;自顶向下第六版中改成了运输层&#xff0c;感觉怪怪的 书中打了邮政服务和代收发信件的兄弟姐妹之间的比方&#xff0c;非常贴切&#xff0c;这是传输层和网络层的作用区别&#xff0c;也就是说&#xff0c;传输层管的是…

多路复用(

apue 多路复用 需求来自用户&#xff0c;用户的需求来自实际的使用场景。在实际运用中&#xff0c;一个系统或者程序需要处理的事件并不是只有一个或一类&#xff0c;而是存在各种各样的事件在一小段事件内一起发生&#xff0c;此时按照没学多线程的逻辑的处理方式就是这样&…

多路复用

讲多路复用先我觉得有必要讲一下什么是阻塞IO、非阻塞IO、同步IO、异步IO这几个东西&#xff1b;linux的五种IO模型&#xff1a; 1)阻塞I/O&#xff08;blocking I/O&#xff09; 2)非阻塞I/O&#xff08;nonblocking I/O&#xff09; 3) I/O复用(select和poll)&#xff08;…

io多路复用的原理和实现_IO多路复用机制详解

select&#xff0c;poll&#xff0c;epoll机制区别总结: 服务器端编程经常需要构造高性能的IO模型&#xff0c;常见的IO模型有四种&#xff1a; (1)同步阻塞IO(Blocking IO)&#xff1a;即传统的IO模型。 (2)同步非阻塞IO(Non-blocking IO)&#xff1a;默认创建的socket都是…

【多路复用器介绍】

【多路复用器介绍】意义 作用 实现 意义逻辑电路原理结构与真值表逻辑电路 实现代码参考资料 意义 多路复用器将接收的复合数据流&#xff0c;依照信道分离数据&#xff0c;并将它们送到对应的输出线上&#xff0c;故称为解多路复用器。 实际生活中&#xff0c;使用多路复用器…

多路复用技术(频分多路复用、时分多路复用和波分多路复用)

基带信号就是将数字信号1或0直接用两种不同的电压来表示&#xff0c;然后送到线路上去传输。 宽带信号则是将基带信号进行调制后形成的频分复用模拟信号。 多路复用技术的基本原理是&#xff1a;各路信号在进入同一个有线的或无线的传输媒质之前&#xff0c;先采用调制技术把…

8、多路复用技术

这一节&#xff0c;我们介绍信道的多路复用&#xff0c;作为数据通信基础的收尾知识点&#xff0c;这个知识点并没有特别复杂的地方&#xff0c;主要是理解不同的复用技术的特点&#xff0c;在一些考试中也没有多少考点&#xff0c;或者说不做重点。 多路复用技术 先从字面上来…