[Java]MyBatis轻松拿下

2024-08-30 10:20
文章标签 java 轻松 mybatis 拿下

本文主要是介绍[Java]MyBatis轻松拿下,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

介绍

在业务开发过程中, 都是使用java程序完成数据库的操作, 目前最主流的技术就是MyBatis

MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。

  1. 官网: https://mybatis.org/mybatis-3/zh/index.html
  2. mybatis是Apache的一个开源项目iBatis, 2010年迁移到了google code 并改名为Mybatis
  3. 2013年11月迁移到Github

快速入门

1.使用流程

1.1准备工作

  1. 创建springboot工程, 勾选
  • Mybatis Framework (Mybatis依赖)
  • MySQL Druver (MySQL驱动依赖)
  • 清理原始工程

  1. 准备实体类
  • 用于封装查询出来的数据
  • 实体类的属性名与表中的字段名一一对应。
  • 实体类的属性类型建议使用包装类型
  • 生成get/set方法
  • 生成有参构造器和无参构造器
  • 重写toString()方法
  1. 准备数据库表

1.2配置Mybatis

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名字
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234

1.3编写SQL语句

  1. 创建Mapper包, 定义持久层接口XxxMapper,
  2. 使用@Mapper注解标识接口;
  • 作用: 把接口交给Mybatis管理
  • 在运行时, mybatis会自动生成该接口的实现类对象, 并且把该对象交给IOC容器管理
  • 作用: 简化数据库的操作
  1. 定义抽象方法, 书写SQL语句
  • 通过注解执行SQL语句

1.4启动测试

@SpringBootTest //springboot整合单元测试的注解
class Day03MybatisApplicationTests {// 注入Mapper接口的实现类对象@Autowiredprivate UserMapper userMapper;@Testpublic void testListUser() {// 调用实现类对象的方法完成数据库操作List<User> userList = userMapper.list();userList.stream().forEach(user -> {System.out.println(user);});}}

2.配置提示

打开语法提示: 默认在mybatis中编写sql语句是不识别的, 可以做一些配置

关联数据库: 在IDEA和数据库默认没有建立连接, 所以不能提示表信息, 需要在idea中配置Mysql数据库信息

3.JDBC

JDBC是java语言操作关系型数据库的一套API

  1. sun公司官方定义的一套操作所有关系型数据可的规范, 即接口
  2. 各个数据库厂商去实现这套接口, 提供数据库驱动jar包
  3. 我们使用这套接口(JDBC)编程, 真正执行的代码是驱动jar包中的实现类

JDBC操作数据库存在的问题

  1. 注册驱动这块的代码存在硬编码现象
  2. 封装数据库数据的代码非常繁琐, 需要一条一条的封装
  3. 每次操作数据库都要创建和释放资源, 性能降低

  1. 在mybatis中, 通过配置的方式连接数据库
  2. 通过注解执行sql语句, 就可以完成数据库操作以及数据封装
  3. 通过数据库连接池, 管理数据库连接对象, 避免频繁创建和释放资源
  4. 使用mybatis操作数据库, 只需要配置连接信息, 编写mapper接口, 非常高效

4.数据库连接池

数据库连接池是个容器, 负责分配 管理数据库连接对象.

标准接口

  1. DetaSource 是官方(sun)提供的数据库连接池接口, 供第三方公司实现
  2. 如果想要开发连接池驱动, 就必须实现该接口
  3. 该接口的作用就是获取数据库连接对象
  4. 核心方法: Connection getConnection() thows SQLException;
  5. 常见产品

  1. Hikari(追光者)是springboot默认使用的连接池技术
  2. Druid(德鲁伊)是阿里巴巴开源的连接池技术, 功能强大, 性能优秀

切换连接池

  1. 德鲁伊官网:

  2. 切换到Druid连接池, 只需要引入德鲁伊连接池依赖就可以了

  1. 切换的效果

5.lombok

lombok的作用就是简化实体类的定义, 提高开发效率

  1. Lombok是一个实用的java类库,
  2. 通过注解的形式, 可以自动生成构造器, getter/setter. equals, hashcide, toString等方法,
  3. 还可以自动生成日志变量

引入

// 无需指定版本
// 因为lombok已经集成到springboot父工程中, 统一管理版本
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

注解

插件

