MyBatis理解

Mybatis介绍

       MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

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

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

 

java的JDBC存在的问题如下

  1. 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。
  2. Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
  3. 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
  4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

Mybatis解决jdbc编程的问题

  • 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。
  • Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
  • 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
  • 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

Mybatis架构

MyBatis理解_第1张图片

 解析:

  1. mybatis需要配置SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。而mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要SqlMapConfig.xml中加载。
  2. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
  3. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  4. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  5. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
  6. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
  7. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

sqlMapConfig.xml




	
	
		
			
			
			
			
				
				
				
				
			
		
	

SqlMapConfig.xml中配置的内容和顺序如下:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

 

 

Mybatis  sql语句中的#{}和${}

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

${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value

parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found:3 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70),selectList可以查询一条或多条记录

Mapper引射器的配置

mappers(映射器)

Mapper配置的几种方法:

使用相对于类路径的资源(现在的使用方式)    如:

使用mapper接口类路径     如:

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中

注册指定包下的所有mapper接口     如:

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中

 

Mybatis的动态sql(标签)

  



	SELECT id, username, birthday, sex, address FROM `user`
	WHERE 1=1
	
		AND sex = #{sex}
	
	
		AND username LIKE
		'%${username}%'
	

  



	SELECT id, username, birthday, sex, address FROM `user`

	
		
			AND sex = #{sex}
		
		
			AND username LIKE
			'%${username}%'
		
	

  



	
	
	SELECT  FROM `user`
	
	
		
			AND sex = #{sex}
		
		
			AND username LIKE
			'%${username}%'
		
	




	id, username, birthday, sex, address

  



	SELECT * FROM `user`
	
		
		
		
		
		
		
		
			#{item}
		
	

 

Mybatis逆向工程

注意:

  1. 逆向工程生成的代码只能做单表查询
  2. 不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了。
  3. 一张表会生成4个文件




	
		
			
			
		
		
		
		
		
		
			
		

		
		
			
			
			
			
		
        
		
			
			
		
		
		
			
			
		
		
		

一对一查询

1.使用resultType方法(自定义pojo)

       思路:将接收查询结果封装成一个pojo,这个pojo可以通过继承其中一个表的对应pojo1来创建,然后书写mapper.xml,resultType即为pojo。增加接口。

 

2.使用resultMap方法(不使用自定义pojo)

        思路:把查询结果中的信息映射到属性多的pojo中,然后在该pojo中添加另一个表的pojo1属性,将关联查询的结果映射到pojo对象中,这样就能把两个表的联合查询结果放在同一个pojo。

mapper.xml:

MyBatis理解_第2张图片

MyBatis理解_第3张图片

javatype改成property

    

两种方法对比,resultType比较简单,resultMap时候在特殊要求(要求延迟加载,要将pojo放到一个pojo)时用。

MyBatis理解_第4张图片

MyBatis理解_第5张图片

 

MyBatis理解_第6张图片

 MyBatis理解_第7张图片

 

一对多

 

多对多

 

延迟加载

 

一级缓存

 

二级缓存

 

 

 

 

你可能感兴趣的:(javase基础知识)