欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis框架

程序员文章站 2022-05-21 09:28:47
...

 第一天大纲:

  1. 高级软件介绍(部分)
  2. MySql数据库建库建表语句强调
  3. 命名规范强调
  4. 基于MVC开发模式完成单表查询和新增
  5. Eclipse中项目默认发布路径
  6. 框架是什么
  7. MyBatis简介
  8. MyBatis搭建流程
  9. 数据库连接池和JNDI复习
  10. 搭建流程详解(全局配置文件,resultType原理及AutoMapping等)
  11. MyBatis三种查询方式

[知识点详解]

一.高级软件介绍

1. JDK 7

2. Eclipse mars2

3. MySql

4. Navicat

二.数据库SQL命令

1创建数据库并指定编码

Create database 数据库名 default character set utf8

2.创建表

Create table 表名(

列名   类型  约束 auto_increment comment ‘备注’,

);

三.Eclipse使用

1. 创建项目

1.1 选择target runtime,否则出现新建jsp报错

1.2 如果忘记选择,右键项目--> build path --> configure path -->选项卡library --> 第四个add library --> server runtime

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis  

2. Eclipse默认会自己下载所需tomcat最简单结构.

.命名规范

1.项目名:没有要求,不起中文

2.包:公司域名倒写 com.bjsxt

3.数据访问层:dao, persist, mapper

4.实体:entity, model, bean,javabean, pojo

5.业务逻辑: service ,biz

6.控制器: controller, servlet,action,web

7.过滤器: filter

8.异常: exception

9.监听器:listener

10.注释:

    10.1 类上和方法上使用文档注释 /**   */

    10.2 在方法里面使用/*  */  或 //

11.类: 大驼峰

12.方法,属性:小驼峰

四.MVC开发模式

1. M: Model 模型,实体类和业务和dao

2. V: view 视图. JSP

3. C:Controller 控制器,servlet

3.1 作用:视图和逻辑分离

4. MVC适用场景:大型项目开发.

5. 图示例

     5.1 先设计数据库

    5.2 先写实体类

    5.3 持久层

    5.4 业务逻辑

    5.5 控制器

    5.6 视图

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

五.框架是什么

1. 框架:软件的半成品.未解决问题制定的一套约束,在提供功能基础上进行扩充.

2. 框架中一些不能被封装的代码(变量),需要使用框架者新建一个xml文件,在文件中添加变量内容.

        2.1 需要建立特定位置和特定名称的配置文件.

        2.2 需要使用xml解析技术和反射技术.

3. 常用概念

    3.1 类库:提供的类没有封装一定逻辑.

                举例:类库就是名言警句,写作文时引入名言警句

    3.2 框架:区别与类库,里面有一些约束.

                举例:框架是填空题

六.MyBatis简介

1. Mybatis 开源免费框架.原名叫iBatis,2010在google code,2013年迁移到github

2. 作用: 数据访问层框架.

          2.1 底层是对JDBC的封装.

3. mybatis优点之一:

        3.1 使用mybatis时不需要编写实现类,只需要写需要执行的sql命令

 

七. 环境搭建

1. 导入jar

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis  

2. 在src下新建全局配置文件(编写JDBC四个变量)

    2.1 没有名称和地址要求

    2.2 在全局配置文件中引入DTD或schema

            2.2.1 如果导入dtd后没有提示

                Window--> preference --> XML --> XMl catalog --> add按钮

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis  

2.3 全局配置文件内容

<?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>
	<!-- default引用environment的id,当前所使用的环境 -->
	<environments default="default">
		<!-- 声明可以使用的环境 -->
		<environment id="default">
			<!-- 使用原生JDBC事务 -->
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
				<property name="username" value="root"/>
				<property name="password" value="smallming"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/bjsxt/mapper/FlowerMapper.xml"/>
	</mappers>
</configuration>

 

