首页 > 其他分享 >Mybatis学习笔记

Mybatis学习笔记

时间:2024-03-28 21:45:47浏览次数:32  
标签:name gender time 笔记 学习 emp SQL Mybatis id

1、概述

1.1 MyBatis

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

官网:https://mybatis.org/mybatis-3/zh/index.html

使用Mybatis操作数据库,就是在Mybatis中编写SQL查询代码,发送给数据库执行,数据库执行后返回结果。

1.2 预编译SQL

性能更高更安全,能防止sql注入

SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的目的。由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。

  1. 编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译。(只是输入的参数不同)
  2. 将敏感字进行转义
1.3 参数占位符
  • #{...} :执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值

    使用时机:参数传递,都使用#{…}

  • ${...}:拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题

    使用时机:如果对表名、列表进行动态设置时使用

2、配置说明

2.1 application.properties
#驱动类名称
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
#指定mybatis输出日志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启驼峰命名;如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射
mybatis.configuration.map-underscore-to-camel-case=true
2.2 数据库连接池(Druid)

官方地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

资源重用、提升系统响应速度、避免数据库连接遗漏

客户端执行SQL语句:要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行后又需要关闭连接对象从而释放资源,每次执行SQL时都需要创建连接、销毁链接,这种频繁的重复创建销毁的过程是比较耗费计算机的性能。

数据库连接池是个容器,负责分配、管理数据库连接(Connection)

程序在启动时,会在数据库连接池(容器)中,创建一定数量的Connection对象;允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用);

释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏;客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象

官方(sun)提供了数据库连接池标准(javax.sql.DataSource接口);第三方组织必须按照DataSource接口实现:C3P0、DBCP、Druid、Hikari (springboot默认)

<dependency>
    <!-- Druid连接池依赖 -->
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.druid.username=root
spring.datasource.druid.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=root
spring.datasource.password=1234
public Connection getConnection() throws SQLException;  //获取连接 
2.3 lombok

一个实用的Java类库

通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。

注解 作用
@Getter/@Setter 为所有的属性提供get/set方法
@ToString 会给类自动生成易阅读的 toString 方法
@EqualsAndHashCode 根据类所拥有的非静态字段自动重写 equals 方法和 hashCode 方法
@Data 提供了更综合的生成代码功能(@Getter + @Setter + @ToString + @EqualsAndHashCode)
@NoArgsConstructor 为实体类生成无参的构造器方法
@AllArgsConstructor 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。
<!-- 在springboot的父工程中,已经集成了lombok并指定了版本号,故当前引入依赖时不需要指定version -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

Lombok会在编译时,会自动生成对应的java代码

在使用lombok时,还需要安装一个lombok的插件(新版本的IDEA中自带)

2.4 解决SQL警告与提示
  1. 在Idea中配置MySQL数据库连接时指定数据库可以识别表名(列名)
  2. 在@Select注解中编写SQL语句时自动提示功能:右键选择sql语句-->show context Actions-->inject language or reference---> MySQL(sql)
2.5 MybatisX

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

2.6 数据封装

实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装;如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。

解决方案:起别名、结果映射、开启驼峰命名


在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样

@Select("select id, username, password, name, gender, image, job, entrydate, " +
        "dept_id AS deptId, create_time AS createTime, update_time AS updateTime " +
        "from emp " +
        "where id=#{id}")
public Emp getById(Integer id);

手动结果映射:通过 @Results及@Result 进行手动结果映射

@Results({@Result(column = "dept_id", property = "deptId"),
          @Result(column = "create_time", property = "createTime"),
          @Result(column = "update_time", property = "updateTime")})
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
public Emp getById(Integer id);

开启驼峰命名(推荐):

  1. 如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射
  2. 实体类的属性 与 数据库表中的字段名严格遵守驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true
2.7 参数名说明

条件查询中,需要保证接口中方法的形参名和SQL语句中的参数占位符名相同,否则会出现not found

参数名在不同的SpringBoot版本中,处理方案不同:

在springBoot的1.x版本单独使用mybatis,编译生成的字节码文件中,不会保留Mapper接口中方法的形参名称,而是使用var1、var2...这样的形参名字,此时要获取参数值时,就要通过@Param注解来指定SQL语句中的参数名

public List<Emp> list(String var1,SHort var2,LocalDate var3,LocalDate var4);
@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(@Param("name")string name,@Param("gender")Short gender, @Param("begin")LocalDate begin,@Param("end")localDate end);

