MyBatis操作数据库
创始人
2024-06-01 15:13:23
0

目录

MyBatis

功能架构

学习MyBatis

第一个MyBatis查询

1、创建数据库和表

2、搭建MyBatis开发环境

2.1、在项目中添加MyBatis框架

2.2、配置数据库连接信息

2.3、配置MyBatis中xml的保存路径(规则)

3、添加业务代码

3.1、创建实体类

3.2、构建Mapper层的代码实现(接口+XML)

SpringBoot单元测试

1、优点

2、执行单元测试

2.1、生成单元测试

2.2、添加单元测试的代码

1、添加用户

1.1、在接口中声明方法

1.2、在xml中提供实现

1.3、后端实现

1.4、测试

2、添加并返回用户的自增ID

2.1、在接口中声明方法

2.2、在xml中提供实现

2.3、后端实现

2.4、测试

3、修改用户信息(姓名)

3.1、在接口中声明方法

3.2、在xml中提供实现

3.3、后端实现

3.4、测试

4、删除用户信息

4.1、在接口中声明方法

4.2、在xml中提供实现

4.3、后端实现

4.4、测试

5、查询所有用户信息

5.1、在接口中声明方法

5.2、在xml中提供实现

5.3、后端实现

查询操作

1、单表查询

1.1、参数占位符#{}和{}

1.2、${}的优点

1.3、SQL注入

1.4、like查询

2、多表查询

2.1、返回类型:resultType

2.2、返回字典映射:resultMap

2.3、一对一的表映射

2.4、一对多

动态SQL使用

1、标签

2、标签

3、标签

4、标签

5、标签


MyBatis

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

功能架构

Mybatis的功能架构分为三层:

(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

学习MyBatis

1、配置MyBatis开发环境

2、使用MyBatis模式和语法操作数据库

第一个MyBatis查询

1、创建数据库和表

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
use mycnblog;-- 创建表[用户表]
drop table if exists  userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default '',createtime datetime,updatetime datetime,`state` int default 1
) default charset 'utf8mb4';-- 创建文章表
drop table if exists  articleinfo;
create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime datetime,updatetime datetime,uid int not null,rcount int not null default 1,`state` int default 1
)default charset 'utf8mb4';-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(vid int primary key,`title` varchar(250),`url` varchar(1000),createtime datetime,updatetime datetime,uid int
)default charset 'utf8mb4';-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES 
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);-- 文章添加测试数据
insert into articleinfo(title,content,uid)values('Java','Java正文',1);-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);

2、搭建MyBatis开发环境

2.1、在项目中添加MyBatis框架

老项目中添加MyBatis

新项目中添加MyBatis框架

2.2、配置数据库连接信息

spring.datasource.url=jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource..password=19930112
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.3、配置MyBatis中xml的保存路径(规则)

MyBatis组成:

1、接口(表的所有操作方法)->给程序其他类的调用

2、XML实现接口->写具体SQL语句 

3、添加业务代码

实现MyBatis查询所有用户的功能

3.1、创建实体类

@Data
public class Userinfo {private int id;private String username;private String password;private String photo;private LocalDateTime createtime;private LocalDateTime updatetime;private int state;
}

3.2、构建Mapper层的代码实现(接口+XML)

先创建接口

@Mapper
public interface UserMapper {/*根据用户id查询*/Userinfo getUserById(Integer id);}

创建xml实现

实现服务层

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public Userinfo getUserById(Integer id){return userMapper.getUserById(id);}
}

实现控制器

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/getUserById")public Userinfo getUserById(Integer id){if (id==null) return null;return userService.getUserById(id);}
}

SpringBoot单元测试

1、优点

1、方便、快捷测试一个功能模块;

2、在打包时会运行所有的单元测试,只有所有的单元测试都通过之后才能正常的打包,这个过程可以减少问题发生的概率;

3、使用单元测试可以在不污染数据库数据的情况下,来测试某个功能的正确性

2、执行单元测试

2.1、生成单元测试

单击右键

2.2、添加单元测试的代码

后端实现 