3. 新建以mapper结尾的包,在包下新建:实体类名+Mapper.xml

    3.1 文件作用:编写需要执行的SQL命令

    3.2 把xml文件理解成实现类.

    3.3 xml文件内容

<?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">
<!-- namesapce:理解成实现类的全路径(包名+类名) -->
<mapper namespace="a.b" >
	<!-- id:方法名 
		parameterType:定义参数类型
		resultType:返回值类型.
		
		如果方法返回值是list,在resultType中写List的泛型,因为mybatis
		对jdbc封装,一行一行读取数据
	-->
	<select id="selAll" resultType="com.bjsxt.pojo.Flower">
		select * from flower
	</select>
</mapper>

4. 测试结果(只有在单独使用mybatis时使用,最后ssm整合时下面代码不需要编写.)

        InputStream is = Resources.getResourceAsStream("myabtis.xml");
		//使用工厂设计模式
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
		//生产SqlSession
		SqlSession session=factory.openSession();
		
		List<Flower> list = session.selectList("a.b.selAll");
		for (Flower flower : list) {
			System.out.println(flower.toString());
		}
		
		session.close();

八. 环境搭建详解

1.全局配置文件中内容

   1.1 <transactionManager/> type属性可取值

            1. JDBC,事务管理使用JDBC原生事务管理方式

            2. MANAGED 把事务管理转交给其他容器.原生JDBC事务setAutoMapping(false);

   1.2 <dataSouce/>type属性

  1. POOLED 使用数据库连接池
  2. UNPOOLED 不实用数据库连接池,和直接使用JDBC一样
  3.  JNDI :java命名目录接口技术.

九.数据库连接池

1.在内存中开辟一块空间,存放多个数据库连接对象.

2.JDBC Tomcat Pool,直接由tomcat产生数据库连接池.

3.图示

        3.1 active状态:当前连接对象被应用程序使用中

        3.2 Idle空闲状态:等待应用程序使用

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

4.使用数据库连接池的目的

      4.1 在高频率访问数据库时,使用数据库连接池可以降低服务器系统压力,提升程序运行效率.

            4.1.1 小型项目不适用数据库连接池.

5.实现JDBC tomcat Pool的步骤.

    5.1 在web项目的META-INF中存放context.xml,在context.xml编写数据库连接池相关属性

<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<Resource
		driverClassName="com.mysql.jdbc.Driver"
		url="jdbc:mysql://localhost:3306/ssm"
		username="root"
		password="smallming"
		maxActive="50"
		maxIdle="20"
		name="test"
		auth="Container"
		maxWait="10000"
		type="javax.sql.DataSource"
	/>
</Context>

     5.2 把项目发布到tomcat中,数据库连接池产生了

6.可以在java中使用jndi获取数据库连接池中对象

    6.1 Context:上下文接口.context.xml文件对象类型

    6.2 代码:

Context cxt = new InitialContext();
DataSource ds = (DataSource) cxt.lookup("java:comp/env/test");
Connection conn = ds.getConnection();

6.3 当关闭连接对象时,把连接对象归还给数据库连接池,把状态改变成Idle

十. 三种查询方式

1.selectList() 返回值为List<resultType属性控制>

    1.1 适用于查询结果都需要遍历的需求

List<Flower> list = session.selectList("a.b.selAll");

for (Flower flower : list) {

System.out.println(flower.toString());

}


  2.selectOne() 返回值Object,

适用于返回结果只是变量或一行数据时


int count = session.selectOne("a.b.selById");

System.out.println(count);

 

3.selectMap() 返回值Map

        3.1 适用于需要在查询结果中通过某列的值取到这行数据的需求.

        3.2 Map<key,resultType控制>


Map<Object, Object> map = session.selectMap("a.b.c", "name123");

System.out.println(map);

 

第二天大纲:

  1. <settings>标签常用属性介绍
  2. MyBatis对Log4J的支持
  3. Log4J复习
  4. <typeAliases>两种别名配置及内置别名
  5. MyBatis实现新增及MyBatis事务
  6. MyBatis实现删除
  7. MyBatis实现修改
  8. MyBatis的分页处理