  1. lombok在编译时, 会自动生成对应的java代码, 使用lombok时, 还需要安装插件
  2. ieda自带该插件, 较老版本的ieda可能需要手动安装

注解

通过Mybatis提供的注解, 完成数据库的增删改查操作

1.删除数据

@mapper // 把接口交给myBatis管理
public interface EmpMapper {//指定sql语句: 根据id删除数据@Delete("delete from emp where id = #{id}")public void delete(Integer id);
}
@SpringBootTest //springboot整合单元测试的注解
class SpringbootMybatisCrudApplicationTests {// 注入empMapper对象@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete () {// 执行对象的删除方法empMapper.delete(17);}
}
  1. 删除操作会返回一个int类型的数值, 表示删除成功的个数, 需要的时候获取
  2. mybatis提供了参数占位符 #{}, 用于读取方法传递的参数

2.参数占位符

1.开启日志输出

在application.prpperties文件中开启日志输出功能, 我们就能在控制台看到mybatis执行的slq语句

#指定mybatis输出日志的位置(输出控制台)
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3.演示sql注入

SQL注入是通过操作输入的数据来修改系统的sql语句, 达到对服务器进行攻击的方法

执行jar包

// 打开cmd窗口, 定位到文件所在目录
java -jar 文件名

访问项目

// 正常访问
select count(*) from emp where username = 'zhangwuji' and posseord = '123456';
// 登录失败
select count(*) from emp where username = 'zhangwuji' and posseord = '11111';
// sql攻击
select count(*) from emp where username = 'aaass' and posseord = '' or '1' = '1';
3.预编译sql

在mybatis中, 使用 #{ ... } 占位的SQL语句, 生成的就是预编译SQL

  1. 当SQL真正执行时, 会自动将 #{} 内的值替换到 ? 号位置, 形成完整的语句
  2. 参数的传递, 都使用#{...}, 安全可靠

预编译sql拥有更好的执行性能(缓存机制) 和 更好的安全防护(sql注入)

  1. 拼接sql: 每次执行的sql语句都是不同的, 所以无法命中缓存中的sql语句
  2. 动态sql: 每次执行的sql语句都是相同的, 可以命中缓存中的sql语句, 在执行阶段拼接具体的值
4.拼接SQL

在mybatis中, 使用 #${ ... } 占位的SQL语句, 生成的就是拼接SQL

  1. 直接将参数拼接在SQL语句中, 一般很少使用
  2. 如果对表名, 列表进行动态设置时使用

4.新增数据

@mapper // 把接口交给myBatis管理
public interface EmpMapper {// 开启主键返回, 并指定将主键值赋值给实体类的id属性@Options(useGeneratedKeys = true, keyProperty = "id")//指定sql语句: 新增员工@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +"values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")public void insert(Emp emp);
}
@SpringBootTest //springboot整合单元测试的注解
class SpringbootMybatisCrudApplicationTests {// 注入empMapper对象@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete () {// 构建员工对象Emp emp = new Enm();// 为对象添加数据emp.setUsername("Tom");emp.setName("汤姆");emp.setGender((short) 1);emp.setJob((short) 1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);// 执行对象的新增方法empMapper.insert(emp);// 如果开启了主键返回, 就可以拿到新增数据的id主键值System.out.printIn(emp.getId());}
}
  1. 主键返回: 新增操作默认不会返回主键的值, 如果需要主键值时, 通过添加注解开启
  2. 开启主键返回后, 新增操作完成, 可以通过实体类, 拿到新增数据的id主键值

5.修改数据

@mapper // 把接口交给myBatis管理
public interface EmpMapper {//指定sql语句: 更新员工@Update("update emp set username = #{username},name=#{name},gender = #{gender},image=#{image},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id =#{id};")public void update(Emp emp);
}
@SpringBootTest //springboot整合单元测试的注解
class SpringbootMybatisCrudApplicationTests {// 注入empMapper对象@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete () {// 构建员工对象Emp emp = new Enm();// 为对象添加数据emp.setUsername("Tom");emp.setId(18);emp.setName("汤姆");emp.setGender((short) 1);emp.setJob((short) 1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);// 执行对象的更新方法empMapper.update(emp);}
}

6.数据封装

实体类属性名 和 数据库表的字段名一致, Mybatis会自动封装

实体类属性名 和 数据库表的字段名不一致, 不能自动封装

