当前位置: 首页 > news >正文

MyBatis入门:快速搭建数据库操作框架 + 增删改查(CRUD)

一、创建Mybatis的项目

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加MySQL驱动

1.添加依赖

或者 手动添加依赖

        <!--Mybatis 依赖包--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.4</version></dependency><!--mysql驱动包--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>

项⽬⼯程创建完成后,⾃动在pom.xml⽂件中,导⼊Mybatis依赖和MySQL驱动依赖

版本会随着SpringBoot 版本发⽣变化

SpringBoot 3.X对⽤MyBatis版本为3.X

对应关系参考:Introduction – mybatis-spring-boot-autoconfigure

2.配置常见的数据库信息

这是常见关于Mybatis的配置信息,大家可以自取

csdn暂时还不支持yml文件,这是 yml 文件:

spring:datasource:                      # 配置数据库名url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: root  #数据库用户password: root  #密码driver-class-name: com.mysql.cj.jdbc.Driver# 设置 Mybatis 的 xml 保存路径
mybatis:  mapper-locations: classpath:mapper/*Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true  #自动驼峰转换

前提是有这样的一个数据库

那么这里提供一个数据库:

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; -- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );-- 创建文章表
DROP TABLE IF EXISTS article_info;CREATE TABLE article_info (id INT PRIMARY KEY auto_increment,title VARCHAR ( 100 ) NOT NULL,content TEXT NOT NULL,uid INT NOT NULL,delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now() 
) DEFAULT charset 'utf8mb4';-- 插入测试数据
INSERT INTO article_info ( title, content, uid ) VALUES ( 'Java', 'Java正文', 1 );

这样一个表

3.写对应的对象

一般写在model文件夹下

@Data
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;//数据库用下划线连接单词,java直接用小驼峰private Integer deleteFlag;private Date createTime;private Date updateTime;}

4.写持久层代码

一般写在mapper文件夹下,或者Dao

@Mapper
public interface UserInfoMapper {//查询所有用户的信息@Select("select * from user_info")List<UserInfo> selectAll();
}

5.单元测试

在对应的mapper接口下,右击

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectAll() {userInfoMapper.selectAll().forEach(x -> System.out.println(x));//等同于
//        List<UserInfo> userInfos = userInfoMapper.selectAll();
//        for (UserInfo userInfo : userInfos) {
//            System.out.println(userInfo);
//        }}
}

结果:

二、Mybatis的基本操作

1.日志打印

2.传递单个参数

通过 #{……} 传递 参数

@Mapper
public interface UserInfoMapper {//                 只有一个参数的时候这里写什么名字无所谓@Select("select * from user_info where id = #{id}")UserInfo selectUserById(Integer id);
}

单元测试:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserById() {System.out.println(userInfoMapper.selectUserById(2));}
}

结果:

3.传递多个参数

3种方法

方法1:

标签 和 方法 中的名字一样

方法2:

它给方法的每个形参取了别名,例如第一个param1 第二个 param2

方法3:

使用@Param("……"),和 标签中的 #{……}对应

@Mapper
public interface UserInfoMapper {//    @Select("select * from user_info where id = #{id} and gender = #{gender}")   方法1    推荐//    @Select("select * from user_info where id = #{param2} and gender = #{param1}")  方法2   不推荐//    @Select("select * from user_info where id = #{id2} and gender = #{gender2}")  错误//@Select("select * from user_info where id = #{id2} and gender = #{gender2}") // 方法3   推荐List<UserInfo> selectUserByIdAndGender(@Param("id2") Integer id,@Param("gender2") Integer gender);}

单元测试:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectUserByIdAndGender() {List<UserInfo> userInfos = userInfoMapper.selectUserByIdAndGender(3, 1);System.out.println(userInfos);}
}

结果:

返回的参数可以是对象,也可以是集合类:

当我们知道数据库中对应的参数只有一个时,可以用类接收,但是最好用集合,万一他人增加了符号相同条件的数据,一个类就装不下。

4.查(Select)

查询之前已经都写到了,就不再写了。

发现这样的一个问题:

数据库的规范是单词之间用下划线分割,java的变量规范是小驼峰命名。这就导致了属性对应不上导致为null

解决办法,我先讲最推荐的:

4.1 开启驼峰命名

在yml或者properties文件中设置:

# 设置 Mybatis 的 xml 保存路径
mybatis:mapper-locations: classpath:mapper/*Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true  #自动驼峰转换

4.2 起别名

@Mapper
public interface UserInfoMapper {@Select("select id, username, password, age, gender, phone, delete_flag as deleteFlag, " +"create_time as createTime, update_time as updateTime from user_info")List<UserInfo> selectAll2();}

即便是不用起别名也不建议用 select *就应该用到哪一列写哪一列,即便是所有的列都需要也这么写,因为更加规范。

4.3 结构映射

4.3.1 @Results 和 @Result
@Mapper
public interface UserInfoMapper {//    @Select("select id, username, password, age, gender, phone, delete_flag as deleteFlag, " +
//            "create_time as createTime, update_time as updateTime from user_info")@Results({@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})@Select("select id, username, password, age, gender, phone, delete_flag, create_time, update_time from user_info")List<UserInfo> selectAll2();
}

这样比起别名麻烦呀,那么真实用法是这样:

4.3.2 @ResultMap

5.增(Insert)

5.1传递对象

方法一:

@Mapper
public interface UserInfoMapper {@Insert("insert into user_info (username, `password`, age, gender) values (#{username},#{password},#{age},#{gender})")Integer insertUser(UserInfo userInfo);}

Mapper层

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUser() {UserInfo userInfo = new UserInfo();userInfo.setUsername("张三");userInfo.setPassword("123445");userInfo.setAge(19);userInfo.setGender(0);userInfoMapper.insertUser(userInfo);}}

成功:

方法二:

@Mapper
public interface UserInfoMapper {@Insert("insert into user_info (username, `password`, age, gender)" +"values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})")Integer insertUserByParam(@Param("userInfo") UserInfo userInfo);
}
@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUserByParam() {UserInfo userInfo = new UserInfo();userInfo.setUsername("李四");userInfo.setPassword("jaba213");userInfo.setAge(19);userInfo.setGender(0);userInfoMapper.insertUser(userInfo);}
}

6.删(Delete)

删除的时候一般使用id删除

假设我们现在是pdd的员工,我们下单了一个商品但是还没有付钱,那么此时我们就需要拿到这个订单的id,如果在10分钟内不付钱,我们就删除这个订单。

那么我们就需要在插入之后拿到id,可以用这个注解:

6.1 @Options

@Mapper
public interface UserInfoMapper {@Delete("delete from user_info where id = #{id}")Integer delete(Integer id);@Options(useGeneratedKeys = true, keyProperty = "id")@Insert("insert into user_info (username, `password`, age, gender)" +"values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})")Integer insertUserByParam(@Param("userInfo") UserInfo userInfo);}

单元测试:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUserByParam() {UserInfo userInfo = new UserInfo();userInfo.setUsername("wangmaz");userInfo.setPassword("54231");userInfo.setAge(19);userInfo.setGender(0);//返回影响的行数Integer result = userInfoMapper.insertUserByParam(userInfo);//                                                  通过getId()获取            System.out.println("执行结果" + result + " ,id : " + userInfo.getId());}

结果:

那么拿到数据你想用这个id干什么自己处理就好了

普通的删除:

@Mapper
public interface UserInfoMapper {@Delete("delete from user_info where id = #{id}")Integer delete(Integer id);}

单元测试:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid delete() {
//    删除id为11的数据userInfoMapper.delete(11);}
}

运行前:

运行后:

7.改(Update)

@Mapper
public interface UserInfoMapper {@Update("update user_info set password = #{password} where id = #{id}")Integer update(Integer id, String password);
}
@Mapper
public interface UserInfoMapper {@Update("update user_info set password = #{password} where id = #{id}")Integer update(Integer id, String password);
}

修改前:

修改后 :

三、报错信息

看到这样的报错“密码错误”,直接去看配置信息

数据库返回结构太多,方法定义的返回结果不匹配

标签参数和方法参数不匹配

相关文章:

  • Web字体本地化的一种方案
  • 电动式传声器与电容式传声器
  • 【区间dp】-----例题4【凸多边形的划分】
  • 【前端基础】Promise 详解
  • Android Studio 介绍
  • 基于Robust Video Matting 使用Unity 实现无绿幕实时人像抠图
  • 编程日志5.19
  • 人工智能100问☞第33问:什么是计算机视觉?
  • 遥感解译项目Land-Cover-Semantic-Segmentation-PyTorch之三制作训练数据
  • 从无符号长整型数中提取字节
  • 力扣刷题Day 56:岛屿数量(200)
  • 策略模式与责任链模式学习笔记:从入门到理解
  • 如何选择自动化编程平台
  • OpenSSL 签名验证详解:PKCS7* p7、cafile 与 RSA 验签实现
  • 【windwos】文本编辑器Notepad++ 替代品Notepad--
  • 支持向量机(SVM)例题
  • 综合实现案例 LVS keepalived mysql 等
  • 深入解析Spring Boot与Redis集成:高效缓存与性能优化实践
  • 《软件工程》第 3 章 -需求工程概论
  • vae 视频截图 复习 gans和vae的原理区别
  • 黑彩网站怎么做/市场调研报告范文2000
  • 做公司网站怎么推广/微信销售平台
  • 公司网站备案怎么做/职业技能培训班
  • 网站虚拟主机哪个好/seo网站排名查询
  • 大连开发区网站制作建设公司/seo外包服务项目
  • b站+网站建设/品牌推广工作内容