Day01
二.数据库sql命令
1.创建数据库并指定编码
create database 数据库名 defalut character set utf8
2.创建表
create他变了 表名(
列名 类型 约束 auto_increment comment ‘备注’,
)
3.使用 创建 dynamic web project
三.命名规范
1.项目名:非中文
2.包:公司域名倒写
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 视图
大 纲:
SSM框架:
1.MyBatis :数据访问层框架
2.Spring 框架:对象维护功能
3.SpringMVC框架:对Servlet封装
框架:1.软件的半成品,为解决问题制定的一套约束,在提供功能基础上进行扩充。
2.框架中一些不能被封装的代码(变量),需要使用框架或者新建一个xml文件,在文件中添加变量内容。
2.1 需要简历特定位置和特定名称的配置文件
2.2 需要使用xml解析技术和反射技术
常用概念
3.1 类库:提供的类没有封装一定逻辑
3.2 框架:区别于类库,里面有一些约束
1.Mybatis开源免费框架,原名叫Ibatis , 2010在google code,2013 迁移到 github
2.作用:数据访问层框架
2.1 底层是对JDBC的封装
3.Mybatis有点之一:
3.1 mybatis不需要编写实现类,只需要编写需要执行的sql命令。
五.环境搭建:
1.导入jar包
Cglib 依赖的包 动态代理包 日志包 字节码解析包也是cglib依赖的包 日志包 日志包 日志包 mybatis核心包 驱动包 日志包 日志包 |
---|
2.在src下新建全局配置文件(编写jdbc四个变量)
2.1 没有名称和地址要求
2.2 在全局配置文件中引入DTD或者schema
2. 在 src 下新建全局配置文件(编写 JDBC 四个变量)
2.1没有名称和地址要求
2.2在全局配置文件中引入 DTD 或 schema
2.2.1 如果导入 dtd 后没有提示
Window—>preference—>XML—>XMlcatalog—>add按钮
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"> |
---|
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"> |
---|
4.测试结果(只有在单独使用mybatis时使用,最后ssm整合时下面的代码不需要编写)
package com.tjc.test; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.tjc.pojo.Flower; public class Test { public static void main(String[] args) throws IOException { InputStream is = Resources.getResourceAsStream(“myBatis.xml”); //使用工厂设计模式 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //生产SqlSession SqlSession session = factory.openSession(); List for(Flower flower:list) { System.out.println(flower); } session.close(); } } |
---|
六.环境搭建详解
1.全局配置文件中内容:
1.1
1.11 JDBC 事务管理使用JDBC原生事务管理方式
1.12 MANAGED 把事务管理转交给其他容器,原生JDBC事物setAutoMapping(false);
1.2
1.21 POOLED 使用数据库连接池
1.22 UNPOOLED 不使用数据库连接池,和直接使用JDBC一样
1.23 JNDI: java目录接口技术
七.数据库连接池
1.在内存中开辟一块空间,存放多个数据库连接对象
2.JDBC Tomcat Pool, 直接由Tomcat产生数据库连接池
3.图示
3.1 active 状态:当前连接对象被应用程序使用中
3.2 Idle 空闲状态: 等待应用程序使用
4. 使用数据库连接池的目的
4.1 在高频率访问数据库时,使用数据库连接池可以降低服务器系统压力,提升程序运行效率
4.11 小型项目不适用数据库连接池
5. 实现JDBC tomcat Pool 的步骤
5.1 在web项目的META-INF中存放context.xml,在context.xml中编写数据库连接池相关属性
<?xml version=“1.0” encoding=“UTF-8”?> url=“jdbc:mysql://localhost:3306/ssm” username=“root” password=“123456” maxActive=“50” maxIdle=“20” name=“test” auth=“Container” maxWait=“10000” type=“javax.sql.DataSource” /> |
---|
5.2 发项目发布到tomcat中,数据库连接池产生了
6.可以在java中使用jndi获取数据库连接池中对象
6.1 Context: 上下文接口: context.xml文件对象类型
6.2 代码:
package com.bjsxt.servlet; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; @WebServlet(“/pool”) public class DemoServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { Context cxt = new InitialContext(); DataSource ds = (DataSource) cxt.lookup(“java:comp/env/test”); Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(“select * from flower”); ResultSet rs = ps.executeQuery(); res.setContentType(“text/html;charset=utf-8”); PrintWriter out = res.getWriter(); while(rs.next()){ out.print(rs.getInt(1)+” ”+rs.getString(2)+” “); } out.flush(); out.close(); rs.close(); } catch (NamingException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } |
---|
6.3当关闭连接对象时,把链接对象归还给数据库连接池,把状态改变成Idle
八.三种查询方式
1. select list() 返回值为List
1.1 适用于查询结果都需要遍历的需求
List for(Flower flower:list) { System.out.println(flower); } |
---|
2.2 selectOne() 返回值Object,
2.1 适用于返回结果只是变量或一行数据时。
int count = session.selectOne(“com.tjc.FlowerMapper.selById”); System.out.println(count); |
---|
2.3 selectMap() 返回值Map
3.1 适用于需求需要在查询结果中通过某列的值取到行数据的需求
3.2 Map
Map |
---|
Day02
一. 注解
1.注解存在的意义:简化 xml 文件的开发.
2.注解在 servlet 3.0 规范之后大力推广的.
3.注解前面的@XXX,表示引用一个@interface
3.1 @interface 表示注解声明
4.注解可以有属性,因为注解其实就是一个接口(类)
4.1每次使用注解都需要导包
5.注解语法: @XXXX(属性名= 值)
6.值的分类
6.1如果值是基本数据类型或字符串: 属性名=值
6.2如果值是数组类型:属性名={值,值}
6.2.1如果只有一个值可以省略大括号
6.3如果值是类类型,属性名=@名称
7.如果注解只需要给一个属性赋值,且这个属性是默认属性,可以省略
属性名
二. 路径
- 编写路径为了告诉编译器如何找到其他资源.
2. 路径分类
2.1相对路径: 从当前资源出发找到其他资源的过程
2.2绝对路径: 从根目录(服务器根目录或项目根目录)出发找到其
他资源的过程
2.2.1标志: 只要以/开头的都是绝对路径
3. 绝对路径:
3.1如果是请求转发 /表示项目根目录(WebContent)
3.2其他重定向, ,,location.href 等/都表示
服务器根目录(tomcat/webapps 文件夹)
4. 如果客户端请求的控制器,控制器转发到JSP后,jsp中如果使用相对
路径,需要按照控制器的路径去找其他资源.
4.1保险办法:使用绝对路径,可以防止上面的问题.
三Log4j
- 由apache退出的开源免费日志处理类库。
2. 为什么需要日志:
2.1 在项目中编写System.out.println();输出到控制台,当项目发布到tomcat后,没有控制台(在命令行界面能看到),不容易观察一些输出结果
2.2 log4j作用,不仅能把内容输出到控制台,还能把内容输出到文件中,便于观察结果。
3.使用步骤
3.1 导入log4j-xxx-jar
3.2 在src下新建log4j.properties(路径和名称都不允许改变)
3.2.1 ConversionPattern: 写表达式
3.2.2 log4j.appender.LOGFILE.File=D:/my.log 文件位置及名称,日志文件为.log
log4j.rootCategory=DEBUG, CONSOLE , LOGFILE log4j.logger.a.b=DEBUG log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%C %d{YYYY-MM-dd hh:mm:ss} %L %m %n log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=D:/my.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%C %m %L %n |
---|
4. log4j输出级别
4.1 fatal(致命错误) > error(错误) > warm(警告) > info(普通信息) > debug(调试信息)
4.21 在log4j.properties 的第一行控制输出级别,图示只能输出比info级别高的
4.22. log4j输出目的地
在log4j第一行控制输出目的地,console控制台,logfile文件
6. pattern 中常用的及格表达式
6.1 %C: 包名+类名
6.2 %d{YYYY-MM-dd HH:mm:ss} :时间
6.3 %L 行号
6.4 %m 信息
6.5 %n 换行
四.标签
- 在mybatis全局配置文件中通过
标签控制mybatis全局开关
2.在mybatis.xml中开启log4j
2.1必须保证由log4j的jar
2.2 在src下必须有log4j.properties
3. log4j中可以输出指定内容的日志(控制某个局部内容的日志级别)
3.1 命名级别(包级别):
例如:namespace=”com.tjc.mapper.PeopleMapper”其中包级别为com.tjc.mapper,需要在log4j.propeties中
3.1.1 先在整体级别调成Error,不输出无用信息
3.1.2 在设置某个指定位置级别为DEBUG
3.2 类级别
3.2.1 namespace属性值
3.3 方法级别
3.3.1 使用namespace属性值+标签id属性值
五.paramteType属性
1.在XXXMapper.xml 中<select><delete>等标签的paramterType可以控制参数类型<br /> 2.SqlSession的selectList()和selectOne()的第二个参数和selectMap()的第三个参数都表述方法的参数。<br /> 2.1示例:<br />
People people = session.selectOne(“com.tjc.mapper.PeopleMapper.selById”,2); System.out.println(people); |
---|
2.2 在Mapper.xml中可以通过#{}来获取参数
2.21 parameterType控制参数类型
2.22 #{} 获取参数内容
2.22.1 使用索引,从0开始,#{}表示第一个参数(从0开始)
2.22.2 也可以使用#{param1}表示第一个参数(从param1开始)
2.22.3 如果只有一个参数(基本数据类型或者Stirng),mybtis对#{}中的内容没有要求,只要有内容即可
2.22.4 如果参数是对象 #{属性名}
2.22.5 如果参数是map, 写成#{key}
面试题:
3.关于#{} 和 ${} 的区别
3.1 #{}获取参数的内容 支持索引获取,param1获取指定位置参数,并且SQL使用?占位符
3.2 ${} 字符串拼接,不使用?,默认${内容} 内容的get/set方法,如果写数字,就是一个数字。
4.如果在xml文件中出现”<”,”>”,双引号 等特殊字符是可以使用XML文件转义标签(XML自身的)
4.1 <![CDATA[ 内容]]>
5.mybatis中实现mysql分页写法
5.1 ?不允许在关键字前后经行数学运算,需要在代码中计算完成后传递到mapper.xml中
int pageSize = 2; int pageNumber = 3; Map //显示几个 map.put(“pageSize”,pageSize); //第几页 map.put(“pageStart”, pageSize(pageNumber-1)); //如果希望传递多个参数,可以使用对象或者map List System.*out |
---|
5.3 在mapper.xml代码中
六.typeAliases 别名
- 系统内置别名: 把类型全部小写
2. 给某个类起别名
2.1 alias=”自定义”
2.2 mapper.xml中peo可以直接应用People类
3.直接给某个包下所有类起别名,别名为类名,区分大小写
3.1 mybatis.xml中配置
<br /> 3.2 mapper.xml中通过类名引用
七 Mybatis实现新增
- 概念复习
1.1 功能:从应用程序角度出发,软件具有哪些功能
1.2 业务:完成功能时的逻辑,对应Service中一个方法
1.3 事务:从数据库角度出发, 完成业务时需要执行的SQL集合,统称一个事务。
1.3.1 事务回滚:如果在一个事务中某个SQ执行失败,希望回归到事务的原点,保证数据库的完整性。
2.在mybatis中,默认关闭了JDBC的自动提交功能
2.1 每一个SqlSession默认都是不自动提交事务的
2.2 session.commit() 提交事务
增删改的时候一定要提交事务
2.3 openSession(true); 设置自动提交——àsetAutoCommit(ture);
3.mybatis底层是对JDBC的封装
3.1 JDBC中executeUdate() 执行新增,删除,修改的SQL,返回值int,表示受影响的行数
3.2 mybaits中标签没有resultType属性,认为返回值都是int
4.在openSession时,Mybatis会创建SqlSession时同时创建一个Transaction(事务对象),同时autoCommit都为false—自动提交默认关闭
4.1 如果出现异常,应该session.rollback()回滚事务。
try { People p = new People(); p.setName(“新增name”); p.setAge(88); int index = session.insert(“com.tjc.mapper.PeopleMapper.ins”,p); if(index>0) { System.out.println(“成功”); }else { System.out.println(“失败”); } } catch (Exception e) { e.printStackTrace(); session.rollback(); } |
---|
DAY 03
一.MyBatis接口绑定方案及多参数传递
1.作用:实现创建一个接口后,把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取mapper.xml中编写的sql。
2.后面mybatis和spring整合时都是用这个方案。
3.实现步骤:
3.1 创建一个接口
3.1.1接口包名和接口名与mapper.xml中namespace相同。
3.1.2接口中方法名和mapper.xml中id相同
3.2 在mybati.xml中
4.代码实现步骤
4.1 在mybatis.xml中
</mappers |
---|
4.2 在com.tjc.mapper下新建接口
public interface LogMapper { List } |
---|
4.3 在com.tjc.mapper新建一个LogMapper.xml
4.3.1 namespace 必须和接口全限定路径(包名+类名)一致
4.3.2 id值必须和接口中的方法名相同
4.3.3 如果接口中方法为多个参数,可以省略paramterType
5.多参数实现办法
5.1 在接口中声明方法
List |
---|
<br />5.2在mapper.xml中添加<br /> 5.2.1 #{}中使用0,1,2或 param1 , param2<br />
|
---|
6.可以使用注解方式在接口中声明方法
6.1 在接口中声明方法
/ mybatis把参数转换为map了,其中@Param(“key”) ,参数内容就是map的value @param accin * @param accout * @return* / List |
---|
6.2 在mapper.xml中添加
6.2.1 #{} **里面写的时@Param(“内容”) 参数中的内容**
7. 调用
InputStream is = Resources.getResourceAsStream(“mybatis.xml”); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession(); / 接口—->实例化 需要给接口一个实例化对象 使用的时JDK的动态代理设计模式 面向接口的代理设计模式(必须有接口) / // LogMapper logMapper = session.getMapper(LogMapper.class); // List // for(Log log:list) { // System.out.println(log); // } ——-就不需要这么写了 LogMapper logMapper = session.getMapper(LogMapper.class); List System.out.println(list); session.close(); |
---|
二.动态SQL
- 根据不同的条件需要执行不同的SQL命令 称为动态SQL
2. MyBatis 中动态SQL 在mapper.xml中添加逻辑判断
3.if使用
4.
4.1 当编写where标签时,如果内容中第一个是and 去掉第一个 and
4.2如果
4.3使用示例:
4.3.1 比直接使用if 少些一个where 1=1
5.
5.1 只要有一个成立,其他都不执行(类似于if—else)
5.2 代码示例
5.2.1 如果accin 和 accout 都不是null或不是””,则最后生成的sql中只有 and accin=?
6.
6.1 作用:去掉最后一个逗号(where 去掉第一个and)
6.2 作用: 如果
6.3 示例
6.3.1 id=#{id} 目的是放置
update log id=#{id }, 防止set后面if语句数据不通过造成的语法错误 accin=#{accIn }, accout=#{accOut }, id=#{id } |
---|
7.Trim
7.1 prefix 在前面添加内容
7.2 prefixOverrides 去掉前面的内容
7.3 suffix 在后面添加内容
7.4 suffixOverrides 去掉后面的内容
7.5 执行顺序:先去掉内容,后添加内容
7.6 代码示例
update log a=a, where id=100 |
---|
8.
8.1 作用:给参数重新赋值
8.2 场景:
8.2.1 模糊查询
8.2.2 在原内容前或者后面添加内容
8.3 代码示例
9.
9.1 循环参数内容,还具备在内容的前后添加内容,还具备添加分隔符功能。
9.2 使用场景: 在in 查询中;在批量新增中(mybatis中foreach效率比较低)
9.2.1 如果希望批量新增,SQL命令的写法:
insert into log values (default,1,2,3),(default,2,3,4),(default,3,4,5) |
---|
9.2.2 openSession()必须指定
9.2.2.1 底层是JDBC的PreparedStatement.addBatch();
factory.openSession(ExecutorType.BATCH) |
---|
9.3 示例:
9.3.1 collection=”” 要遍历的集合
9.3.2 item 迭代变量,#{迭代变量名}获取内容
9.3.3 open 循环后左侧添加的内容
9.3.4 close 循环后右侧添加的内容
9.3.5 separator 每次循环时,元素之间的分隔符
10.
10.1 某些SQL片段如果希望复用,可以使用
id,accin,accout,money |
---|
10.2 在
select
from log
三 ThreadLocal
- 线程容器,给线程绑定一个Object内容,只要线程不变,可以随时取出
1.1 改变线程,无法取出内容
2 语法示例
public static void main(String[] args) { final ThreadLocal threadLocal.set(“测试”); // 匿名内部类中的属性只可以是全局获知final修饰的 // final 修饰对象的特点:不允许重新实例化 new Thread() { public void run() { String result = threadLocal.get(); System.out.println(“结果” + result); }; }.start(); String result = threadLocal.get(); System.out.println(result); } |
---|
四.缓存
1.应用程序和数据库的交互过程是一个相对比较耗时的过程。
2.缓存存在的意义:让应用程序减少对数据库的访问,提升程序的运行效率。
3.MyBatis中默认SqlSession缓存开启
3.1 同一个SqlSession对象调用同一个)
3.2.1 在mybatis时,一个标签不写resultType属性,而是使用resultMap属性应用
3.使用resultMap实现单表映射关系、
3.1 数据库设计
3.2 实体类设计
public class Teacher { private int id1; private String name1; } |
---|
3.3 Mapper.xml代码
4.使用resultMap实现关联单个对象(N+1方式)
4.1 N+1查询方式:先查询出某个表的全部信息,根据这个表的信息查询另一个表的信息。
4.2 与业务装配的区别
4.2.1 在service里面写的代码,由mybatis完成装配
4.3 实现步骤
4.3.1 在student实体类中包含了一个teacher对象
public class Student { private int id; private String name; private int age; private int tid; private Teacher teacher; |
---|
4.3.2 在TeacherMapper中提供一个查询
<br />4.3.3 在StudentMapper中<br /> 4.3.3.1 <association> 装配一个对象时使用<br /> 4.3.3.2 property 对象在类中的属性名<br /> 4.3.3.3 select: 通过哪个查询查询出这个对象的信息<br /> 4.3.3.4 column:把当前表的那个列的值作为参数传递给另一个查询<br /> 4.3.3.5大前提 使用的时N+1方式时,如果列明和属性名相同可以不配置,只用Auto mapping特性,但是mybatis只会给列装配一次
<association property=“teacher” select=“com.tjc.mapper.TeacherMapper.selById” column=“tid”> |
---|
4.3.3.6 可以将上面代码简化成
5. 使用resultMap实现关联单个对象(联合查询方式)
5.1 只需要编写一个SQL,在StudentMapper中添加下面效果
5.1.1
5.1.2 此时把
5.1.3 javaType 属性:
- N + 1 方式和联合查询方式对比
6.1 N+1: 需求不确定时
6.2 联合查询:需求中确定查询时两个表一定都查询
7. N+1 名称由来
7.1 举例:学生中有三条数据
7.2 需求: 查询所有学信息及授课老师信息
7.3 需要执行的SQL命令
7.3.1 查询全部学生信息: select from 学生
7.3.2 执行3遍 select from 老师 where id=学生的外键
7.4 使用多条SQL命令查询量表数据时,如果希望把需要的数据都查询出来,则需要执行N+1条SQL才能把所有数据库查询出来
7.5缺点:
7.5.1 效率低
7.6有点
7.6.1 如果有的时候不需要查询学生时同时查询老师,只需要执行一个select * from student
7.7适用场景: 有的时候需要查询学生同时查询老师,有的时候只需要查询学生。
7.8如何解决N+1查询带来的效率低的问题
7.8.1 默认带的前提:每次都是两个查询
7.8.2 使用两表联合查询
三 使用
1.在Teacher中添加List查询关联集合对象(N+1)
public class Teacher { private int id; private String name; private List<?> list; |
---|
2.在StudentMapper.xml 中添加通过tid查询
3.在TeacherMapper.xml中添加查询全部
3.1
<collection property=“list” select=“com.tjc.mapper.StudentMapper.selByTid” column=“id”> |
---|
四. 使用实现加载集合数据(联合查询方式)
1. 在teacherMapper.xml中添加
1.1 mybatis可以通过主键判断对象是否被加载过
1.2 不需要担心创建重复Teacher
五.使用Auto Mapping结合别名实现多表查询
5.1 只能使用多表联合查询方式<br /> 5.2 要求:查询出的列名和属性名相同<br /> 5.3 实现方式:<br />** 5.3.1 . 在SQL<br />** 5.3.2 集合对象还是老老实实的用<collection />标签**
六. MyBatis 注解
1.注解:为了简化配置文件
2. Mybatis注解简化mapper.xml文件
2.1 如果设计动态SQL,依然使用mapper.xml
3.mapper.xml和注解可以共存
4.使用注解时,mybatis.xml中
4.1
4.2
5.实现查询
@Select(“select * from teacher”) List |
---|
6.实现新增
@Insert(“insert into teacher values(default,#{name})”) int insTeacher(Teacher teacher); |
---|
7.实现修改
@Update(“update teacher set name=#{name} where id=#{id}”) int updTeacher(Teacher teacher); |
---|
8.实现删除
@Delete(“delete from teacher where id=#{id}”) int delById(@Param(“id”)int id); |
---|
9.使用注解实现
9.1以N+1距离
9.2 在StudentMapper接口添加查询
@Select(“select from student where tid=#{0}”) List |
---|
9.3 在TeacherMapper接口添加
9.3.1 @Results()相当于
9.3.2 @Result()相当于
9.3.2.1 @Result(id=true)相当于
9.3.3 @Many() 相当于
9.3.4 @One() 相当于
@Results(value= { @Result(id=true,property=”id”,column=”id”), @Result(property=”name”,column=”name”), @Result(property=”list”,column=”id”,many=@Many(select=”com.tjc.mapper.StudentMapper.selByTID”)) }) @Select(“select * from teacher”) List |
---|
七. 运行原理
运行过程中涉及到的类
1.1ResourcesMyBatis 中 IO 流的工具类
1.1 加载配置文件
1.2SqlSessionFactoryBuilder() 构建器
1.2.1 作用:创建 SqlSessionFactory 接口的实现类
1.3XMLConfigBuilder MyBatis 全局配置文件内容构建器类
1.3.1 作用负责读取流内容并转换为 JAVA 代码.
1.4Configuration 封装了全局配置文件所有配置信息.
1.4.1 全局配置文件内容存放在Configuration 中
1.5DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类
1.6Transaction 事务类
16.1 每一个 SqlSession 会带有一个 Transaction 对象.
1.7TransactionFactory 事务工厂
1.7.1 负责生产 Transaction
1.8Executor 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.9DefaultSqlSession 是 SqlSession 接口的实现类
1.10ExceptionFactoryMyBatis 中异常工厂
2. 流程图
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 的运行原理.(面试官说的.)