在springBoot的2.x版本中(保证参数名一致),springBoot的父工程对compiler编译插件进行了默认的参数parameters配置,使得在编译时,会在生成的字节码文件中保留原方法形参的名称,所以#{…}里面可以直接通过形参名获取对应的值

@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);

3、注解说明

@Mapper
  1. 表示当前接口是mybatis中的Mapper接口
  2. 程序运行时框架会自动生成接口的实现类对象(代理对象)并给交Spring的IOC容器管理
@Select
  1. select查询,后面书写select查询语句
@Delete
  1. 编写delete操作的SQL语句
  2. 如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写,但是建议保持与形参一致。
@Options[主键返回]

在数据添加成功后,需要获取插入数据库数据的主键。

@Mapper
public interface EmpMapper {
    //会自动将生成的主键值,赋值给emp对象的id属性
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @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);
}
@Test
public void testInsert(){
    Emp emp = new Emp();
    emp.setUsername("jack");
    emp.setDeptId(1);
    //调用添加方法
    empMapper.insert(emp);
	// 返回主键
    System.out.println(emp.getDeptId());
    System.out.println(emp.getId());
}
@Results和@Result
  1. 实体类属性名和数据库表查询返回的字段名不一致时进行映射
@Results({@Result(column = "dept_id", property = "deptId"),
          @Result(column = "create_time", property = "createTime"),
          @Result(column = "update_time", property = "updateTime")})
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
public Emp getById(Integer id);
@SpringBootTest
  1. 代表该测试类已经与SpringBoot整合,测试类在运行时会自动通过引导类加载Spring的环境(IOC容器)。
  2. 可以通过@Autowired注解注入需要测试的bean对象进行测试
@SpringBootTest
public class MybatisQuickstartApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testList(){
        List<User> userList = userMapper.list();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}
@Param
  1. Spring1.x版本时,写在形参中,用来指定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(@Param("name")string name,@Param("gender")Short gender, @Param("begin")LocalDate begin,@Param("end")localDate end);

4、注解开发

创建实体类时LocalDate类型对应数据表中的date类型;LocalDateTime类型对应数据表中的datetime类型

@Mapper
public interface EmpMapper {

    // 根据id删除数据
    @Delete("delete from emp where id = #{id}")//使用#{key}方式获取方法中的参数值
    public void delete(Integer id);
    
    // 新增员工信息,主键返回
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @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);   // #{...} 里面写的名称是对象的属性名
    
    // 根据id修改员工信息
    @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);
    
    // 根据id查询员工信息
    @Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
    public Emp getById(Integer id);
    
    // 模糊查询
    @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);
    
}

5、XML开发【重点】

在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
  2. XML映射文件的namespace属性为Mapper接口全限定名一致
  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致

resultType属性指查询返回的单条记录所封装的类型。

5.1 dtd约束+例子
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lmcode.mapper.EmpMapper">

    <!--查询操作-->
    <select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where name like concat('%',#{name},'%')
              and gender = #{gender}
              and entrydate between #{begin} and #{end}
        order by update_time desc
    </select>
</mapper>
5.2 动态sql

条件不是写死的,应该传递参数后再组装这个查询条件;如果没有传递参数就不应该组装这个查询条件。

情景:

搜索姓名带有"张"的员工:

select * from emp where name like '%张%' order by update_time desc;

搜索姓名带有"张"的男性员工:

select * from emp where name like '%张%' and gender = 1 order by update_time desc;

<sql>:定义可重用的SQL片段

<include>:通过属性refid,指定包含的SQL片段

<if>用于判断条件是否成立,如果条件为true,则拼接SQL

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

<set>动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)

</foreach>遍历方法中传递的集合

@Mapper
public interface EmpMapper {
    public void update(Emp emp);
    public void deleteByIds(List<Integer> ids);
}
<sql id="commonSelect">
 	id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>

<select id="list" resultType="com.itheima.pojo.Emp">
    select <include refid="commonSelect"/> 
    from emp
    <where>
        <!-- if做为where标签的子元素 -->
        <if test="name != null">
            and 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>