,<settings>标签常用属性介绍

<setting>标签起到一个全局开关的作用。

1,<settings> 配置介绍

1.<!-- settings是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 -->  
2.    <settings>  
3.        <!-- 该配置影响的所有映射器中配置的缓存的全局开关。默认值true -->  
4.      <setting name="cacheEnabled" value="true"/>  
5.      <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认值false  -->  
6.      <setting name="lazyLoadingEnabled" value="true"/>  
7.        <!-- 是否允许单一语句返回多结果集(需要兼容驱动)。 默认值true -->  
8.      <setting name="multipleResultSetsEnabled" value="true"/>  
9.      <!-- 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。默认值true -->  
10.      <setting name="useColumnLabel" value="true"/>  
11.      <!-- 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 默认值false  -->  
12.      <setting name="useGeneratedKeys" value="false"/>  
13.     <!--  指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 -->   
     <!-- 默认值PARTIAL -->  
14. <setting name="autoMappingBehavior" value="PARTIAL"/>  
15.        
16.      <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>  
17.     <!--  配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。默认SIMPLE  -->  
18.      <setting name="defaultExecutorType" value="SIMPLE"/>  
19.      <!-- 设置超时时间,它决定驱动等待数据库响应的秒数。 -->  
20.      <setting name="defaultStatementTimeout" value="25"/>  
21.        
22.      <setting name="defaultFetchSize" value="100"/>  
23.      <!-- 允许在嵌套语句中使用分页(RowBounds)默认值False -->  
24.      <setting name="safeRowBoundsEnabled" value="false"/>  
25.      <!-- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。  默认false -->  
26.      <setting name="mapUnderscoreToCamelCase" value="false"/>  
27.      <!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。  
28.             默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。  
29.            若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。  -->  
30.      <setting name="localCacheScope" value="SESSION"/>  
31.      <!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。  -->  
32.      <setting name="jdbcTypeForNull" value="OTHER"/>  
33.    <!--   指定哪个对象的方法触发一次延迟加载。  -->  
34.      <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>  
35.    </settings>  

 

二,MyBatis对Log4J的支持

1, 复习一下log4j

      1.1 log4j日志处理,apache的开源组件

    1.2 主要解决了。项目中输出的记录的问题。比如说需要打印某个变量的值。我们更多的采用System.out.println();

使用System.out.println()输出的缺点就是未来信息会输出到控制台。而且该信息未必是客户所要的。但是由于是IO操作会影响系统的性能。所系项目在上线前,我们需要将所有的打印语句取掉。

如果项目在运行时出现了某些错误。我们不能将错误信息保存住,导致拍错时没有无依据。所以我们需要将错误信息保存到磁盘。

2.log4j的使用步骤

    2.1 需要在项目添加log4j.jar。Commons-logging.jar

    2.2 添加 log4j.properties(注意,配置文件的名称必须要叫该名,位置必须要放到src根下。)

log4j.rootLogger=error,R,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=<%d> %5p (%F:%L) [%t] (%c) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=d:/SysLog111.log
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=7
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=<%d> %p (%F:%L) [%t] %c - %m%n

属性介绍:

1、日志处理器的全局控制 日志输出级别以及输出方式

log4j.rootLogger=error,R,stdout

2、ConversionPattern表达式

%d   输出时间 yyyy-mm-dd HH-mm-ss SSS 如果需要对日志的时间做格式化处理可以使用{日期格式}
%p   打印日志的级别 : fatal(致命)> error(错误) > warn(警告) > info(信息) > debug(调试)
%F   产生输出信息的类的名称
%L   产生输出信息的代码的行数
%t   产生输出信息线程名称
%C   产生输出信息的类的全名
%m   输出信息
%n   回车换行

3,使用<setting>标签配置日志记录

Mybatis内置了好几种日志记录技术 如:log4j、jdk14loggingImpl、slf4j。。。。

那么mybatis到底使用的是哪个呢?mybaits采用的查找的方式。

如果需要让mybatis使用我们自己的日志记录,那么需要mybaits的总体配置文件中通过<settings>标签来指定

<settings>
		<setting name="logImpl" value="LOG4J"/>
</settings>

三,<typeAliases>两种别名配置及内置别名

Mybatis中提供了一些内置别名如:

    string –>String.class

    int      -->Integer.class

    map --->Map.class

    ……

具体请参看

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

1.包别名

<typeAliases>
		<package name="com.bjsxt.pojo"/>
</typeAliases>
<package name="com.bjsxt.pojo"/>
表示可以配置一个统一的包名。如果我们使用的对象是位于该包下的。那么我们就可以不用给定包名了。
直接给定类名就可以了。但是类名的内容上必须要一样,而且忽略大小写。

2.类别名

<typeAliases>
		<typeAlias type="com.bjsxt.pojo.Users" alias="suibian"/>
</typeAliases>

为具体的某个类起一个别名,当在mybatis中使用该类型时,可以直接给定别名。

 

四,MyBatis实现新增及MyBatis事务

Mybatis在执行DML操作时事物默认的是关闭的。等同于conn.setAutoCommit(false);

Mybatis的openSession()无参的方式默认的事物不自动提交

OpenSession(true)表示开启自动提交。

平时使用时应该更多的使用无参的。因为事物到底进行什么样的控制,应该是由我们来决定的。

五,MyBatis实现添加

   1,需要在mybatis的映射配置文件中添加<insert>

       Id=f自定义标记

       parameterType=”参数类型

   2, 调用SqlSession.insert(nameapce+id,参数);

   3, 事物提交

六,MyBatis实现删除

  1,映射配置文件:<delete> id  parameterType

  2, SqlSession.delete(namespace+id,参数);

  3,事物提交

七,MyBatis实现修改

  1,<update> id  parameterType

  2, SqlSession.update(namespace+id,参数);

  3,事物提交

八,MyBatis的分页处理

1, 回顾oracle如何分页

Select t.* from (select rownum rn,u.* from users u where u.username = ?? and u.userpwd= ???) t where t.rn between 1 and 2

 

Oracle 计算from to的公式

由于oracle使用的rownum伪劣来实现分页,rownum是从1开始的。所以计算公式如下:

    Pageindex //当前页

    Pagenumber//每页显示的条数

From:(pageindex -1)* pagenumber +1;

To :pageindex * pagenumber;

 

Mysql 计算from to的公式

 由于mysql分页是根据结果的条数进行运算,从第一几条开始,取多少条。

 Sql:select * from users limit from ,to

    Pageindex //当前页

    Pagenumber//每页显示的条数

From:pageindex-1*pagenumber;

To :pagenumber;

 

第三天大纲:

  1. 动态代理
  2. MyBatis接口绑定方案
  3. 动态SQL
  4. 缓存

一, MyBatis接口绑定方案

 使用Mybatis接口绑定方式:

1. 映射配置文件必须要和接口的名称相同。

2. 映射配置文件的namespace必要放接口的全名。

3. 在总体配置文件中关联映射配置文件时不能在使用

    <mapper>需要换成<package> 存放接口与映射配置文件的包名。

4. 通过SqlSession对象调用他的getMapper方法来后去接口的代理对象。

UserMapper um = session.getMapper(UserMapper.class);

5. 如果使用该方式来操作数据库,那么对于映射配置文件中的参数传递,就不需要通过parameterType来指定了。

二,动态Sql

复习高级查询

高级查询的特点是条件多元化。

在xml文件中如果需要使用一些特殊符号可以使用如下方式

<![CDATA[
		select * from users  where userid <  #{suibian}
]]>

1,<if>

1.1 使用该标签是 条件之间的关系不能使用 && 或者是 || 。需要使用 and 或者是 or

