[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

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory