目录

一、MyBatis

二、一个MyBatis查询

1、环境准备

(1)xml文件中添加MyBatis依赖

(2)准备springboot启动配置

(3)准备数据库对应的mybatis文件

2、插入操作->获取自增的主键

3、mybatis处理结果集

三、MyBatis表查询

1、MyBatis占位符

2、like查询

3、多表查询(关系映射)

(1)一对一表映射

(2)一对多表映射

四、动态SQL

1、<if>标签

2、<trim>标签

3、<where>标签

4、<set>标签

5、<foreach>标签


一、MyBatis

MyBayis支持自定义SQL、存储过程以及高级映射,几乎去除了所有的JDBC代码以及设置参数和获取结果集的工作。可以通过简单的xml或注释来配置和映射原始类型、接口为数据库中的记录。简单来说MyBatis是更简单完成程序和数据库交互的工具,更简单的进行操作和读取数据库中的数据。

回顾JDBC操作:

  1. 创建数据库连接池DataSource;
  2. 通过DataSource获取数据库连接Connection;
  3. 编写要执行的带占位符的SQL语句;
  4. 通过Connection及SQL创建操作命令的对象Statement;
  5. 替换占位符:指定要替换的数据库字段类型,占位索引及要替换的值;
  6. 使用Statement执行SQL语句;
  7. 查询操作:返回结果集ResultSet;更新操作:返回一个int值;
  8. 处理结果集;
  9. 释放资源。

存在以下几个问题:

(1)DataSource和Connection两者的关系?

  • DataSource提供连接池的支持。连接池在初始化是创建一定数量的数据库连接,这些连接可以复用,每次使用完数据库连接,释放资源调用connection.close()都是将Connection对象回收。
  • DataSource创建时,设置了url,账号,密码,不是连接数据库的;通过DataSource.getConnection()获取连接对象时,才通过Connection表示出建立的数据库连接这个概念。

(2)创建操作命令的对象Statement是,如何防止sql注入?

使用PreparedStatement(预编译的操作命令对象)。拼接字符串=>替换占位符。

(3)防止sql注入的原理是什么?

PreparedStatement防止会进行预编译,把替换的字符·中,单引号加上“/”zhuanyi

对于crud操作:

  • 输入都是一个对象(根据属性来及逆行过滤/插入/修改),真实开发时,方法参数可以设计为int、String,其实也可以作为对象的属性;
  • 输出:修改/插入/删除返回int;查询操作返回List/某个对象。

二、一个MyBatis查询

MyBatis也是一个ORM(Object Relational Mapping,对象关系映射)框架,在面向对象编程的语言中,将关系型数据库中的数据与对象建立起映射关系,进而自动完成数据与对象的互相转换:

  • 将输入数据(传入的对象)+SQL映射成原生的SQL(输入替换占位符)
  • 将结果集映射为返回对象(输出对象)

1、环境准备

(1)xml文件中添加MyBatis依赖

在Spring环境的基础上,需要添加MyBatis和数据库相关的依赖包(添加完成后刷新maven即可):

        <!--添加MyBatis依赖包--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><!--使用第三方的数据库连接池方案(不使用mysql驱动包中内置的连接池)--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.3</version></dependency><!--添加数据库驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><!--可以不添加,表示我们编译时不能使用这个依赖包中的API,运行时才会依赖--><scope>runtime</scope></dependency>

(2)准备springboot启动配置

配置application.properties文件:

配置mybatis:数据库相关的信息:

#配置mybatis:数据库相关的信息(注意修改数据库名等信息)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

配置mybatis的xml文件路径

#mybatis的xml文件路径(classpath:是spring框架中的写法,类加载的路径)
#表示类加载根路径下,mapper文件夹下,**Mapper.xml
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

(3)准备数据库对应的mybatis文件

实体类、mapper文件、xml文件(一张表,对应一套)。

以用户表user为例:

【1】添加实体类

【2】添加mapper接口

【3】添加UserMapper.xml文件

数据持久的实现,mybatis的固定的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的全限定名-->
<mapper namespace="com.example.demo.mapper.UserMapper">
</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">
<!--改为自己的mapper的全限定名-->
<mapper namespace="org.example.mapper.UserMapper">
<!--select/update等标签是sql语句,id和接口方法名一致-->
<!--resultType指定结果集转换的类型:如果是一行数据,设置为具体的一个类型,如果是多行数据,设置为List包裹的泛型数据--><select id="selectAll" resultType="org.example.model.User">select * from  user</select>
</mapper>

