MyBatis大全总结

首先讨论一下基本的概念~:
(1)MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。

(2)MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

(3)MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录.
(4)是半自动化持久层框架,就是操作一个单表,也要自己写sql语句 Hibernate是全自动的sql就不容易做特殊优化
(5)jdbc编程—当我们使用jdbc持久化的时候,sql语句被硬编码到java代码中。这样耦合度太高。代码不易于维护。在实际项目开发中会经常添加sql或者修改sql,这样我们就只能到java代码中去修改。

分隔~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

使用:
需要导入jar包:
	log4j-1.2.17.jar 						日记
	mybatis-3.4.1.jar						 mybatis的
	mysql-connector-java-5.1.7-bin.jar				mysql驱动

添加配置文件:
	mybatis-config.xml						核心配置文件 名字暂时可以随便取
     log4j.properties						日记配置文件


1写一个.xml文件 充当核心配置文件
<?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>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<!-- dataSource 数据源
					POOLED	表示使用数据库连接池
			 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="root" />
			</dataSource>
		</environment>
	</environments>
	<!-- 引入sql语句对应的配置文件 -->
	<mappers>
		<mapper resource="com/xxx/pojo/UserMapper.xml" />
	</mappers>
</configuration>

2 log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n


3写数据库表单对应的javaBean对象 xxx  (我用了User类)
4写xxxMapper.xml来映射sql语句  然后将此配置文件配置到核心配置文件中去    注意名字不要改其他的 是规范    
<?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">
<!-- 
	namespace 是名称空间 属性一般情况下。
		一种定义规则:
			一种是使用对流的javaBean的全类名
			一种是使用Mapper接口的全类名
 -->
<mapper namespace="com.xxx.pojo.User">
	<!-- 
		select 定义select查询语句
			id			给你要定义的sql语句,设置一个唯一的id值。
			resultType	查询完返回的类型
			parameterType  设置参数的类型(例如在delete update insert语句中使用)
			#{id}		这是一个占位符
	 -->
	<select id="selectUserById" resultType="com.xxx .pojo.User">  //注意这里resultType对单个对象和集合都适用
		select id,last_name lastName,sex from t_user where id = #{id}
	</select>
</mapper>


5利用org.apache.ibatis.io.Resources读取核心配置文件
(1)Resources.getResourceAsStream("前面写的核心配置文件");   //返回一个输入流
(2)new SqlSessionFactoryBuilder().build(输入流);				//通过SqlSessionFactoryBuilder 创建SqlSessionFactory实例  注意此实例在一个项目中只有一个实例!~~~~~~
(3)关闭输入流
(4)通过SqlSessionFactory调用openSession方法创建SqlSession对象 (相当于Connection对象)
(6)SqlSession调用selectOne执行select查询语句返回一个对象(名称空间值+sql映射配置文件select标签id值,参数)
							selectList
							insert 等更新需要自己commit
(5)关闭SqlSession

我们可以自己写DAO接口以及实现类 然偶胡在构造器或者set方法中将sqlSessionFactory赋值进去,即可以把上面5(4)的方法通过自己写的dao来调用~

**

插入之后返回主键值

**

方法(1)insert标签:useGeneratedKeys=“true”   keyProperty="id"配置返回的值赋给对象里的id
方法(2)selectKey标签 用来定义sql语句 在其他语句之前或之后执行(此时看log会发现执行了两条语句~)
					在insert标签内部写:
					<selectKey order=“BEFORE”>SELECT	LAST_INSERT_ID()</selectKey>
					order属性设置selectKey语句执行的顺序 在这里要用after
					keyProperty配置返回的值赋给对象里的id

**

Mapper接口方式实现增删改查

**
可以不用自己写实现类 只需要写接口就可以用
要求:(1)Mapper.java类名和Mapper.xml配置文件名一样
(2)放在同一个包下
1 <mapper namespace=“接口全类名”
2 标签id必须跟接口方法名相同 parameterType和resultType也必须完全一样
3 SqlSession调用getMapper方法 参数传入接口类名.class

