其他查询操作
多表查询
多表查询和单表查询类似,只是 SQL
不同而已
准备工作
上面我们建立了一个用户表,我们再来建立一张文章表,进行多表关联查询
- 文章表的
uid
- 对应用户表的
id
数据准备:
对应 Model
:
package com.glg.mybatis.module;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private Integer uid;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
数据查询
需求:根据 uid
查询作者的名称等相关信息
SQL:
SELECT
ta.id,
ta.title,
ta.content,
ta.uid,
tb.username,
tb.age,
tb.gender
FROM
articleinfo ta
LEFT JOIN userinfo tb ON ta.uid = tb.id
WHERE
ta.id = 1
补充实体类:
package com.glg.mybatis.model;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private Integer uid;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
// 用户相关的信息
private String username;
private Integer gender;
}
ArticleInfoMapper
接口定义:
package com.glg.mybatis.mapper;
import com.glg.mybatis.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ArticleInfoMapper {
ArticleInfo selectArticleAndUserById(Integer id);
}
ArticleInfoMapper.xml
实现:
<select id="selectArticleAndUserById" resultType="com.glg.mybatis.model.ArticleInfo">
select ta.*, tb.username, tb.gender
from articleinfo ta
left join userinfo tb
on ta.uid = tb.id
where ta.id = #{id}
</select>
#{} 和 ${}
MyBatis
参数赋值有两种⽅式,咱们前⾯使⽤了 #{}
进⾏赋值,接下来我们看下⼆者的区别
#{} 和 &{} 的使用
#{} 和 &{} 的区别
// $ 和 # 的区别
@Select("select * from userinfo where username = #{username}")
UserInfo getUserByName(String userName);
@Select("select * from userinfo where username = ${username}")
UserInfo getUserByName2(String userName);
- 在运行之后,第一个方法成功执行,但第二方法报错了
- 我们可以发现,是
SQL
语句报错了,admin
少了引号
#
:是预编译SQL
,占位的方式$
:是即时SQL
,直接拼接- 因为预编译和即时,所以
#
比$
的性能高
数据库连接池
在上面 MyBatis
的讲解中,我们使用了数据库连接池技术,避免频繁的创建连接,销毁连接
接下来我们了解一下数据库连接池
介绍
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
- 没有使用数据库连接池的情况:每次执行
SQL
语句,要先创建一个新的连接对象,然后执行SQL
语句,SQL
语句执行完,再关闭连接对象释放资源。这种重复的创建连接、销毁连接比较消耗资源 - 使用数据库连接池的情况:程序启动时,会在数据库连接池中创建一定数量的
Connection
对象,当客户请求数据库连接池,会从数据库连接池中获取Connection
对象,然后执行SQL
,SQL
语句执行完,再把Connection
归还给连接池
优点:
- 减少了网络开销
- 资源重用
- 提升了系统的性能
使用
常见的数据库连接池
C3P0
DBCP
Druid
Hikari
目前比较流行的是:Hikari
、Druid
Hikari
:SpringBoot
默认使用的是数据库连接池
Hikari
是日语“光”的意思,Hikari
也是以追求性能极致为目标
Durid
如果我们想把默认的数据库连接池切换为 Durid
数据库连接池,只需要引入相关依赖即可
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.25</version>
</dependency>
参考官方地址: https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
Durid
连接池是阿里巴巴开源数据库连接池项目- 功能强大,性能优秀,是
Java
语言最好的数据连接池之一- 学习文档: https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5
总结
MySQL 开发企业规范
- 表名,字段名使用小写字母或数字,单词之间以下划线分割。尽量避免出现数字开头或者两个下划线中间只出现数字。数据库字段名的修改代价很大,所以字段名称需要谨慎考虑
MySQL
在Windows
下不区分大小写,但在Linux
下默认是区分大小写的。因此,数据库名、表名、字段名都不允许出现任何大写字母,避免节外生枝
- 正例:
aliyun_admin
,rdc_config
,level3_name
- 反例:
AliyunAdmin
,rdcConfig
,level_3_name
- 表必备三字段:
id
,create_time
,update_time
id
必为主键,类型为bigint unsigned
,单表自增时,步长为 1
create_time
,update
的类型均为datetime
类型,create_time
表示创建时间,update_time
表示更新时间
- 在表查询中,避免使用
*
作为查询的字段列表,标明需要哪些字段
- 增加查询分析解析成本
- 增加字段容易与
resultMap
配置不一致- 无用字段增加网络消耗,尤其是
text
类型的字段