  1. 通过查询语句查到数据, 把数据封装到实体中, 返回给前端
  2. 由于实体类采用驼峰命名法, 数据库中采用下划线分割, 会导致有些数据无法自动封装

1.起别名

在SQL语句中, 给不一样的字段名设置一个别名, 别名和实体类的属性名一致, 就可以正确封装数据

2.手动结果映射

通过@Results 和 @Result 注解, 手动对映射结果进行调整, 以正确的封装数据

3.开启驼峰命名转换

让Mybatis自动把 下划线的字段名 转成 驼峰命名风格, 以完成封装数据

#开启mubatis驼峰命名自动映射开关
mybatis.configuration.map-underscore-to-camel-case=true

7.查询数据

@mapper // 把接口交给myBatis管理
public interface EmpMapper {//指定sql语句:  根据id查询员工@Select("select * from emp where id= #{id}")public Emp getById(Integer id);
}
@mapper // 把接口交给myBatis管理
public interface EmpMapper {//指定sql语句:  根据条件查询员工@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +"entrydate between #{begin} and #{end} order by update_time desc;")public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}
@SpringBootTest //springboot整合单元测试的注解
class SpringbootMybatisCrudApplicationTests {// 注入empMapper对象@Autowiredprivate EmpMapper empMapper;@Testpublic void testGetById () { // 执行对象的查询方法Emp emp = empMapper.getById(1);System.out.printIn(emp);}@Testpublic void testList () { // 执行对象的条件查询方法List<Emp> list = empMapper.list("张", (short) 1, LocalDate.of(2010,1,1), LocalDate.of(2020,1,1));System.out.printIn(list);}
}
  1. #{}不能在引号内使用, ${}可以在引号内使用, 但是不推荐使用
  2. 建议使用mysql提供的 concat() 拼接函数, 用于拼接字符串
  3. concat('hello', 'Mysql' ,'!!!') 执行结果是 'helloMysql!!!'

8.版本差异

在早期或者单独使用mybatis时, 需要使用 @Param()注解 声明形参, 才能在 #{} 中使用数据, 原因是spinrgboot2.x版本 中引用了一个插件, 可以在编码后记住形参的名字, 有名字才能正确的访问数据

XML

使用mybatis的注解, 主要用来完成简单的增删改查, 如果是复杂的sql, 建议使用 xml 文件来映射sql语句

1,创建xml文件

XML映射文件的名称与Mapper接口名称一致,并且XML文件和Mapper接口放置在相同包下(同包同名)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="待定"></mapper>

2,设置namespace属性

XML映射文件的namespace属性为Mapper接口全限定名一致

复制接口全类名:

<mapper namespace="com.itheima.mapper.EmpMapper">
</mapper>

3.编写sql, 设置id属性

XML映射文件中, sql语句的id 与Mapper文件中的方法名一致, 并保持返回类型一致

<mapper namespace="com.itheima.mapper.EmpMapper">// resultType: 单条记录所封装的类型(指定返回值的类型)// id="xx":  id与mapper文件的方法名一致<select id="list" resultType="com.itheima.pojo.Emp">select * from emp where name like concat('%',#{name},'%') and gender = #{gender} andentrydate between #{begin} and #{end} order by update_time desc;</select></mapper>

4.插件

MybatisX是一款基于IDEA的快速开发Mabatis的插件, 为效率而生

生成XML文件中的sql标签

  1. alt +enter -> Generate statement -> 自动生成SQL语句

  1. ctrl +alt + L : 格式化sql语句

动态SQL

随着条件变化而变化的SQL语句称为动态sql

if标签

用于判断条件是否成立, 使用test属性进行条件判断, 如果条件为true, 则拼接SQL,

需求: 根据条件查询员工, 筛选字段有值, 则作为条件, 没有值则忽略

<select id="list" resultType="com.itheima.pojo.Emp">select * from empwhere <if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if>order by update_time desc
</select>
  1. 以上代码通过 if标签 实现了条件的动态拼接
  2. 但是代码存在问题, 不传name, 只根据gender查询, sql语句中就会多出一个 and关键字
  3. 所以在书写动态sql时, 会使用where标签 替换 where关键字

where元素只会在 子元素有内容 的情况下才插入where子句, 而且会自动去除子句 多余的AND 或 OR

<select id="list" resultType="com.itheima.pojo.Emp">select * from emp<where><if test="name != null">name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time desc
</select>

动态的在行首插入 SET 关键字, 并会删除多余的逗号, 用在update语句中

需求: 动态更新员工数据, 如果更新时传递有值,则更新该字段, 否则不更新

<update id="update">update emp<set><if test="username != null">username = #{username},</if><if test="name != null">name = #{name},</if><if test="gender != null">gender = #{gemder},</if><if test="job != null">job = #{job},</if><if test="updateTime != null">update_time = #{updateTime}</if></set>where id = #{id}
</select>
  1. 如果不使用set标签替换set关键字, 代码就会有问题
  2. 比如只传入username字段, 后面的字段不传, sql语句中就会多出一个逗号
  3. 所以在动态更新数据时, 会使用set标签替换set关键字

foreach标签

循环遍历, 主要用在批量操作中

// 批量删除员工
public void deleteByIds(List<Integer> ids);
// 批量删除员工(18,19,20)
<delete id="deleteById">delete from emp where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>

sql标签

封装重复性的SQL语句

<mapper namespace="com.itheima.mapper.EmpMapper">// 定义可重用的sql片段<sql id="唯一名称">select id,username,password,name,gender,image,job,entrydate,dept_id,create_time,update_timefrom emp</sql><select id="list" resultType="com.itheima.pojo.Emp">// 通过refid属性, 引入sql片段<include refid = "唯一名称"  />where <if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if>order by update_time desc</select>
</mapper>

这篇关于[Java]MyBatis轻松拿下的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120549

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直