栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis

1、 框架介绍 1.1三层架构

软件开发常用架构是三层结构,一般包括以下三层:

  • 持久层:主要完成与数据库之间的操作(对数据库的增删改查)。数据库访问对象一般称为Data Access Object(简称DAO),所以持久层也叫DAO层。
  • 业务层:主要根据功能需求完成业务逻辑的定义和实现。主要是为上层提供服务,所以业务层也叫Service层或是Business层
  • 表现层:主要完成与最终软件使用用户的交互,需要有交互页面(UI),所以,表现层也叫Web层或者View层

三层架构之间的调用关系为:表现层调用业务层,业务层调用持久层,各层之间的数据交互,一般使用Java实体对象来传递数据

1.2框架 1.2.1 何为框架

框架就是一套规范,有相应规定的约束。

框架可以理解为半成品软件,框架做好后,接下来就在它的基础上进行开发。

1.2.2 为何使用框架

框架将一些冗余且重用率低的代码给我们封装好了,并且使用反射机制与动态代理机制,将代码实现了通用性,让开发人员专注于核心业务代码的实现。

1.2.3 常见的框架
Java世界中的框架非常的多,每一个框架都是为了解决某一部分或某些问题而存在的。下面列出在目前企业中流行的几种框架(一定要注意他们是用来解决哪一层问题的):

  • 持久层框架:专注于解决数据持久化的框架。常用的有mybatis、hibernate、spring jdbc等等。
  • 表现层框架:专注于解决与用户交互的框架。常见的有struts2、spring mvc等等。
  • 全栈框架: 能在各层都给出解决方案的框架。比较著名的就是spring。
     

企业中最常用的组合为Spring + Spring MVC + mybatis(SSM)

2、Mybatis简介

MyBatis是一个优秀的基于ORM的半自动轻量级持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码.

2.1 ORM思想

ORM(Object Relational Mapping)对象关系映射

O(对象模型):
实体对象,即我们在程序中根据数据库表结构建立的一个个实体javaBean
R(关系型数据库的数据结构):
关系数据库领域的Relational(建立的数据库表)
M(映射):
从R(数据库)到O(对象模型)的映射,可通过XML文件映射

2.2 实现
  1. 让实体类和数据库表进行一一对应关系,先让实体类和数据库表对应,再让实体类属性和表里面字段对应
  2. 不需要直接操作数据库表,直接操作表对应的实体类对象

mybatis采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作

3.Mybatis快速入门 3.1 MyBatis开发步骤

案例需求:
通过mybatis查询数据库user表的所有记录,封装到User对象中,打印到控制台上

步骤:

  1. 创建数据库及user表
  2. 创建maven工程,导入依赖(MySQL驱动、mybatis、junit)
  3. 编写User实体类
  4. 编写UserMapper.xml映射配置文件(ORM思想)
  5. 编写SqlMapConfig.xml核心配置文件 , 数据库环境配置 , 映射关系配置的引入(引入映射配置文件的路径)
  6. 编写测试代码
    1. 加载核心配置文件
    2. 获取sqlSessionFactory工厂对象
    3. 获取sqlSession会话对象
    4. 执行sql
    5. 打印结果
    6. 释放资源

具体开发步骤:MyBatis开发步骤

4.Mybatis核心文件概述 4.1MyBatis核心配置文件层级关系

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
配置文档的顶层结构如下

 4.2 MyBatis常用配置解析 4.2.1 environments标签

数据库环境的配置,支持多环境配置

事务管理器(transactionManager)类型有两种:

  1. JDBC: 这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
  2. MANAGED: 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。 例如:mybatis与spring整合后,事务交给spring容器管理。
     

数据源(dataSource)常用类型有三种:

  1. NPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
  2. POOLED: 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
  3. JNDI : 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用
     
4.2.2 properties标签

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties:

jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql:///mybatis_db 
jdbc.username=root 
jdbc.password=123123

 4.2.3 typeAliases标签

类型别名是为 Java 类型设置一个短的名字。

4.2.4 mappers标签

该标签的作用是加载映射的,加载方式有如下几种:

1. 使用相对于类路径的资源引用,例如: 
	 
2. 使用完全限定资源定位符(URL),例如: 
	 

《下面两种mapper代理开发中使用:暂时了解》 
3. 使用映射器接口实现类的完全限定类名,例如: 
	 
4. 将包内的映射器接口实现全部注册为映射器,例如: 
	
5.Mybatis的API概述 5.1API介绍 5.1.1 SqlSession工厂构建器SqlSessionFactoryBuilder

常用API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象

String resource = "org/mybatis/builder/mybatis-config.xml"; 
InputStream inputStream = Resources.getResourceAsStream(resource); 
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 
SqlSessionFactory factory = builder.build(inputStream);

Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。

5.1.2 SqlSession工厂对象SqlSessionFactory

SqlSessionFactory 有多个个方法创建SqlSession 实例。常用的有如下两个:

5.1.3 SqlSession会话对象

SqlSession 实例在 MyBatis 中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。

执行语句的方法主要有:

 T selectOne(String statement, Object parameter) 
 List selectList(String statement, Object parameter) 
int insert(String statement, Object parameter) 
int update(String statement, Object parameter) 
int delete(String statement, Object parameter)

操作事务的方法主要有:

void commit() 
void rollback()
5.2 Mybatis基本原理介绍

6.Mybatis的dao层开发使用 6.1代理开发方式 6.2.1 简介