Mybatis接口实现的原理:JDK动态代理
1通过mapperProxyFactory.newInstance(sqlSession)创建代理对象
		底层就是Proxy.newProxyInstance返回的代理对象
		会判断调用的sql是什么方法 例如如果是select 再判断是不是返回多个还是单个 还是map 还是油表 如果是单个 就执行sqlSession.selectOne

**

利用核心配置文件properties

**

resource写上自己写的jdbc文件 里面的内容会起作用 而不是在主配置文件里的properties起做用

在这里插入图片描述
在这里插入图片描述
**

mybatis的核心配置setting

**

<settings><setting name...  value...></setting>
1 mapUnderscoreToCamelCase自动开启数据库列名的映射的驼峰标示(下划线变驼峰)  默认为false

**

mybatis的核心配置typeAliases别名

**

<typeAliases>
			<typeAlias type="全类名" alias="别名"		定义一个别名 以后这个类在配置文件中就可以用别名标示了
			<package name="包名">    自动扫描指定包下的所有类 	 别名就是类名首字母小写
</typeAliases>
若果两个包下面有相同的类名 就可以使用@Alias("别名")来定义别名

**

类处理器typeHandlers

**
Mybatis和PreparedStatement中都会使用类型处理器将获取到的值以合适的方式转换成为java类型

类型处理器								Java 类型								JDBC 类型
BooleanTypeHandler				java.lang.Boolean, boolean					数据库兼容的 BOOLEAN
ByteTypeHandler					java.lang.Byte, byte						数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandler				java.lang.Short, short						数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler				java.lang.Integer, int				 	数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler					java.lang.Long, long				 数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler					java.lang.Float, float					 数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler					java.lang.Double, double		 	数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler					java.math.BigDecimal					 数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler									java.lang.String						CHAR, VARCHAR
ClobReaderTypeHandler								java.io.Reader						-
ClobTypeHandler						java.lang.String								CLOB, LONGVARCHAR
NStringTypeHandler					java.lang.String								NVARCHAR, NCHAR
NClobTypeHandler						java.lang.String								NCLOB
BlobInputStreamTypeHandler						java.io.InputStream	-
ByteArrayTypeHandler									byte[]	数据库兼容的字节流类型
BlobTypeHandler								byte[]	BLOB, LONGVARBINARY
DateTypeHandler									java.util.Date	TIMESTAMP
DateOnlyTypeHandler									java.util.Date	DATE
TimeOnlyTypeHandler									java.util.Date	TIME
SqlTimestampTypeHandler								java.sql.Timestamp	TIMESTAMP
SqlDateTypeHandler												java.sql.Date	DATE
SqlTimeTypeHandler												java.sql.Time	TIME
ObjectTypeHandler																Any	OTHER 或未指定类型
EnumTypeHandler											Enumeration Type	VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandler						Enumeration Type	任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。

**

mybatis核心配置之environments环境

**

1可以配置多个环境 映射多个数据库  在environments里面配置多个environment 更改id 就好 
2transactionManager 有两个参数 jdbc(有事务)     MANAGED这个配置没做什么
		如果用的spring+myabits这个2transactionManager就没意义 因为会被spring的配置覆盖掉
	**我们也可以自定义事务管理器:
	(1)实现TransactionFactory
	  (2)实现Transaction 并且在 TransactionFactory方法中返回
	  然后把自定义的事务管理器的全类名放在transactionManager的type属性当中 就可以实现自己的事务管理器 我们可以在自己的类中写自己的方法~

**

mybatis核心配置之databaseIdProvider

**

让mybatis支持多种数据库
	<databaseIdProvider type="DB_VENDOR">
		<property name="SQL Server" value="sqlserver" />
		<property name="MySQL" value="mysql" />
		<property name="DB2" value="db2" />
		<property name="Oracle" value="oracle" />
	</databaseIdProvider>
在Mapper.xml中的sql语句标签可以配置databaseId属性 在我们使用不同数据库的时候 就会动态的找寻相对应的语句执行~

**

mybatis核心配置之映射器mappers

**

作用:引入sql语句对应的mapper配置文件
1利用类路径下的资源路径:<mapper resource="">这里写的是xml文件
2使用mapper接口的方式		<mapper class="接口全类名">  这里写的是全类名 可以通过指定类扫描mapper配置文件
3使用包名				  <package name="包名">	搜索所有包名下的配置文件