<select id="selectUesrByProperty" resultType="users">
		    select * from users where 1=1
		<if test="username != null and username.length() > 0">
			and username = #{username}
		</if>	
		
		<if test="userid != null and userid > 0">
			and userid =#{userid}
		</if>
</select>

2.<where>

2.1 会自动的在sql语句中添加where关键字

2.2 如果没有任何条件满足,那么<where>标签将不会在sql中添加where关键字。可以解决 where 1=1

2.3 只要有添加满足 <where>标签就会去掉第一个and

<select id="selectUesrByProperty2" resultType="users">
		select * from users 
		<where>
			<if test="username != null and username.length() > 0">
				and username = #{username}
			</if>	
			
			<if test="userid != null and userid > 0">
				and userid =#{userid}
			</if>
		</where>
</select>

3.<choose>

3.1是多选一

<select id="selectUesrByProperty3" resultType="users">
		select * from users
		<where>
			<choose>
					<when test="username != null and username.length() > 0">
						and username = #{username}
					</when>
					<otherwise>
						and userid = #{userid}
					</otherwise>
			</choose>
		</where>
</select>

4.<set>

4.1 会自动的在update语句中添加set关键字

4.2 会自动去掉最后一个逗号。

4.3 如果更新条件没有满足的,那么set关键也不会添加

<update id="updateUsers">
		update users  
		<set>
			<if test="username != null and username.length() > 0">
				 username = #{username},
			</if>	
			<if test="userpwd != null and userpwd.length() > 0">
				userpwd = #{userpwd},
			</if>
			<if test="userage != null and userage > 0 ">
				userage = #{userage},
			</if>
		</set>
		where userid = #{userid}
</update>

5,<trim>

prefix=""在内容之前添加什么 

prefixOverrides="" 去掉内容前面的什么

suffix="" 在内容的后面添加什么

suffixOverrides=""去掉内容后面的什么

5.1顺序:从前到后的,先添加,后去掉。

<update id="updateUsers2">
		update users
		<trim  prefix="set" prefixOverrides="suibia," suffix="where" suffixOverrides=",">
		suibia,
		    <if test="username != null and username.length() > 0">
				 username = #{username},
			</if>	
			<if test="userpwd != null and userpwd.length() > 0">
				userpwd = #{userpwd},
			</if>
			<if test="userage != null and userage > 0 ">
				userage = #{userage},
			</if>
		</trim>
		 userid = #{userid}
</update>

6.<foreach>

collection="list" 迭代的集合

item="suibian" 存放迭代结果的变量

open="(" 在结果之前添加什么

close=")" 在结果之后添加什么

separator=","在迭代过程中添加分隔符。迭代的最后一次不添加。

<select id="selectUserByNameIn" resultType="users">
		select * from users 
		<where>
			username in 
			<foreach collection="list" item="suibian" open="(" close=")" separator=",">
				#{suibian} 
			</foreach>
		</where>
</select>

7. 使用mybatis实现批量添加

