MyBatis Daquan summary

First discuss the basic concepts of ~:
(1) is MyBatis persistence framework to support outstanding custom SQL, stored procedures and advanced mappings.

(2) MyBatis avoids almost all the JDBC code and manual setting parameters and obtaining the result set.

(3) MyBatis can use simple XML or annotation for the original mapping and configuration, interface and Java POJO (Plain Old Java Objects, normal Java objects) in the database records.
(4) is a semi-automated persistence framework, is operating a single table, but also to write sql statement sql Hibernate is fully automatic optimization is not easy to do special
(5) jdbc program - when we use jdbc persistence, sql statement is hard-coded into java code . Such high degree of coupling. Code is easy to maintain. In the actual project development will often add or modify the sql sql, so we can only go to the java code modification.

Separated ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

使用:
需要导入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来调用~

**

After insertion returns to the main key

**

方法(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 manner CRUD interfaces

**
you can not write your own class that implements the interface can be used to write only
requirements: (1) Mapper.java class name and configuration file name as Mapper.xml
(2) placed in the same package
1 <mapper namespace = "interfaces whole class name "
2 tag id must be the same parameterType and resultType with the interface method name must be exactly the same as
3 SqlSession call getMapper method parameters into the interface class name .class

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

**

Using the core profile properties

**

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

Here Insert Picture Description
Here Insert Picture Description
**

Mybatis core configuration setting

**

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

**

Mybatis core configuration typeAliases alias

**

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

**

Class processor typeHandlers

**
Mybatis and PreparedStatement type processor will use the value of the acquired converted into a suitable manner type 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 core configuration of the environments environment

**

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

**

mybatis core configuration of 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 core configuration of the mapper mappers

**

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

**

Use annotations mapped sql statement

**
At this point there is no need to use Mapper.xml to map the sql statement

在接口的方法上写:
(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 mapping file parameter passing

**

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

**

{}, And the difference between the $ {}

**

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

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

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

**

Custom result set

**

用来解决查询的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表示集合中的类型		

**

One distributed queries

**
Sometimes we use only the query results after a certain sub-segments so check out all this time is a waste of queries can be distributed

代码显示地使用了哪个子段的表才查哪个
我们需要把表分成虚拟的主表和从表进行查询 所以需要写两个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
全部配置好后 执行第一个查询语句的时候就会查主表  在使用到第二个表的字段的时候才会再次进行查询

**

Many step-query

**

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

**

Many bidirectional associations

**

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

**

Dynamic sql

**

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

**

mybatis Cache

**

缓存:缓存指的是将经常访问的数据保存到一个高速的数据存储区,其实就是内存~    缓存的目的当然就是为了快速访问
一级缓存(默认开启的):	指的是将数据保存在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 reverse engineering:

**
mapper mapper interface corresponds to the interface can be quickly generated in accordance with the table corresponding bean mapping file corresponding to the object
1 to write a profile xml

Here Insert Picture Description
(Picture from the network intrusion deleted)
2 write a java class run:

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>
Published 63 original articles · won praise 44 · views 6265

Guess you like

Origin blog.csdn.net/weixin_40695328/article/details/89684106