上面的代码中:

  • select/update/insert/delete标签是sql语句,id和接口方法名一致;
  • resultType指定结果集转换对象的类型:如果是一行数据,设置为一个具体的类型,如果是多行数据,设置为List包裹的泛型类型。

2、插入操作->获取自增的主键

再很多场景下,都需要返回自增主键的值,如:

新增一个用户后:

(1)如果刷新页面=>新增的自增主键可以不返回,会重新请求用户列表的数据;

(2)如果不刷新页面=>必须返回自增主键的值。不刷新页面,列表多出来的一行用户,没有主键id,无法进行正常的删除、修改操作。

如何获取自增主键呢?

<!-- 返回自增id -->
<!--xml文件的sql语句中,需要添加两个参数,参能获取到自增的主键-->
<insert id="add2" useGeneratedKeys="true" keyProperty="id">insert into userinfo(username,password,photo,state)values(#{username},#{password},#{photo},1)
</insert>
  • useGeneratedKeys:MyBatis使用JDBC的getGeneratedKeys方法去除由数据库生成的主键(MySQL关系型数据库管理系统的自增字段),默认值:false;
  • keyColumn:设置生成键值再表中的列名,在某些数据库中,当主键列不是表中的第一列时,必须进行设置。如果生成列不止一个,可以用逗号分隔开;
  • keyProperty:值定能够为一识别对象的属性。如果生成列不止一个,可以用逗号分割多个属性名称。

3、mybatis处理结果集

类似于jdbc处理结果集的方式:

  • 遍历:移动到下一行;
  • 每一条数据对应一个对象:把每个字段设置到对象的属性。

结果集字段名=对象的属性名,设置该字段的值为对象的属性;如果结果集字段名带_下划线,对象属性也需要一样(可以在application.properties中配置为下划线自动转驼峰式)

如果查询的结果记得字段和对象的属性名不一致,就不能使用结果集类型(resultType),需要使用结果集映射(resultMap)

<!--结果集映射resultMap,指定Java对象的属性和接轨国际字段的映射关系--><resultMap id="BaseResultMap" type="org.example.model.User">
<!--id标签配置主键字段的映射,result标签配置非主键字段的映射-->
<!--每个标签配置两个属性,property指定Java对象属性,column指定对应的sql字段--><id property="id" column="id" /><result property="username" column="username"/><result property="password" column="password"/><result property="nameDesc" column="name_desc"/></resultMap>
<!--查询字段的name_desc和User中nameDesc属性不一致,需要配置resultMap--><select id="selectAll" resultMap="BaseResultMap">select * from  user</select>

三、MyBatis表查询

1、MyBatis占位符

#{变量名}:

  • 原理:先替换为jdbc占位符?,再执行jdbc的替换
  • 作用:防止sql注入

${变量名}:

  • 原理:拼接字符串;
  • 可能存在sql注入
  • 应用:再进行orderby排序时,占位符需要使用${},不能使用#{}(会由多余的单引号)

2、like查询

like查询不能使用#{}(会报错),也不能直接使用${}(存在sql注入),可以考虑使用mysql的聂志函数concat()来处理。

<select id="findUserByName3" resultType="com.example.demo.model.User">select * from userinfo where username like concat('%',#{username},'%');
</select>

3、多表查询(关系映射)

(1)一对一表映射

先查看文章和用户的一对一关系(ArticleMapper.xml文件编写如下):

    <resultMap id="BaseResultMap" type="org.example.model.Article"><!--        文章表字段和对象属性的关联--><id column="id" property="id" /><result column="title" property="title" /><result column="content" property="content" /><result column="create_time" property="createTime" /><result column="user_id" property="userId" /><!-- 文章属性user设置为1对1映射 --><!--用户信息的映射,再另一个类中有,直接拿来用就行--><!--找到u_开头的结果集字段,去除前缀,映射到UserMapper.xml中的结果集映射中--><association property="user" columnPrefix="u_"resultMap="org.example.mapper.UserMapper.BaseResultMap"></association></resultMap><!--    文章表关联用户表,返回文章表和用户表1对1映射--><select id="selectOneToOne" resultMap="BaseResultMap">selectu.id u_id,u.username u_username,u.password u_password,u.nickname u_nickname,u.head u_head,u.github u_github,a.id,a.title,a.content,a.create_time,a.user_idfrom user u,article awhere u.id=a.user_id</select>

(2)一对多表映射

对于一对多映射,查询结果为一个集合。

查看用户和文章的一对多关系(需要修改Usermapper.xml文件):

  <!-- 结果集映射resultMap,指定Java对象的属性,和结果集字段的映射关系 --><resultMap id="BaseResultMap" type="org.example.model.User"><!-- id标签是配置主键字段的映射,result标签配置非主键字段的映射 --><!-- id/result标签,都要配置两个属性:property指定java对象属性,column指定结果集字段名 --><id property="id" column="id" /><result property="username" column="username" /><result property="password" column="password" /><result property="nickname" column="nickname" /><result property="head" column="head" /><result property="github" column="github" /><result property="nameDesc" column="name_desc" /><!-- 一个用户关联多篇文章:1对多映射 --><collection property="articles"columnPrefix="a_"resultMap="org.example.mapper.ArticleMapper.BaseResultMap"/></resultMap><select id="selectOneToMany" resultMap="BaseResultMap">selectu.id,u.username,u.password,u.nickname,u.head,u.github,a.id a_id,a.title a_title,a.content a_content,a.create_time a_create_time,a.user_id a_user_idfrom user u,article awhere u.id=a.user_id</select>

四、动态SQL

1、<if>标签

sql中,分为必填字段和非必填字段,对于非必填的字段,需要根据用户传进来的数据判断是否传入该字段,使用<if>标签。

<!--对象中性别字段不为空时,才传入-->
<!--test中的sex,时对象中的属性,不是数据库中的字段-->
insert into user(username,password,nickname,<if test="sex != null">sex,</if>
) values (#{username},#{password},#{nickname},<if test="sex != null">#{sex},</if>
)

2、<trim>标签

之前的if标签,只有一个字段是选填项,如果有多个字段选填,使用if标签的时候可能会存在“,”处理的问题,可以使用trim标签,对多个字段都采取动态生成的方式,标签中有如下属性:

  • prefix:值作为整个语句块的前缀;
  • suffix:值作为整个语句块的后缀;
  • prefixOverride:表示整个语句块要去掉的前缀;
  • suffixOverride:表示整个语句块要去掉的后缀;
insert into user
<!--拼接前缀、后缀小括号,同时去掉最后多的一个逗号-->
<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">username,</if><if test="password != null">password,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=","><if test="username != null">#{username},</if><if test="password != null">#{password},</if>
</trim>
</insert>

3、<where>标签

查询操作:对于if标签和trim标签,如果进行where查询,此时不传入字段时会报错,所以查询的时候需要使用where标签。

select * from user
<where><if test="username != null">and username=#{username}</if><if test="password != null">and password=#{password}</if>
</where>

4、<set>标签

修改操作,修改的字段和值是可选的场景使用。

update user
<set><if test="username != null">and username=#{username}</if><if test="password != null">and password=#{password}</if>
</set>

5、<foreach>标签

对集合进行遍历,有以下属性:

  • collection:绑定方法参数中的集合;
  • item:遍历时的每一个对象;
  • open:语句块的前缀;
  • close:语句块的后缀;
  • separactor:每次遍历之间间隔的字符串。

使用场景:

(1)根据id进行批量删除:

<delete id="deleteByIds">delete from articlewhere id in<foreach collection="list" item="item" open="(" close=")" separator=",">#{item}</foreach>
</delete>

(2)批量插入:

insert into user(username,password) values
<foreach collection="list" item="item" separactor=",">(#{item.username},#{item.password})
</foreach>

MyBatis操作数据库相关推荐

  1. Quartz SpringMvc Mybatis操作数据库异常

    Quartz SpringMvc Mybatis操作数据库,空指针(nullpointexception)异常 quartz动态定时任务在执行时是以线程的形式在后台定期执行,Mybatis链接数据库基 ...

  2. java spring 数据库_JAVA - SpringBoot项目引用MyBatis操作数据库

    JAVA - SpringBoot项目引用MyBatis操作数据库 添加POM依赖: org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1 ...

  3. 搭建MyBatis操作数据库

    1.下载MyBatis压缩包 https://github.com/mybatis/mybatis-3/releases,选择合适版本的MyBatis 将其解压到指定目录,如下: 2.创建表格stud ...

  4. Mybatis操作数据库实现主键自增长

    (一)oracle中没有主键自增长,所有可以通过创建序列或使用触发器实现 1.先创建表 CREATETABLE USER1(ID NUMBER(10),NAME VARCHAR2(20),SEX VA ...

  5. Mybatis学习笔记-配置Log4j以便查看MyBatis操作数据库的过程

    配置Log4j 在src/main/resources中添加log4j.properties配置文件 编写测试代码 在配置中加入该SQL语句返回的结果集的封装类型 自行测试 java.sql.SQLN ...

  6. MyBatis是持久化层框架(SQL映射框架)-操作数据库

    MyBatis是持久化层框架(SQL映射框架)-操作数据库 1.环境搭建 1).创建一个java工程: 2).创建测试库,测试表,以及封装数据的javaBean,和操作数据库的dao接口 创建表:自己 ...

  7. 通过接口操作MyBatis及数据库配置文件

    优点: 不用每次实例化SqlSession 配置优于硬编码 减少sql书写错误的概率 规范代码,面向接口服务 文章目录 一.回顾 二.如何通过接口操作MyBatis 2.1. 文件结构 2.2. 依赖 ...

  8. Mybatis介绍、jdbc操作数据库原始写法以及Mybatis架构

    文章目录 Mybatis介绍 jdbc操作数据库原生写法 使用jdbc编程问题总结 Mybatis架构 Mybatis介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年这个 ...

  9. 使用mybatis操作MySQL中的数据库表1---读取数据

    1)MySQL中创建表 create table student ( id int(11) not null, name varchar(255) default null, email varcha ...

  10. mybatis操作Oracle数据库批量插入与更新、运行注意事项、属性含义

    一.项目需求 针对将近300万用户的用电数据进行统计分析,将结果更新保存Oracle数据库.我需要往一个表里面插入数据,数据量总计在500万条左右.一条一条插入的话非常慢,2万条数据近20分钟,后面就 ...

最新文章

  1. 读博前三年0文章,后期发力一口气11篇一作!这个“90后”现任职985博导
  2. 5G NGC — AF 与 NEF 网络能力开放
  3. python3 检测端口是否开放
  4. android 单个模块编译的方法
  5. 从原理上搞懂如何设置线程池参数大小?
  6. (74)分析 APC 插入过程 —— KeInsertQueueApc , KiInsertQueueApc
  7. 解决mysql 1032 主从错误
  8. 130242014022 蓝宏铮 第2次实验
  9. 清华大学 现代软件工程 学生特别想学的领域
  10. 金属零件图像数据集_如何使用包装零件来开发易于维护的数据仓库解决方案
  11. 传说之下音乐计算机版,传说之下同人音乐
  12. 【心电信号】基于matlab GUI心电信号数字滤波处理【含Matlab源码 484期】
  13. 牛顿迭代法的matlab程序,牛顿迭代法matlab程序
  14. 2021-07-01本科毕业设计需要查重什么?
  15. [培训-无线通信基础-8]:分集技术(微分集、宏分集、信号合并、分集增益)
  16. JavaScript 对象
  17. msxml3.dll 错误'800c0005' 系统未找到指定的资源错误
  18. 使用win10自带的微软远程桌面,远程控制不同局域网的电脑【无需公网IP、无需进入路由器】
  19. fastreport中文乱码问题
  20. mac系统用键盘操作菜单栏

热门文章

  1. 基于PLC的智能化配电箱系统
  2. 创建Django项目及配置
  3. 中兴F607ZA查看超级管理员密码
  4. STC8A8K低功耗模式验证
  5. 计算机execl必背知识点,【分享】Excel必备基础知识(1)
  6. MySQL之环境变量配置
  7. 把14亿中国人都拉到一个微信群在技术上能实现吗?
  8. tomcat启动报错解决org.jaxen.util.AncestorOrSelfAxisIterator
  9. bootstrap在线定制工具
  10. 虚拟机怎么启动共享文件服务器,VMware虚拟机中ubuntu启用本地文件共享的设置方法...