mybatis
概念:
mybatis是一款基于Java的优秀的持久层框架,使用者只用关注SQL语句而不需要费力地去加载驱动、创建链接、创建statement等繁杂的过程。
mybatis通过XML文件或者注解将各种statement配置起来,并通过Java对象和statement中的sql语句进行映射生成最终的执行sql语句
最后mybatis框架执行SQL语句并将结果映射为Java对象返回,采用了ORM解决了实体和数据库映射的问题,对JDBC进行了封装,屏蔽了JDBC中API底层访问细节,是我们越过JDBC中的API,就可以完成对数据库的持久化操作。
开发步骤:
添加mybatis坐标
创建相关数据表
编写相关实体类
编写映射文件xxxMapper.xml
编写核心文件sqlMapConfig.xml
编写测试类
核心文件层级关系:
configuration配置:
properties属性
setting设置
typeAliases 类型别名
typeHandlers 类型处理器
objectFactory 对象工厂
plugings 插件
environment:环境
①environment 环境变量
②transactionManager 事务管理器
③DataSource 数据源
databaseldProvicder 数据库厂商标识
mappers映射器
mybatis的代理实现
测试
@Test
public void testProxyDao() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获得MyBatis框架生成的UserMapper接口的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}
要求
Mapper 接口开发需要遵循以下规范:
①) Mapper.xml文件中的namespace与mapper接口的全限定名相同
② Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
③ Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
④Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
映射文件深入
动态SQL语句编辑
foreach
循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)。
foreach标签的属性含义如下:
•collection:代表要遍历的集合元素,注意编写时不要写#{}
•open:代表语句的开始部分
•close:代表结束部分
•item:代表遍历集合的每个元素,生成的变量名
•sperator:代表分隔符
sql片段抽取:
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
MyBatis映射文件配置:
①导入通用PageHelper的坐标
②在mybatis核心配置文件中配置PageHelper插件
③测试分页数据获取
开发步骤
添加mybatis坐标
创建相关数据表
编写相关实体类
编写映射文件xxxMapper.xml
编写核心文件sqlMapConfig.xml
核心文件层级关系
configuration配置: properties属性 setting设置 typeAliases 类型别名 typeHandlers 类型处理器 objectFactory 对象工厂 plugings 插件 environment:环境 ①environment 环境变量 ②transactionManager 事务管理器 ③DataSource 数据源 databaseldProvicder 数据库厂商标识 mappers映射器
编写测试类
多表查询
1.1 一对一查询
1.1.1 一对一查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
![](img\图片1.png)
1.1.2一对一查询的语句
对应的sql语句:select * from orders o,user u where o.uid=u.id;
查询的结果如下:
![](img\图片2.png)
1.1.3 创建Order和User实体
```java
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
```
1.1.4 创建OrderMapper接口
```java
public interface OrderMapper {
List
}
```
1.1.5 配置OrderMapper.xml
一对多查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
![](img\图片4.png)
1.2.2 一对多查询的语句
对应的sql语句:select *,o.id oid from user u left join orders o on u.id=o.uid;
查询的结果如下:
![](img\图片5.png)
1.2.3 修改User实体
```java
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List
}
```
1.2.4 创建UserMapper接口
```java
public interface UserMapper {
List
}
```
1.2.5 配置UserMapper.xml
多对多查询
1.3.1 多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
1.3.2 多对多查询的语句
对应的sql语句:select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id
inner join role r on ur.role_id=r.id;
查询的结果如下:
![](img\图片8.png)
1.3.3 创建Role实体,修改User实体
```java
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List
//代表当前用户具备哪些角色
private List
}
public class Role {
private int id;
private String rolename;
}
```
1.3.4 添加UserMapper接口方法
```java
List
```
1.3.5 配置UserMapper.xml
注解开发
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装 实现复杂关系映射之前我们可以在映射文件中通过配置
修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可
```xml
```
或者指定扫描包含映射关系的接口所在的包也可以
```xml
```
一对多 情况下xml注解配置
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "password",column = "password"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "orderList",column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.OrderMapper.findByUid"))
})
List
}
public interface OrderMapper {
@Select("select * from orders where uid=#{uid}")
List
}
多对多 情况下
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "password",column = "password"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "roleList",column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid"))
})
List
public interface RoleMapper {
@Select("select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=#{uid}")
List
}
一对一 情况下:
public interface OrderMapper {
@Select("select * from orders")
@Results({
@Result(id=true,property = "id",column = "id"),
@Result(property = "ordertime",column = "ordertime"),
@Result(property = "total",column = "total"),
@Result(property = "user",column = "uid",
javaType = User.class,
one = @One(select = "com.itheima.mapper.UserMapper.findById"))
})
List
}