1.什么是MyBtis
MyBatis是持久层框架,⽤于简化JDBC的开发。
2.准备工作
2.1 创建⼯程
数据库:
2.2 配置数据库连接字符串
以application.yml⽂件为例:
2.3 写持久层代码
@Data
public class UserInfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
添加mapper接口:
@Mapper会告诉Spring,把对象交给Spring管理
2.4 单元测试
3. MyBatis的基础操作(注解)
3.1 打印日志
在Mybatis当中我们可以借助⽇志,查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果
#打印mtbatis日志的配置
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.2 传递参数
@Mapper
public interface UserInfoMapper {
@Select("select * from userinfo")
List<UserInfo> selectAll();
@Select("select * from userinfo where id= 1 ")
UserInfo selectOne();
@Select("select * from userinfo where id=#{id} ")
UserInfo selectOne1(Integer id);
//参数重命名
@Select("select * from userinfo where id=#{userId} ")
UserInfo selectOne2(@Param("userId") Integer id);
}
首先要添加@SpringBootTest注解,启动Spring容器,才能注入
@SpringBootTest
@Slf4j
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void selectAll() {
List<UserInfo> list = userInfoMapper.selectAll();
log.info(list.toString());
}
@Test
void selectOne() {
log.info(userInfoMapper.selectOne().toString());
}
@Test
void selectOne1() {
log.info(userInfoMapper.selectOne1(1).toString());
}
@Test
void selectOne2() {
log.info(userInfoMapper.selectOne2(1).toString());
}
}
3.3 增
①
②获取自增ID:
③对INSERT的参数进行重命名:
如果对对象进行重命名:
此时会报错:
修改:
#{对象名.属性名}
3.4 删
3.5 改
3.6 查
①
@Mapper
public interface UserInfoMapper {
/**
* 查询
* @return
*/
@Select("select * from userinfo")
List<UserInfo> selectAll();
@Select("select * from userinfo where id=#{id}")
UserInfo selectOne(Integer id);
//对参数进行重命名
@Select("select * from userinfo where id=#{id123}")
UserInfo selectOne2(@Param("id123") Integer id);
}
②结果映射
MyBatis会自动把mysql返回的数据,和java对象进行映射(规则:名称一致)
如果mysql字段名和java对象的属性不一致:
方法一:对字段进行重命名(不推荐)
方法二:@Results注解
想重复利用的话,进行命名:
方法三: 自动转驼峰
4. MyBatis XML配置⽂件
4.1 配置数据库连接字符串和MyBatis
4.2 写持久层代码
1. 方法定义Interface
2. 方法实现 XXX.xml
4.2.1 添加mapper接口
4.2.2 添加UserInfoXMLMapper.xml
数据持久成的实现,MyBatis的固定xml格式:
4.2.3 单元测试(同注释)
4.3 增删改查
4.3.1 增
UserInfoXMLMapper接⼝:
@Mapper
public interface UserInfoXMLMapper {
Integer insert(UserInfo userInfo);
}
UserInfoXMLMapper.xml实现:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserInfoXMLMapper">
<insert id="insert">
insert into userinfo (username,password,age,gender,phone)
values(#{username},#{password},#{age},#{gender},#{phone})
</insert>
</mapper>
单元测试:
@Slf4j
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("java108");
userInfo.setPassword("java108");
userInfo.setAge(1);
userInfo.setGender(2);
userInfo.setPhone("456567899231");
Integer result= userInfoXMLMapper.insert(userInfo);
log.info("影响行数:{}, 插入的结果ID:{}",result,userInfo.getId());
}
}
返回自增ID:
4.3.2 删
@Mapper
public interface UserInfoXMLMapper {
Integer delete(Integer id);
}
4.3.3 改
4.3.4 查
此操作需要写全限定类名
下面来看映射操作(<resultMap标签>):
其它两种方法:1)给字段设置别名 2)配置自动转驼峰
此时有结果的映射,这个就不需要了:
5. 其他查询操作
5.1 多表查询
看打印日志:
可以看出:sql语句返回的结果有username和age,但是打印的结果没有
这是为什么呢?
因为对象里面没有username和age,所以加上
此时打印结果为:
总结:SQL中直接查询多个表,把查询的结果放在一个对象即可
5.2 #{} 和 ${}(常见面试题)
首先看Interger类型的:
使用$查询:即时SQL
使用#查询:预编译SQL
再看String类型
#:
使用$的时候报错:少了个' '
那就需要加上:
总结:使用#时,如果参数为String,会自动加上' ',$不会,$符合是直接拼接
5.3 排序
使用#,会报错
此时#给asc自动加上引号,报错
使用$,运行正确
总结:排序时,不能使用#,如果使用#,会给参数加上' '
5.4 like查询
使用#号,报错:
又多加了一个引号,报错
使用$符号,正常运行:
注意:模糊查询时,如果使用#,需要搭配mysql的内置函数concat,而不能直接使用
那既然#符号不适用某些场景,那可以只使用$嘛?
不可以,$符号存在漏洞
5.5 $符号漏洞SQL注入
SQL注⼊:
是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的⽅法。
举个例子:
正常访问:
select * from userinfo where username = 'admin'
把admin改为 'or 1 = ' 1,即select * from userinfo where username =' 'or 1 = ' 1'
此时数据库会将usrname = '' 和'1'看作一对去执行,但其实参数是'or 1 = '
其中参数or被当做了SQL语句的⼀部分
#和$区别其中之一就是预编译SQL和即时SQL的区别
1)预编译SQL性能更高
2)预编译SQL不存在SQL注入的问题
实际开发中,能使用#的,都使用#,使用$时,一定要考虑到SQL注入的问题
6.数据库连接池
6.1 介绍
数据库连接池负责分配、管理和释放数据库连接,它允许应⽤程序重复使⽤⼀个现有的数据库连接,⽽不是再重新建⽴⼀个
- 没有使⽤数据库连接池的情况:
每次执⾏SQL语句,要先创建⼀个新的连接对象,然后执⾏SQL语句,SQL 语句执⾏完,再关闭连接对象释放资源.这种重复的创建连接,销毁连接⽐较消耗资源
- 使⽤数据库连接池的情况:
程序启动时,会在数据库连接池中创建⼀定数量的Connection对象,当客⼾请求数据库连接池,会从数据库连接池中获取Connection对象,然后执⾏SQL,SQL语句执⾏完,再把 Connection归还给连接池.
6.2 优点
1. 减少了⽹络开销
2. 资源重⽤
3. 提升了系统的性能
6.3 使用
常见的数据库连接池:
- C3P0
- DBCP
- Druid
- Hikari
⽬前⽐较流⾏的是Hikari,Druid
6.3.1 Hikari
Hikari : SpringBoot默认使⽤的数据库连接池
6.3.2 Druid
如果想把默认的数据库连接池切换为Druid数据库连接池,引⼊相关依赖即可
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>