<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=#{gender},
        </if>
        <if test="image != null">
            image=#{image},
        </if>
        <if test="job != null">
            job=#{job},
        </if>
        <if test="entrydate != null">
            entrydate=#{entrydate},
        </if>
        <if test="deptId != null">
            dept_id=#{deptId},
        </if>
        <if test="updateTime != null">
            update_time=#{updateTime}
        </if>
    </set>
    where id=#{id}
</update>

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

6、图片

XML配置查询

XML配置查询

XML映射文件

XML映射文件

预编译SQL

预编译SQL

标签:name,gender,time,笔记,学习,emp,SQL,Mybatis,id
From: https://www.cnblogs.com/lm02/p/18102683

相关文章

  • 新机器安装docker (新手笔记)-- 知其所以然
    1.安装Docker-2024.03.28官方手册清华大学开源软件镜像站|可从主页找到Docker资源#AddDocker'sofficialGPGkey:sudoapt-getupdatesudoapt-getinstallca-certificatescurlsudoinstall-m0755-d/etc/apt/keyringssudocurl-fsSLhttps://download.docker......
  • JAVA学习笔记
    第一章Java起步入门 #jdk版本JavaSE(J2SE,Java2PlatformStandardEdition,标准版)JavaSE以前称为J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。JavaSE包含了支持JavaWeb服务开发的类,并为JavaEE和JavaME提供基础。JavaE......
  • LLMRec论文阅读笔记
    LLMRec论文阅读笔记Abstract​ 长期以来,数据稀疏性的问题一直是推荐系统中的一个挑战,以前的研究都试图通过合并侧边信息来解决这个问题。然而,这种方法经常会引入副作用,如噪声、可用性问题和低数据质量,这反过来会阻碍用户偏好的准确建模,并对推荐性能产生不利影响。鉴于大型语言模......
  • 学习变量的目的及基本数据类型介绍
    今日练习1.如何书写python的注释语法【1】单行注释单行注释是指只对一行进行注释,一旦换了一行就不生效了注释方法:#注释内容快速注释单行代码【2】多行注释多行注释适用于代码块注释方法:英文状态下的三个单引号或者双引号,头尾皆需要"""内容"""'''内......
  • 云计算02笔记---远程连接服务ssh 以及cp mv rm cd mkdir echo 等Linux常用命令
    远程连接服务ssh语法格式:ssh用户名@ip地址【-p指定端口号】例如:[email protected]默认端口号:22修改端口号:vim/etc/ssh/sshd_config编辑其中一行#port22改为port2222删去了注释符号#且改变端口号拷贝命令cpcp位置1位置2从位置1复制到位置......
  • 云计算笔记03--配置yum源及下载nginx并上传项目至服务器(常用命令 lrzsz cat head tail
    配置yum源首先将系统自带的yum源进行备份cd/etc/yum.repos.d///进入到yum配置目录mkdirbackup//创建一个备份目录mv*.repobackup///将所有以.repo结尾的文件移动到备份目录中#阿里云的yum源网站:https://developer.aliyun.com/......
  • 云计算随堂笔记
    一.查看windows的ip地址输入ipconfig二.命令提示符[root@localhost]Root:超级管理员Localhost:主机名三.网卡启动/命令关闭启动网卡:ifupens33网卡关闭:ifdownens33查看ip地址:ipa四.时间管理查看服务器当前时间:date修改系统时间:date-s'2021-12-1218:33:20'查看硬件......
  • [附源码]计算机毕业设计保险客户管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍在现代保险行业中,客户管理系统对于提升客户服务水平、增强客户满意度和构建长期客户关系至关重要。随着大数据和人工智能技术的发展,保险公司迫切需要一个先进的......
  • [附源码]计算机毕业设计技术文档管理系统(JSP+java+springmvc+mysql+MyBatis)
    本项目包含程序+源码+数据库+LW+调试部署环境,文末可获取一份本项目的java源码和数据库参考。项目文件图项目介绍技术文档管理系统是企业信息化建设的重要组成部分,它关系到知识的积累、共享和管理效率。随着企业规模的扩大和业务的多样化,传统的文件管理方式已无法满足快速检......
  • C++ 字符串完全指南:学习基础知识到掌握高级应用技巧
    C++字符串字符串用于存储文本。一个字符串变量包含由双引号括起来的一组字符:示例创建一个string类型的变量并为其赋值:stringgreeting="Hello";C++字符串连接字符串连接可以使用+运算符来实现,生成一个新的字符串。示例:stringfirstName="John";stringlastN......