目录
1.MyBatis是什么?
2.为什么要学习 MyBatis?
3.怎么学MyBatis?
4.第⼀个MyBatis查询
4.1创建数据库表
4.2 添加MyBatis框架⽀持
4.3配置连接字符串和MyBatis
4.3.1配置连接字符串
4.3.2 配置 MyBatis 中的 XML 路径
4.4添加业务代码
4.4.1 添加实体类
4.4.2添加Mapper接口
4.4.3 添加 UserMapper.xml
4.4.4 添加 Service
4.4.5 添加 Controller
4.4.6 使⽤ postman 测试
4.4.7带有参数的查询
5.增、删、改操作
5.1增加操作
5.2 修改⽤户操作
5.3 删除⽤户操作
6.查询操作
6.1 单表查询
编辑
编辑
编辑
6.1.1 参数占位符 #{} 和 ${}
6.1.2SQL注入问题
6.1.3${} 优点
6.1.4 like 查询
6.2多表查询
6.2.1 返回类型:resultType
6.2.2返回字典映射:resultMap
6.2.3 多表查询
6.2.3.1 ⼀对⼀的表映射
7.复杂情况:动态SQL使⽤
7.1 标签
7.2 标签
7.3 标签
7.4 标签
7.5 标签
8.补充
-- 创建数据库
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 default now(),
updatetime datetime default now(),
`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 default now(),
updatetime datetime default now(),
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 default now(),
updatetime datetime default now(),
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://ww
w.baidu.com',1);
select * from userinfo;
select * from userinfo where username='admin' and password= '' or 1='1';
select * from userinfo ORDER BY id DESC;
select * from userinfo where username like CONCAT('%','m','%');
在创建新项目时,在添加Spring框架的基础上,加入MyBatis FrameWork和MySQL Driver框架支持。
在application.yml文件中添加以下内容:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
username: root
password: 111111
driver-class-name: com.mysql.cj.jdbc.Driver
MyBatis 的 XML 中保存是查询数据库的具体操作 SQL,配置如下:
#数据库配置
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
先添加用户的实体类,使用Data注解可以自己生成一些方法:
@Data
public class User {
private Integer id;
private String name;
private String pwd;
private String photo;
private Date createtime;
private Date updatetime;
private Integer state;
}
@Mapper
public interface UserMapper {
/**
* 查询所有数据
* @return
*/
List queryAll();
}
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List selectAllUser() {
return userMapper.queryAll();
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/selectAll")
public List selectAllUser(){
return userService.selectAllUser();
}
}
/**
* 根据id查询
* 当只有一个参数时,可以不用加注解,参数名可以随便写,可以不一样
*/
User queryById(@Param("uid") Integer id);
当只有一个参数时,接口内的参数名可以随便写,不用加注解,有多个参数时,需要添加@Param注解,注解内的value值与xml中的要一致。
把xml文件中的id改成uid,可以执行成功。
mapper接口:
Integer insert(User user);
xml实现:
insert into userinfo (username,password,photo) values(#{username},#{password},#{photo})
使用Test方法实现结果:
如果设置了Param注解,就必须要使用Param注解的命名
Integer insert2(@Param("userinfo") User user);
insert into userinfo (username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
想要拿到自增id,可以在xml文件的insert标签里面添加以下内容:
insert into userinfo (username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
mapper接口:
void update(User user);
update userinfo set username=#{username},password=#{password} where id=#{id}
mapper接口:
/**
* 删除数据
*/
void delete(Integer id);
mapper.xml 实现代码:
delete from userinfo where id=#{id}
上面我们已经实现了简单的单表查询操作,但我们的SQL语句属性都使用的是#,如果换成$会有什么结果呢?
根据id查询:
User queryById(@Param("uid") Integer id);
使用#查询结果:
使用$查询结果:
根据name查询:
User queryByName(String username);
使用#:
使用$:
为什么使用$就会出现异常呢?
User queryByNameAndPassword(@Param("username") String username,@Param("password") String password);
@Test
void queryByNameAndPassword() {
String username="admin";
// String password="admin";
String password="' or 1='1";
User user=userMapper.queryByNameAndPassword(username,password);
log.info(user==null?null:user.toString());
}
可以从上述的结果中发现,我们给密码赋值为“' or 1='1” ,即使不需要密码,也可以查出全部信息,这就会造成很严重的安全问题。
当我们使用#{}进行排序操作时:
通过结果可以发现,当我们使用#操作时,会将传入排序的方法认为是想要查询的值,程序查不出来就会报错。
使用${}:
当我们使用${},程序就可以正常的查询出来。
所以排序时,只能使用${},为了防止SQL注入的问题,我们再前端让用户只能点击来排序,参数由后端来拼接,后端在查询之前,对参数进行校验,只能传入两个值:desc,asc。
使用#{}:
当使用#{}时,程序会报错;
使用${}:
使用${}不会报错,但${}存在SQL注入问题,该怎么解决呢?
使用mysql的内置函数concat:
然⽽即使是最简单查询⽤户的名称也要设置返回的类型,否则会出现如下错误:
一个xml文件中可以存在多个resultMap,只要id不同就可以。
如果程序中的属性和SQL字段名不一致,就会查不出来,但使用resultMap就可以解决这个问题。
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private Date createtime;
private Date updatetime;
private Integer uid;
private Integer rcount;
private Integer state;
// //作者相关信息
private User user;
private String username;
}
此时我们就需要使⽤特殊的⼿段来实现联表查询了。
⼀对⼀映射要使⽤
引入其他xml的resultMap,路径是:xml的namespace+resultMap的id
常见使用写法:
insert into articleinfo(
title
,content
,uid
,state
)
values
(
#{title}
,#{content}
,#{uid}
,#{state}
)
这时候就可以使用trim标签:
insert into articleinfo
title
,content
,uid
,state
values
#{title}
,#{content}
,#{uid}
,#{state}
ListqueryByCondition(@Param("uid") Integer uid,@Param("state") Integer state);
我们传入两个参数:
但当我们只传入一个参数时:
报错了,where后面直接跟的and,第一个参数不传,结果where和and中间的数据没有了,造成sql语句报错,该怎么解决呢?
1.在where后面加1=1
2.使用where标签:
一条数据都不传入:
根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤
当我们更新多个字段时,也会出现与上面一样的问题,我们就可以通过set标签来解决:
update articleinfo
state=#{state},
uid=#{state};
void batchDelete(@Param("ids") Listids);
delete from articleinfo where id in
#{deleteId}
MyBatis的实现有两种方式:
1.xml方式,也就是我们上面所用到的方式
2.注解方式
@Mapper
public interface UserMapper2 {
@Select("select * from userinfo")
List queryAll();
@Select("select * from userinfo where id= #{id}")
List queryById(Integer id);
}
对于比较简单的SQL语句,注解的方式写起来很简单,但是负责一点的SQL语句写起来会非常复杂
字符串的拼接很繁琐,而且没有错误提示,比较不适合新手,所以新手学习MyBatis框架,建议先使用xml方式再学习注解的方式。