@SpringBootTest  //表明当前单元测试是运行在Spring Boot环境中的
class UserMapperTest {//注入测试对象(属性注入)@Autowiredprivate UserMapper userMapper;@Testvoid getUserById() {//添加单元测试的运行代码Userinfo userinfo=userMapper.getUserById(1);System.out.println(userinfo);Assertions.assertEquals("admin",userinfo.getUsername());}
}

前端实现

MyBatis增删改查操作

@Transactional

在不污染数据库的前提下进行测试功能是否正确

1、添加用户

1.1、在接口中声明方法

    /*添加用户信息*/int add(Userinfo userinfo);

1.2、在xml中提供实现

    insert into userinfo(username,password,createtime,updatetime)values(#{username},#{password},#{createtime},#{updatetime})

1.3、后端实现

    @Testvoid add() {//构造对象并设置相应的值Userinfo userinfo=new Userinfo();userinfo.setUsername("边伯贤");userinfo.setPassword("1992");userinfo.setCreatetime(LocalDateTime.now());userinfo.setUpdatetime(LocalDateTime.now());//调用MyBatis添加方法执行添加操作int result=userMapper.add(userinfo);System.out.println("添加:"+result);Assertions.assertEquals(1,result);}

1.4、测试

2、添加并返回用户的自增ID

2.1、在接口中声明方法

    /*添加并返回用户的自增ID*/int addGetId(Userinfo userinfo);

2.2、在xml中提供实现

    insert into userinfo(username,password,createtime,updatetime)values(#{username},#{password},#{createtime},#{updatetime})

2.3、后端实现

    @Testvoid addGetId() {//构造对象并设置相应的值Userinfo userinfo=new Userinfo();userinfo.setUsername("郑秀晶");userinfo.setPassword("1994");userinfo.setCreatetime(LocalDateTime.now());userinfo.setUpdatetime(LocalDateTime.now());//调用MyBatis添加方法执行添加操作int result=userMapper.addGetId(userinfo);System.out.println("添加:"+result);int uid=userinfo.getId();System.out.println("用户id:"+uid);Assertions.assertEquals(1,result);}

2.4、测试

3、修改用户信息(姓名)

3.1、在接口中声明方法

    /*修改*/int upUserName(Userinfo userinfo);

3.2、在xml中提供实现

    update userinfo set username=#{username} where id=#{id}

3.3、后端实现

    @Testvoid upUserName() {//构造对象并设置相应的值Userinfo userinfo=new Userinfo();userinfo.setId(3);userinfo.setUsername("嘟嘟");int result=userMapper.upUserName(userinfo);System.out.println("修改:"+userinfo);}

3.4、测试

4、删除用户信息

4.1、在接口中声明方法

    /*删除*/int delById(@Param("id") Integer id);

4.2、在xml中提供实现

    delete from userinfo where id=#{id}

4.3、后端实现

    @Testvoid delById() {Integer id=4;int result=userMapper.delById(id);System.out.println("删除:"+result);}

4.4、测试

5、查询所有用户信息

5.1、在接口中声明方法

    /*查询全部*/List getAll();

5.2、在xml中提供实现

    

5.3、后端实现

    @Testvoid getAll() {List list=userMapper.getAll();Assertions.assertEquals(1,list.size());}

查询操作

1、单表查询

1.1、参数占位符#{}和{}

#{}:预编译处理

${}:字符直接替换

预编译处理是指: MyBatis 在处理#()时,会将SQL中的#0}替换为?号,使用PreparedStatement的set方法来赋值。

直接替换:是MyBatis 在处理${0}时,就是把${}替换成变量的值。

区别:

1、${}存在SQL注入问题,而#{}不存在;

2、${}直接替换,#{}是预处理 

1.2、${}的优点

 它会把其内部变量解析为字符串值拼接到一条语句上,不会做其余的处理,例如加''

1.3、SQL注入

1.4、like查询

like查询要使用concat()连接

List getListByName(@Param("username") String username);
    
    @Testvoid getListByName() {String username="伯";List list=userMapper.getListByName(username);System.out.println("list:"+list);}

2、多表查询

2.1、返回类型:resultType

数据库表中的字段名和实体类中的属性完全一致时,才能使用,否则会出现数据不显示的情况

2.2、返回字典映射:resultMap

使用场景:实现程序中属性和表中字段的映射功能(当程序中的属性和表的字段不一致时,可以强行的映射到一起)

当程序中的属性和数据库的字段名不一致时的解决方案:

1、使用resultMap标签;

2、使用数据库别名as重命名 

    

2.3、一对一的表映射

使用标签

联表查询

@Data
public class Articleinfo {private int id;private String title;private String content;private String createtime;private String updatetime;private int uid;private int rcount;private int state;
}
@Data
public class ArticleinfoVO extends Articleinfo{private String username;
}
@Mapper
public interface ArticleMapper {ArticleinfoVO getById(@Param("id") Integer id);
}
    
@SpringBootTest
class ArticleMapperTest {@Autowiredprivate ArticleMapper articleMapper;@Testvoid getById() {ArticleinfoVO articleinfoVO=articleMapper.getById(1);System.out.println(":"+articleinfoVO);}
}

问题:扩展类 继承了基类,但是在查询时,只展示出了扩展类的字段,而没有展示基础类的字段

在扩展类页面单击右键

@Data
public class ArticleinfoVO extends Articleinfo implements Serializable{private String username;@Overridepublic String toString() {return "ArticleinfoVO{" +"username='" + username + '\'' +"} " + super.toString();}
}

2.4、一对多

使用标签

联表查询语句(left.join/inner join)+XXXVO

动态SQL使用

能够满足复杂条件的sql连接 

1、标签

语法:

...

test会产生一个boolean类型的结果,如果是true,那么执行if标签里边的内容,如果是false,那么就不执行if标签里边的内容

    int add2(Userinfo userinfo);
    insert into userinfo(username,photo;password)values(#{username},#{photo},#{password})
    @Testvoid add2() {Userinfo userinfo=new Userinfo();userinfo.setUsername("krystal");userinfo.setPhoto(null);userinfo.setPassword("1994");int result=userMapper.add2(userinfo);System.out.println("结果是"+result);}

2、标签

 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。 

语法:

username,password,photo,

prefix是指在最前边加上某个内容

suffix是指在最后边加上某个内容

suffixoverrides 是指如果做后边是某个值时就去掉

    int add3(Userinfo userinfo);
    insert into userinfousername,password,photo,values#{username},#{password},#{photo},
    @Testvoid add3() {Userinfo userinfo=new Userinfo();userinfo.setUsername("sehun");userinfo.setPassword("1994");userinfo.setPhoto("exo.jpg");int result=userMapper.add3(userinfo);System.out.println("添加:"+result);}

3、标签

语法:

username=#{username}and password=#{password}

特征:

1、where标签通常要配合if标签一起使用;

2、where标签会删除最前边的and关键字(不会删除最后边的);

3、where标签中如果没有内容,那么也不会生成where sql关键字 

    List getListByParam(String username,String password);
    

或者

        username=#{username}and password=#{password}
    @Testvoid getListByParam() {List list=userMapper.getListByParam("krystal","1994");System.out.println("list:"+list);}

4、标签

根据传入的用户对象属性来更新用户数据,使用标签来指定动态内容

语法:

username=#{username},password=#{password},photo=#{photo}

特征:

1、set标签通常要配合if标签一起使用;

2、set标签会自动去除最后一个英文逗号

    int update2(Userinfo userinfo);
    update userinfousername=#{username},password=#{password},photo=#{photo}where id=#{id}
    @Testvoid update2() {Userinfo userinfo=new Userinfo();userinfo.setId(2);userinfo.setUsername("啵啵虎");userinfo.setPassword("1992");userinfo.setPhoto("exo.jpg");int result=userMapper.update2(userinfo);System.out.println("修改:"+result);}

5、标签

对集合进行遍历时可以使用该标签

标签有如下属性: .

collection: 绑定方法参数中的集合,如List, Set, Map或数组对象

item:遍历时的每一个对象

open: 语句块开头的字符串

close: 语句块结束的字符串

separator: 每次遍历之间间隔的字符串

    int dels(List ids);
    delete from userinfo where id in#{id}
    @Testvoid dels() {List ids=new ArrayList<>();ids.add(4);ids.add(5);int result=userMapper.dels(ids);System.out.println("删除:"+result);}

相关内容

热门资讯

中国青少年网球城市挑战赛(内蒙... 转自:内蒙古日报本报5月17日讯  (记者  柴思源)5月16日上午,第二届中国青少年网球城市挑战赛...
焕发博物馆持久活力 转自:内蒙古日报□袁宝年  内蒙古博物院推出“北疆文脉·新启未来”主题活动,将“10平米”博物馆植入...
园区强支撑 云咖正跃升 转自:云南日报在位于昆明经开区(自贸试验区昆明片区)的云南中啡食品有限公司智能化生产线上,经过烘焙、...
乌兰察布:让劳务品牌成为促就业... 转自:内蒙古日报本报乌兰察布5月17日电  (记者  郭奇男)近年来,乌兰察布市人力资源和社会保障局...
坚持问题导向和严的标准 分类指...   新华社石家庄5月17日电 中共中央政治局常委、中央书记处书记蔡奇16日至17日在河北唐山市检查指...
北京成立我国首个脑机接口临床病...   本报讯(记者 柴嵘)昨天,北京天坛医院成立脑机接口临床与转化病房,将通过开展科研及临床试验,推动...
前4月我区新能源发电量突破10... 转自:内蒙古日报本报5月17日讯  (记者  康丽娜)据自治区能源局最新消息,今年前4月,自治区新能...
大运河岸有座糯米大坝 大运河连镇段曲折多弯,被称为“九曲十八弯”。 陈鑫露摄  本报记者 李如意 通讯员 宋昀倩  大运河...
梅洛尼会见默茨时称自己非 “国...   意大利总理梅洛尼在被问及是否会为德国总理默茨即将与美国总统唐纳德・特朗普的会面提供建议时表示,自...
50名日本青年解锁课本外的立体... 北京语言大学的学生和日本青年分组讨论。 主办方供图  本报记者 吴娜 实习生 孙择 隆楚妍  5月1...
迈出艰难一步 未实现突破   俄罗斯和乌克兰代表团16日在土耳其伊斯坦布尔举行双方三年多来的首次直接谈判。双方就互换1000名...
逐“光”而行向未来——在“中国... 来源:新华网 .新华社武汉5月17日电 能背在身上的激光工坊、可每秒传输1.2TB数据的光纤、会自动...
潘展乐全国游泳冠军赛夺冠 来源:新华社微博 【潘展乐400米自夺冠】在刚刚举行的2025年全国游泳冠军赛男子400米自由泳决赛...
岛内舆论担忧“非核家园”冲击台... 来源:新华网 新华社台北5月17日电(记者李建华)台湾第三核能发电厂(简称核三厂)2号机17日正式除...
2025创新核药专题会议在锡举... 来源:无锡日报  昨天(5月17日),2025太湖湾生命健康未来大会平行论坛之一——2025创新核药...
市领导调研便民就医公共交通优化... 来源:无锡日报市领导调研便民就医公共交通优化提升工作 “一院一策”优化就医公共交通体系 细致入微解决...
以军过去48小时行动致加沙地带... 转自:财联社【以军过去48小时行动致加沙地带200人死亡】财联社5月18日电,据加沙政府媒体办公室当...
转存了解!这件即将归国的文物大... 当地时间5月16日,国家文物局在中国驻美国大使馆接收美国史密森尼学会国立亚洲艺术博物馆返还的子弹库帛...
“流动探头”赋能基层社会治理 本报果洛讯 (记者 余晖 李永波) 5月14日,果洛藏族自治州玛沁县委社会工作部举办玛沁县“流动探头...
返回海晏村创业的年轻人 夕阳熔金、晚霞绚烂,昆明滇池之畔的海晏古渔村,正以其独特的魅力吸引着游客的目光。这里有着“落霞与孤鹜...