多表关系的查询
多表关系有:
- 一对一:一个人只能有一个身份证号。
- 一对多:一个用户可以有多个银行卡号,一个用户可以下多个订单。
- 多对一:一个银行卡只能属于一个用户,一个订单只能属于一个用户。
- 多对对:一个用户可以有多个角色,一个角色可以有多个用户。
Mybatis多表查询的关系的分类
- Mybatis:把多对一当成一对一处理,把多对多当成一对多处理,
- Mybatis所以的多表查询关联查询只有两类:
- 一对一(多对一):一个人只有一个身份证,一个银行卡有一个用户
- 一个Account,对应一个User,在Account里面有一个User对象的引用。
- 一对多(多对多):一个用户多个Account,在User里有一个Account集合。
MySql语句查询的回顾:
- 1内连接查询
- 表示查询两张表必定有关联的数据
- 隐式内连接:select * from 表一,表二 where 表关联的条件
- 显示内连接:select * from 表一 inner join 表二 on 关联条件
SELECT * FROM account INNER JOIN role ON account.id=role.`ID`;
- 2 外连接的查询
- 左外连接的查询:查询左表的全部数据,以及右表的关联数据:select * from 表一 left join 表二 on 关联条件
- 右外连接的查询:查询右表的全部数据,以及左表关联的数据:select * from 表一 right join 表二 on 表关联的数据
- 3DQL语句
- 1.3.1条件查询:selcet 字段名 from 表名 where 条件;
- 1.3.2比较运算符:查询分数大于80分的学生:select * from student where math>80;
- 1.3.3逻辑运算符:and(&&) 多个条件同时满足or(||)多个条件其中一个不满足就not(!)
- 1.3.4查询age大于35且性别为男的学生:select * from student where age>35 and sex='男';
- 1.3.5范围BETWEEN值一AND值二表示值一到值二的范围,比如:ang between 80 and 100
- 1.3.6查询english成绩大于75且小于88的分数的学生:selset * from student where english BETWEEN 75 AND 88;
- 1.3.7模糊查询:LIKE表示模糊查询:select * from 表名 where like '通配字符串'其中%表示0个或多个字符_:表示一个字符
- 1.3.8查询性马的人:select * from student where name like '%马%';
- SELECT *FROM USER WHERE sex='男' AND username LIKE '%王%';
- 1.3.9排序是通过:ORDER BY 子句,可以将查询的结果进行排序:select 字段名 from 表名 where 字段=值 order by 字段名
- 1.4.0单列排序: 具体操作查询所有的年龄进行降序:select * from student order by age desc;
having与where的区别
having是在分组后对数据进行过滤.
where是在分组前对数据进行过滤
having后面可以使用聚合函数
where后面不可以使用聚合函数
limit语句:
1.MIMIT语法格式:比如查询学生表中的数据,从第三条开始显示,显示6条:
select * from student LIMIT 2,6;
数据库的约束:
1.主键:primary key
2.unique:唯一
3.not null:非空
4.foreign key:外键
5.主键递增:AUTO_INCREMENT
主键的作用:用来唯一标识一条语句:每个表应该都有一个主键。
一对一(多对一)关联查询
需求描述:
有用户表(user)和帐户表(account),一个用户有多个帐户,一个帐户只属于一个用户;帐户表中有外键指向用户表主键。
需求:查询帐户表信息,及其关联的用户信息
准备工作:项目列表
1.创建Maven的java显目,配置显目坐标,并引入Mybatis的依赖
2.分别创建好user表和account表的实体类:User和Account
Mybatis依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Mybatis_Note01</artifactId>
<groupId>com.itheima</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../Mybatis_Note01/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>Mybatis_Note02</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
</dependencies>
</project>
User表
package com.itheima.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.Date;
@Getter
@Setter
@ToString
public class User {
private Integer id;
private String username;
private Date birthday;//出生日期
private String sex;
private String address;//地址
}
Account表
package com.itheima.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Account {
private Integer id;
private Integer uid;
private Double money;
}
创建映射器的配置文件AccountDao.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.itheima.dao.AccountDao">
</mapper>
3.准备核心配置文件Mybatis的核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.itheima.domain"/>
</typeAliases>
<environments default="mysql_mybatis">
<environment id="mysql_mybatis">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
其中用到知识点:(重点)
4.编写单元测试类
private InputStream inputStream;
private SqlSessionFactoryBuilder builder;
private SqlSessionFactory factory;
private SqlSession session;
private UserDao dao;
@Before
public void init() throws Exception {
//1.读取核心配置文件SqlMapConfig.xml
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactoryBuilder的构造者对象
builder = new SqlSessionFactoryBuilder();
//3.使用构造者对象builder,根据配置文件的信息inputStream,构造一个SqlSessionFactory工厂对象
factory = builder.build(inputStream);
//4.使用工厂对象factory,生产一个SqlSession对象
session = factory.openSession();
//5.使用Session对象,获取映射器userDao接口的代理对象
dao = session.getMapper(UserDao.class);
}
@After
public void destory() throws Exception {
//6.释放资源
session.close();
inputStream.close();
}
需求实现
方案一:类继承方式(不推荐)
这种方式的重点在于:创建新的javaBean,定义与所有的字段对应的属性,可以使用继承的方式来减少代码量
1.创建UserAccount类,定义user表对应的属性,然后继承Account类或者
2.创建UserAccount类,定义account表对应的属性,然后继承User类
(1)创建javaBean:UserAccount
package com.itheima.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class UserAccount extends Account {
private String username;
private String address;
}
(1.1)在映射器配置文件AccountDao中增加方法
//查询所有帐号,及其关联的用户信息--类继承的方式
List<UserAccount> queryAllAccounts1();
(2)在映射器配置文件AccountDao.xml中增加statement
<select id="queryAllAccounts1" resultType="userAccount">
select a.*, u.username, u.address from account a left join user u on a.uid = u.id
</select>
(3)使用注解写开发
常用注解介绍
-
@Select:相当于映射配置文件里的select标签:用于配置查询方法的语句
-
@Insert:相当于映射配置文件里的insert标签
-
@SelectKey:相当于映射配置文件里的selectKey标签,用于添加数据后获取最新的主键值
-
@Update:相当于映射配置文件里的update标签
-
@Delete:相当于映射配置文件里的delete标签
-
@Results:相当于映射配置文件里的resultMap标签
-
@Result:相当于映射配置文件里的result标签,和@Results配合使用,封装结果集的
-
@One:相当于映射配置文件里的association,用于封装关联的一个JavaBean对象
-
@Many:相当于映射配置文件里的collection标签,用于封装关联的一个JavaBean对象集合
在映射器文件中AccounDao方法使用注解(这种方法不需写映射器的配置文件.xml)
使用到了知识点:
@Select("select a.*,u.username,u.address from account a left join user u on a.uid=u.id")
List<UserAccount> queryAllcounts2();
在单元测试类中编写test中书写测试方法
@Test
public void testDemo02(){
final List<UserAccount> userAccounts = dao.queryAllcounts2();
for (UserAccount userAccount : userAccounts) {
System.out.println(userAccount);
}
}