**

使用注解的方式映射sql语句

**
此时就不需要使用Mapper.xml来映射sql语句了

在接口的方法上写:
(1)@Select (value=“”)  @Update (value=“”)  @Delete (value=“”)   @Insert (value=“”)
		insert语句可以再写一个注解: @SelectKey(before=false,statement=“select last_insert_id()”,keyProperty=“id”,resultType=Integer。class)来将生成的id返回
(2)mappers 改成<mapper class="接口全类名">  这里写的是全类名 可以通过指定类扫描mapper配置文件

**

Mybatis sql映射文件参数传递

**

(1)一个普通数据类型  写变量名 #{变量名}
(2)多个普通数据类型  用#{param1} #{param2} #{param3}
							或者用注解的方式@param("")然后就可以用#{前面写的名字}来使用了
(3)传递的是一个对象(包括map对象)用#{属性名或者key名}
(4)传递多个pojo对象	使用#{param1.属性名}    #{param2.属性名}

**

{} 和 ${}的区别

**

#{}是占位符?	
xml中配置的是#{}会解析成 ?

${}是原样输出参数的值 并且需要做字符串拼接的操作
xml中的配置: '${xxx}'   

若果需要模糊查询 我们一般使用:concat('%',#{参数},'%')

**

自定义结果集

**

用来解决查询的pojo对象中包含pojo对象或者pojo对象集合的情况~  此时需要使用resultMap自定义返回的结果
resultMap上的属性
		type :返回的对象全类名
		id的值是resultMap的值
里面的标签:
		id 专门用来映射id主键列
		result 映射非主键列		可以使用集联映射来给pojo中的pojo赋值   column是查询出来的字段名 property是bean对象的属性
		association标签专门映射pojo中的一个bean对象: property是pojo对象中bean对象的属性名 javaType是pojo对象中bean对象的全类名	
			association中再使用id 和result赋值
		collection 专门用来映射集合  property表示映射的集合的属性名 ofType表示集合中的类型		

**

一对一分布查询

**
有时候我们查询结果后只运用了某个子段 所以全部查询出来就是很浪费的 这时候可以用分布查询

代码显示地使用了哪个子段的表才查哪个
我们需要把表分成虚拟的主表和从表进行查询 所以需要写两个mapper接口和映射xml 分别查询两个表的子段   在一对一的情况下 就是第一个pojo对象为主表 pojo里面的pojo对象为从表 分两步进行查询  不使用到pojo里的pojo对象就不进行查询

使用:
association   :
			select属性写上第二个mapper.xml的名称空间.标签id   即第二批次执行的查询语句
			column传入在第一个主表中查询出来的pojo 中的pojo的id值   
		此时就可以分成两个语句进行查询
		
还需要使用延迟加载 :

		   延迟加载在一定程序上可以减少很多没有必要的查询。给数据库服务器提升性能上的优化。
			要启用延迟加载,需要在mybatis-config.xml配置文件中,添加如下两个全局的settings配置。
			
			<!-- 打开延迟加载的开关 -->  
	       <setting name="lazyLoadingEnabled" value="true" />  
	       <!-- 将积极加载改为消极加载  按需加载 -->  
			<setting name="aggressiveLazyLoading" value="false"/>  
			懒加载功能,mybatis3.2.8版本,需要同时引入两个jar包
			cglib-2.2.2  asm-3.3.1
全部配置好后 执行第一个查询语句的时候就会查主表  在使用到第二个表的字段的时候才会再次进行查询

**

一对多分步查询

**

查询的代码方法跟上面一对一的一样 只不过查询的是集合;

**

一对多双向关联

**

顾名思义 就是一个A对象里面有一个集合对象 集合对象里面的每一个B对象又有开头的A对象
所以在第一个懒加载里面调用了第二个对象的懒加载 第二个对象的懒加载又调用了第一个的懒加载
这里会产生一个问题:就是注意不要调用A.toString()否则会出错stackoverflowerror
需要用什么的时候 就把这个属性拿出来 手动调用

**

动态sql

**

if  可以动态的根据你的值来决定,是否需要动态的添加查询条件
where 	可以帮我们在多个动态语句中,有效的去掉前面的多余的and  或 or 之类的多余关键字 还可以动态的判断中间是否包含查询条件。如果没有连where关键字也不会出现。
trim 可以动态在包含的语句前面和后面添加内容。也可以去掉前面或者后面给定的内容
				prefix 前面添加内容
				suffix 后面添加内容
				suffixOverrides 去掉的后面内容
				prefixOverrides 去掉的前面内容
choose when otherwise 可以执行多路选择判断,但是只会有一个分支会被执行。 类似switch case 语句
set   删除条件后面的逗号
foreach标签	用来遍历集合
					collection遍历的数据源
					open属性设置遍历的开始内容
					close属性设置遍历的结束内容
					item属性是当前遍历到的数据
					separator属性设置遍历的每个元素之间的间隔符

**

mybatis 缓存

**

缓存:缓存指的是将经常访问的数据保存到一个高速的数据存储区,其实就是内存~    缓存的目的当然就是为了快速访问
一级缓存(默认开启的):	指的是将数据保存在SqlSession中(同一个SqlSession)
							只有在SqlSession中没有的才发送sql语句到数据库进行查询 查询回来后直接放在一级缓存中
		---------------一级缓存的管理:
						缓存失效的四种情况:
						1.不在同一个SqlSession对象中
						2.执行语句的参数不同。缓存中也不存在数据。
						3.执行增,删,改,语句,会清空掉缓存(两次查询中间做了增删改查的操作~)
						4.手动清空缓存数据 (调用session对象的clearCache())
二级缓存(默认不开启的!~):	指的是将数据保存以mapper中(同一个sqlSessionFactory)
				因为是从sqlSessionFactory中创建出来的SqlSession对象 所以下段话很容易理解:
				1先从二级缓存中查询(sqlSessionFactory对象)
				2再从一级缓存中查询
				3都没有才到数据库中查询 并且放到一级缓存中
				4SqlSession关闭的时候把数据保存到二级缓存中~
				当SqlSession执行相关的缓存失效情况时候(例如执行添加删除等操作) 就会清空一级和二级缓存~
				这就意味着多个sqlSessionFactory下的SqlSession对象只要有一个查询回来数据就会保存在sqlSessionFactory中 其后的sqlSession对象查询相同数据会直接去二级缓存查询 不会像上面一样重新查询数据库了(但是不同的一级缓存sqlSession需要在其他sqlSession查询前关闭)
		开启二级缓存:
			myBatis的二级缓存默认是不开启的。我们需要在mybatis的核心配置文件中配置setting选项 和 在Mapper的配置文件中加入cache标签。并且需要被二级缓存的对象必须要实现java的序列化接口。
		二级缓存的使用步骤:
			1、在mybatis-config.xml中配置选项
				<settings>
					<setting name="cacheEnabled" value="true"/>
				</settings>
			2、在Mapper.xml中去添加一个cache标签
			3、对象必须要实现java的序列化接口 (因为涉及到了序列化和反序列化)
		底层:是CachingExecutor内部的query方法会创建一个CacheKey对象(查询语句加参数 所以参数不同会导致缓存失效 因为key不同) 
		    TransactionCacheManager二级缓存事务管理器以上述CacheKey为参数查询 查询不到一级执行器SimpleExecutor就会调用一级缓存localCache查询 也没有就调用queryFromDatabse查询数据库~

**

mybatis的逆向工程:

**
可以快速根据表生成对应的 bean对象 对应的mapper接口 mapper接口对应的映射文件
1写一个xml配置文件

在这里插入图片描述
(图片来自网络 侵删)
2写一个java类 运行:

List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		File configFile = new File("你的配置文件.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
				callback, warnings);
		myBatisGenerator.generate(null);

去除全部注释:
<commentGenerator>
        <property name="suppressAllComments" value="true" />
</commentGenerator>
发布了63 篇原创文章 · 获赞 44 · 访问量 6265

猜你喜欢

转载自blog.csdn.net/weixin_40695328/article/details/89684106