Sql语句的批量添加:insert into users(username,userage) values(‘a’,20),(‘bb’,39),(‘c’,22);
<insert id="insertUserBath">
		insert into users(username,userpwd,userage) values
		<foreach collection="list" item="var" separator=",">
			(#{var.username},#{var.userpwd},#{var.userage})
		</foreach>
</insert>

8,<sql>

可以在该标签中定义个sql片段。达到对该片段的重复利用。

9.<include>

可以将某个sql片段包含进来。

三,Mybatis缓存

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

缓存的含义:所谓缓存就是减少操作数据库的次数,提高框架自身的性能。

Mybatis缓存类型分为两种。

1, 一级缓存(SqlSession) 必用的。

Mybatis的一级换存,是使用SqlSession中的map来实现。

Map的key会根据当前的mapprStatement的id以及sql最为他生成key依据。所以我们在实行查询时,只有执行同一个id的条件相同的sql才能从缓存中获取数据。

2.清空缓存

2.1 session.commit();

2. 2session.clearCache();

2.3 session.close();

2, 二级缓存(SqlSessionFactory)

注意:缓存使用原则:只缓存查询频率比较高的数据。千万不要存放经常会改变的数据。

 

Mybatis中的二级缓存。是一个可选的。不是必须的。

Mybatis的二级缓存与一级缓存区别:

2.1二级缓存是将所有的数据缓存到SqlSessionFactory 而一级缓存是存放到sqlsession中的

2.2 二级缓存的缓存时间要长于一级换存的缓存时间。

2.3 二级缓存缓存的数据可以面向不同Sqlsession 对象,而一级缓存只能是通过SqlSession 且mapperStatement 以及sql语句和条件完全相同才能从缓存中读取数据。

3.mybatis的二级缓存的使用方式。

3.1 在总体配置文件中通过<settings>开始二级缓存。默认的已经开启

 <setting name="cacheEnabled" value="true"/>  

3.2被缓存的对象必须要实现可序列化接口。或者在映射配置文件中的<cache>标签中添加readonly=true

<cache readOnly="true"/>

3.3 在需要缓存映射配置文件中添加<cache/>

3.3 二级缓存在什么情况下进行缓存呢?必须要commit 才会将数据存放到二级缓存中。

3.4 <cache标签介绍>

<!--

 eviction是缓存的淘汰算法,可选值有"LRU(默认的) 最近最少 使用算法;

 "、"FIFO 先入先出算法"、"SOFT"、"WEAK",缺省值是LRU

flashInterval指缓存过期时间,单位为毫秒,60000即为60秒,缺省值为空,即只要容量足够,永不过期

size指缓存多少个对象,默认值为1024

readOnly是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。

 <cache

eviction="FIFO"  回收策略为先进先出

flushInterval="60000" 自动刷新时间60s

size="512" 最多缓存512个引用对象

readOnly="true"/> 只读 -->

 

3.5 可以自己选择缓存哪些SQL返回的结果

<select id="selectUserById" resultType="users" useCache ="false">

useCache默认值为true

 

第四天大纲:

  1. Auto Mapping实现(别名方式)
  2. <resultMap>实现单表配置
  3. 单个对象关联查询(N+1,外连接)
  4. 集合对象关联查询
  5. Annotation
  6. 注解开发
  7. MyBatis运行原理

一.Auto Mapping实现(别名方式) 

Mybatis要求对象的属性名与列名相同。如果不相同。我们可以使用对投影的列起别名的方式来解决该问题

<select id="selectUserById" resultType="users">
	select userid,username as name,userpwd userpwd,userage from users where userid = #{userid}
</select>

二.resultMap标签

1,<resultMap>

该标签是为了显示在映射是,属性与结果集的列转换的问题。通过对resultmap的配置可以将对象的属性与结果的列做绑定。

2,resultMap属性介绍

     2.1Type:指定pojo。表示需要对哪个模型做映射。

     2.2Id:唯一标识。叫什么都行。只要在所有的映射配置文件中不冲突就可以。

3.resultMap中的子节点

    3.1<id>:结果集中的主键绑定。Property=”对象中属性的名称” column=”结果集中的列名”

    3.2<result>:非主键的绑定。Property=”对象中属性的名称” column=”结果集中的列名”

三.使用<resultMap>查询关联集合对象(N+1)

1.多表查询的两种方式:

1.1 使用n+1次查询,其实就是分解查询。

    优点:节省内存空间。

    缺点:性能低下。因为会与数据多次交互。

1.2 使用联合查询(内联,外联)

    优点:效率高。只与数据库交互一次。

    缺点:空间浪费。因为返回的结果集较大。

2.使用mybatis实现N+1次查询

    2.1N+1次查询需要配合延迟加载才能体现他的优点。

    2.2延迟加载实现”

    2.2.1在resultmap中配置关联对象

<resultMap type="com.bjsxt.pojo.Users" id="suibian">
		<id property="userid" column="userid"/>
		<result property="name" column="username"/>
		<result property="userpwd" column="userpwd"/>
		<result property="userage" column="userage"/>
		<collection property="orders" select="selectOrderByUserid" column="userid"></collection>
	</resultMap>
<select id="selectOrderByUserid" resultType="orders">
		select * from orders where user_id = #{suibian}
</select>

  2.2.2修改总体配置文件,开启延迟加载

Mybatis中默认情况下延迟加载时候关闭的。需要在<settings>标签中,开启延迟加载

<settings>
		<setting name="logImpl" value="LOG4J"/>
		<setting name="lazyLoadingEnabled" value="true"/>  
</settings>

四.使用<resultMap>实现加载集合数据(联合查询方式)

1. 在一条sql中把数据检索到。可以使用内联,外联,子查询。

2. 如果在mybatis中使用联合查询,需要注意的是。

我们需要在顶一个resultmap。由于返回的结果集既包含了user又包含了order。所以我们需要在resultmap中将对象的属性与返回的结果集的列做一一对应。否则mybatis无法识别对应关系。而N+1查询使用的分解式的查询方式,所以并不需要完全的配置映射关系。

3. 在<collection>标签中必须要配置ofType属性。

该属性的作用是告知mybatis在查询到的结果集当中哪一部分需要映射到什么对象中。否则mybatis仍然不知道如何处理结果集。而N+1次中则可以忽略该属性。因为,在N+1次查询中通过查询的<select>标签中的resultType已经知道用什么模型装配什么数据了。

<!-- 联合查询 -->
	<resultMap type="com.bjsxt.pojo.Users" id="suibian2">
		<id property="userid" column="userid"/>
		<result property="name" column="username"/>
		<result property="userpwd" column="userpwd"/>
		<result property="userage" column="userage"/>
		<collection property="orders" ofType="orders">
			<id property="orderid" column="orderid"/>
			<result property="orderprice" column="orderprice"/>
		</collection>
	</resultMap>
	<select id="selectUserById3" resultMap="suibian2">
		 select * from users left join orders on userid=user_id where userid =#{userid}
	</select>

五.Annotation(注解)讲解

1.什么是annotation

    Annotation是jdk1.5以后提供的一个新特性。目的是为配置文件瘦身。

    我们可以通过一些特定的annotation完成对项目的配置。

2.annotaion的语法

    @annotation的名称(value,value,value)

3. 定义一个annotation

3.1通过IDE可以直接创建一个annotation

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

3.2定义一个annotation

/*
 * @Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含
 * @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
 * @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
 */
/*
 *  @Target(ElementType.TYPE)   //接口、类、枚举、注解
 *	@Target(ElementType.FIELD) //字段、枚举的常量
 *	@Target(ElementType.METHOD) //方法
 *	@Target(ElementType.PARAMETER) //方法参数
 *	@Target(ElementType.CONSTRUCTOR)  //构造函数
 *	@Target(ElementType.LOCAL_VARIABLE)//局部变量
 *	@Target(ElementType.ANNOTATION_TYPE)//注解
 *	@Target(ElementType.PACKAGE) ///包   
 */
/*
 *  @Document:说明该注解将被包含在javadoc中
 *  @Inherited:说明子类可以继承父类中的该注解
 */
@Target( { ElementType.METHOD ,ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RunOrder {
	int value();
}

3.3解析annotation

3.3.1需要是jdk的反射。判断当前目标是否含有指定的annotation

mm.isAnnotationPresent(MethodOrder.class)//返回boolean

3.3.2如果含有指定的annotation,先将该annotation取出

MethodOrder om = mm.getAnnotation(MethodOrder.class);

3.3.3 从annotation中取值

int var = om.value();

3.3.4 完整案例

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodOrder {
	int value();
}
------------------------------------------------------------------------------------------------

public class MyMethod {
	@MethodOrder(2)
	public void method1() {
		System.out.println("Method1...........");
	}
	@MethodOrder(3)
	public void method2() {
		System.out.println("Method2...........");
	}
	@MethodOrder(1)
	public void method3() {
		System.out.println("Method3...........");
	}

	public void method4() {
		System.out.println("Method4...........");
	}
}
------------------------------------------------------------------------------------------------
public class Test4 {
	public static void main(String[] args)throws Exception {
		Class clazz = Class.forName("com.sxt.MyMethod");
		Object obj = clazz.newInstance();
		Method[] m = clazz.getDeclaredMethods();
		Map<Integer, Method> map = new TreeMap<Integer, Method>();
		for(Method mm :m){
			if(mm.isAnnotationPresent(MethodOrder.class)){
				MethodOrder om = mm.getAnnotation(MethodOrder.class);
				int var = om.value();
				map.put(var, mm);
			}
		}
		
		Set<Integer> keys = map.keySet();
		for(Integer key:keys){
			System.out.println(key);
			Method mm = map.get(key);
			mm.invoke(obj, null);
		}
	}
}

运行结果:

1
Method3...........
2
Method1...........
3
Method2...........

六.MyBatis注解

mybatis的注解并不能完全替代掉配置文件。总体配置文件仍然需要存在。映射配置文件可以没有。

但是,如果使用到了mybatis的动态sql处理,仍然需要依赖传统的映射配置文件。

@select :执行一个查询<select>

@insert :执行一个添加<insert>

@update :执行一个更新<update>

@Results :<resultmap>

@Result(id=true, property= “”,column=””): <id>

@Result(property= “”,column=””)<result>

@May: <collection  select=>

@one:

七.Mybatis运行原理

1. 运行过程中涉及到的类

 1.1 Resources MyBatis中IO流的工具类

            1.1.1加载配置文件

 1.2 SqlSessionFactoryBuilder() 构建器

           1.2.1 作用:创建SqlSessionFactory接口的实现类

1.3 XMLConfigBuilder  MyBatis全局配置文件内容构建器类

          1.3.1 作用:负责读取流内容并转换为JAVA代码.

1.4 Configuration 封装了全局配置文件所有配置信息.

          1.4.1 全局配置文件内容存放在Configuration中

1.5 DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类

1.6 Transaction 事务类

           1.6.1 每一个SqlSession会带有一个Transaction对象.

1.7 TransactionFactory 事务工厂

          1.7.1 负责生产Transaction

1.8 Executor  MyBatis执行器

          1.8.1 作用:负责执行SQL命令

          1.8.2 相当于JDBC中statement对象(或PreparedStatement或CallableStatement)

         1.8.3 默认的执行器SimpleExcutor

          1.8.4 批量操作BatchExcutor

          1.8.5 通过openSession(参数控制)

1.9 DefaultSqlSession 是SqlSession接口的实现类

1.10 ExceptionFactory MyBatis中异常工厂

2. 流程图

Mybatis框架
            
    
    博客分类: 常用框架 Mybatis 

3.文字解释

在MyBatis运行开始时需要先通过Resources加载全局配置文件.下面需要实例化SqlSessionFactoryBuilder构建器.帮助SqlSessionFactory接口实现类DefaultSqlSessionFactory.

在实例化DefaultSqlSessionFactory之前需要先创建XmlConfigBuilder解析全局配置文件流,并把解析结果存放在Configuration中.之后把Configuratin传递给DefaultSqlSessionFactory.到此SqlSessionFactory工厂创建成功.

由SqlSessionFactory工厂创建SqlSession.

每次创建SqlSession时,都需要由TransactionFactory创建Transaction对象,同时还需要创建SqlSession的执行器Excutor,最后实例化DefaultSqlSession,传递给SqlSession接口.

根据项目需求使用SqlSession接口中的API完成具体的事务操作.

如果事务执行失败,需要进行rollback回滚事务.

如果事务执行成功提交给数据库.关闭SqlSession

到此就是MyBatis的运行原理.(向面试官说的.)

 

相关标签: Mybatis