采用 Mybatis 的基于接口代理方式实现 持久层 的开发,这种方式是我们后面进入企业的主流。
基于接口代理方式的开发只需要程序员编写 Mapper 接口,Mybatis 框架会为我们动态生成实现类的对象。

这种开发方式要求我们遵循一定的规范:

  • Mapper.xml映射文件中的namespace与mapper接口的全限定名相同
  • Mapper接口方法名和Mapper.xml映射文件中定义的每个statement的id相同
  • Mapper接口方法的输入参数类型和mapper.xml映射文件中定义的每个sql的parameterType的类型相同
  • Mapper接口方法的输出参数类型和mapper.xml映射文件中定义的每个sql的resultType的类型相同
     

Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

 6.2.2 编写UserMapper接口

public interface UserMapper { 
	public List findAll() throws Exception; 
}
6.2.3 编写UserMapper.xml
 
 
 
	 
	
		select * from user where username like concat(concat('%',#{username}),'%');
	

测试

@Test
public void testFindByUsername() throws Exception {
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
	List list = userMapper.findByUsername4("王");
	for (User user : list) {
		System.out.println(user);
	} 
}

模糊查询有四种方式,我这里写的四种里面比较推荐的那一种方式

7.1.4 ${} 与 #{} 区别【面试题】

#{} :表示一个占位符号

  • 通过#{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,# {}可以有效防止sql 注入。
  • #{} 可以接收简单类型值或 pojo 属性值。
  • 如果 parameterType 传输单个简单类型值, #{} 括号中可以是value 或其它名称。
     

${} :表示拼接sql 串

  • 通过${} 可以将 parameterType 传入的内容拼接在 sql 中且不进行jdbc 类型转换,会出现 sql 注入问题。
  • ${} 可以接收简单类型值或 pojo 属性值。
  • 如果 parameterType 传输单个简单类型值, ${} 括号中只能是value。
     
7.2 Mybatis 映射文件深入 7.2.1 返回主键

应用场景
我们很多时候有这种需求,向数据库插入一条记录后,希望能立即拿到这条记录在数据库中的主键值。

 useGeneratedKeys
public interface UserMapper {
	// 返回主键
	public void save(User user);
}


	INSERT INTO `user`(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})

注意:只适用于主键自增的数据库,mysql 和sqlserver 支持,oracle 不行。

selectKey
public interface UserMapper {
	// 返回主键
	public void save(User user);
}


	
		SELECT LAST_INSERT_ID();
	
	INSERT INTO `user`(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})

测试代码
@Test
public void testSave() throws Exception {
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
	User user = new User();
	user.setUsername("张三");
	user.setAddress("北京");
	user.setBirthday(new Date());
	user.setSex("男");
	userMapper.save(user);
	System.out.println("返回主键:" + user.getId());
}
7.2.2 动态 SQL

MyBatis练习2_动态查询

MyBatis 映射文件配置


	SELECT * FROM `user` where id = #{uid}

测试代码

@Test
public void testOrderWithUser() throws Exception {
	OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
	List list = orderMapper.findAllWithUser();
	for (Order order : list) {
		System.out.println(order);
	} 
}
@Test
public void testOrderWithUser() throws Exception {
	OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
	List list = orderMapper.findAllWithUser();
	for (Order order : list) {
		System.out.println(order);
	} 
}
7.5.3 一对多嵌套查询

查询一个用户,与此同时查询出该用户具有的订单

查询语句

-- 先查询用户
SELECT * FROM `user`;

-- 再根据用户 id 主键,查询订单列表
SELECt * FROM orders where uid = #{用户 id};

UserMapper 接口

public interface UserMapper {
	public List findAllWithOrder();
}

UserMapper.xml 映射



	
	
	
	
	
	
	
	


	SELECT * FROM orders where uid = #{uid}

测试代码

@Test
public void testUserWithOrder() throws Exception {
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
	List list = userMapper.findAllWithOrder();
	for (User user : list) {
		System.out.println(user);
	} 
}
7.5.4 多对多嵌套查询

查询用户同时查询出该用户的所有角色

查询语句

-- 先查询用户
SELECT * FROM `user`;

-- 再根据用户 id 主键,查询角色列表
SELECt * 
FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid`
WHERe ur.`uid` = #{用户 id};

UserMapper 接口

public interface UserMapper {
	public List findAllWithRole();
}

UserMapper.xml 映射



	
	
	
	
	
	
	
	



	SELECT 	r.id,r.`role_name` roleName,r.`role_desc` roleDesc 
	FROM 	role r INNER JOIN user_role ur ON r.`id` = ur.`rid` 
	WHERe 	ur.`uid` = #{uid}

测试代码

@Test
public void testUserWithRole() throws Exception {
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
	List list = userMapper.findAllWithRole();
	for (User user : list) {
		System.out.println(user);
	} 
}

小结

一对一配置:使用+做配置,通过column 条件,执行 select 查询
一对多配置:使用+做配置,通过column 条件,执行 select 查询
多对多配置:使用+做配置,通过column 条件,执行 select 查询
优点:简化多表查询操作
缺点:执行多次sql 语句,浪费数据库性能
 

8.MyBatis加载策略 8.1 什么是延迟加载

实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的订单信息。此时就是我们所说的延迟加载。

就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载

优点:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表 速度要快。
缺点:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时 间,所以可能造成用户等待时间变长,造成用户体验下降。
在多表中:

  • 一对多,多对多:通常情况下采用延迟加载
  • 一对一(多对一):通常情况下采用立即加载

注意:延迟加载是基于嵌套查询来实现的
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/992183.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号