[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

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环