【JavaWeb】mybatis基础

2023-10-23 15:10:27 浏览数 (1)

前言

记录学习JavaWeb课程中的部分知识点,包括maven依赖管理、maven高阶、Mybatis、SpringBoot自动配置等。本篇是关于mybatis的相关配置,以实现对数据的增删改查功能。

MyBatis增删改查

相关配置

  1. 准备数据库表emp,sql代码如下:
代码语言:javascript复制
create table user(
     id int unsigned primary key auto_increment comment 'ID',
     name varchar(100) comment '姓名',
     age tinyint unsigned comment '年龄',
     gender tinyint unsigned comment '性别, 1:男, 2:女',
     phone varchar(11) comment '手机号'
) comment '用户表';

insert into user(id, name, age, gender, phone) VALUES (null,'白眉鹰王',55,'1','18800000000');
insert into user(id, name, age, gender, phone) VALUES (null,'金毛狮王',45,'1','18800000001');
insert into user(id, name, age, gender, phone) VALUES (null,'青翼蝠王',38,'1','18800000002');
insert into user(id, name, age, gender, phone) VALUES (null,'紫衫龙王',42,'2','18800000003');
insert into user(id, name, age, gender, phone) VALUES (null,'光明左使',37,'1','18800000004');
insert into user(id, name, age, gender, phone) VALUES (null,'光明右使',48,'1','18800000005');


select * from user;

-- 部门管理
create table dept(
     id int unsigned primary key auto_increment comment '主键ID',
     name varchar(10) not null unique comment '部门名称',
     create_time datetime not null comment '创建时间',
     update_time datetime not null comment '修改时间'
) comment '部门表';

insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());

-- 员工管理
create table emp (
     id int unsigned primary key auto_increment comment 'ID',
     username varchar(20) not null unique comment '用户名',
     password varchar(32) default '123456' comment '密码',
     name varchar(10) not null comment '姓名',
     gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
     image varchar(300) comment '图像',
     job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
     entrydate date comment '入职时间',
     dept_id int unsigned comment '部门ID',
     create_time datetime not null comment '创建时间',
     update_time datetime not null comment '修改时间'
) comment '员工表';

INSERT INTO emp(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
    (13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
  1. 创建一个新的springboot工程,选择引入对应的依赖,如mybatis、mysql驱动、lombok

其实最方便的还是新建一个空的maven项目,直接把依赖配置粘贴上去(pom.xml)

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>02-springboot-mybatis-crud</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  1. application.properties中引入数据库连接信息
代码语言:javascript复制
#配置数据库的连接信息 - 四要素
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456

#开启mybatis日志 并输出至控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  1. 创建对应的实体类Emp(实体类属性采用驼峰命名)

构造该实体类时使用了lombok中的@Data、@NoArgsConstructor及@AllArgsConstructor,简化了无参和带有各参数的构造,避免重复使用alt insert生成。

代码语言:javascript复制
package com.itheima.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id; // ID
    private String username; // 用户名
    private String password; // 密码
    private String name; // 姓名
    private Short gender; // 性别, 1 男, 2 女
    private String image; // 图像url
    private Short job; // 职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师'
    private LocalDate entrydate; // 入职日期
    private Integer deptId; // 部门ID
    private LocalDateTime createTime; // 创建时间
    private LocalDateTime updateTime; // 修改时间
}
  1. 准备Mapper接口 EmpMapper
代码语言:javascript复制
package com.itheima.mapper;

import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.util.List;

@Mapper
public interface EmpMapper {
}

增加

如果需要新增数据,sql语句应为:

代码语言:javascript复制
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values ('songyuanqiao','宋远桥',1,'1.jpg',2,'2012-10-09',2,'2022-10-01 10:00:00','2022-10-01 10:00:00');

对应的接口方法为:

代码语言:javascript复制
@Mapper
public interface EmpMapper {

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

}
参数占位符

#{…}为MyBatis的参数占位符,还有一种形式为${…}。需要注意花括号中的名称是对象的属性名(采用驼峰命名),不是数据库中的字段名。

在项目开发中,建议使用#{…},生成预编译SQL,防止SQL注入安全。

预编译SQL

预编译SQL可以提升性能,将sql语句参数化,编译一次之后会将编译后的SQL语句缓存起来,可多次运行,不需要对相同的sql语句做重复编译。同时将敏感字进行转义,保障SQL的安全性。

主键返回

如果需要在添加数据后,返回该数据对应数据表中的主键(id),只需要添加如下注解。

代码语言:javascript复制
//会自动将生成的主键值,赋值给emp对象的id属性
@Options(useGeneratedKeys = true,keyProperty = "id")

删除

根据主键删除数据,sql语句如下:

代码语言:javascript复制
delete from emp where id = 17;

接口方法如下:

代码语言:javascript复制
@Mapper
public interface EmpMapper {
    
    @Delete("delete from emp where id = #{id}")
    public void delete(Integer id);
    
}

修改

根据主键修改数据,与增加数据的方式相同,sql语句如下:

代码语言:javascript复制
update emp set username = 'linghushaoxia', name = '令狐少侠', gender = 1 , image = '1.jpg' , job = 2, entrydate = '2012-01-01', dept_id = 2, update_time = '2022-10-01 12:12:12' where id = 18;

接口方法如下:

代码语言:javascript复制
@Mapper
public interface EmpMapper {
    
    @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);
    
}

查询

根据主键查询数据,sql语句如下:

代码语言:javascript复制
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp;

查询结果中的deptId、createTime、updateTime为空, 因为数据表中的字段与实体类中的属性名不一致,导致mybatis不能自动封装。

解决方案

  1. 字段起别名
  2. @Results注解
  3. 开启mybatis驼峰命名法自动映射开关
条件查询

在实际使用中,我们可能需要根据姓名、性别、入职时间及最后修改时间多项条件对员工表进行模糊查询,

  • 姓名:要求支持模糊匹配
  • 性别:要求精确匹配
  • 入职时间:要求进行范围查询
  • 根据最后修改时间进行降序排序

可能使用的sql语句示例如下:

代码语言:javascript复制
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
where name like '%张%' 
	and gender = 1 
	and entrydate between '2010-01-01' and '2020-01-01 '
order by update_time desc;

对应两种可以使用的接口方法:

第一种(使用${…}进行字符串拼接):

代码语言:javascript复制
@Select("select * from emp where name like '%${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);

该方法并不是预编译的形式,所以效率不高、且存在sql注入风险。

第二种(使用MySQL提供的字符串拼接函数concat):

代码语言:javascript复制
@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);

函数:concat(’%’ , ‘关键字’ , ‘%’),此方法生成的SQL都是预编译的SQL语句(性能高、安全)

需要注意编写代码中的参数名规范,保证接口中方法的形参名和SQL语句中的参数占位符名相同。参数名在不同的SpringBoot版本中,处理方案也不同。

xml映射文件

通过id(对应的方法)找到对应的sql语句 来完成数据库的操作

https://mybatis.net.cn/getting-started.html

0 人点赞