Mybatis框架
1.问题总结
1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。
设想:使用数据库连接池管理数据。
2、将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护。
设想:将sql语句配置在xml配置文件中,及时sql变化,不需要对java代码进行重新编译。
3、想preparadStatement中设置参数,对占位符号位置和设置参数,硬编码在java代码中,不利于系统维护。
设想:将对占位符号位置和设置参数全部配置在xml中。
4、从resultSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护。
设想:将查询结果集自动映射成java 对象。
2 1Mybatis框架
mybatis是什么?
1.mybatis是一个持久层的框架,是apache下的顶级项目。
2.mybatis让程序员将主要精力放在sql上,通过mybatis提供的应设防时,自由灵活生成(办自动化,大部分需要程序员编写sql)满足需要sql语句。
3.mybatis将需要向preparadStatement输入的参数自动的映射(输入映射),将查询结果集灵活的映射出java对象(输出映射)。
2.2mybatis框架
sqlMapConfig.xml(是mybatis的全局配置文件,名称是不固定的)配置了数据源、事务等mybatis运行环境
配置映射(配置sql语句)
mapper.xml、mapper.xml、mapper.xml…
SqlSessionFactory(会话工厂),根据配置文件来创建工厂
作用:创建SqlSession对象
SqlSession(会话),是一个接口,面向用户(程序员)的接口
作用:操作数据库(发出sql增、删、改、查)
Executro(执行器),是一个接口(基本执行器、缓存执行器)
作用:SqlSession内部通过执行器来操作数据库
mappedstatement(底层封装对象)
作用:对操作数据库存储封装,包括sql语句,输入参数、输出结果类型。
mysql
环境:mybatis-3.5
lib下,依赖包
mybatis-3.5.1.jar
mysql 数据库驱动包
在pom.xml文件中添加依赖jar包
这是一个maven的依赖包网站可以看到各种jar包的版本
https://mvnrepository.com/ maven—pom.xml
点击箭头可以进去看到的配置信息
这样就可以直接复制进pom.xml里了,不用担心找不到版本问题了
mybatis依赖包
org.mybatis
mybatis
3.2.6
mysql依赖包
mysql
mysql-connector-java
5.1.43
整体的项目目录结构;
java: 放dao接口以及实体类
resources: 放配置文件以及一些属性文件
mapper: 放mapper映射文件
Test : 放一些测试类
4.1MyBatis的核心对象
MyBatis的核心接口和类,如下:
(1)每个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心。
(2)首先获取SqlSessionFactoryBuilder对象,可以根据XML配置文件或Configuration类的实例构建该对象。
(3)然后获取SqlSessionFactory对象,该对象实例可以通过SqlSessionFactoryBuilder对象获取
(4)有了SqlSessionFactory对象以后,进而可以获得SqlSession实例,SqlSession对象中完全包含以数据库为背景的所有执行SQL操作的方法,可以用该实例来直接执行已映射的SQL语句。
4.2.1SqlSessionFactoryBuilder
1.SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且提供了多个build()方法的重载,
常用的有以build(),InpuStream(字节流),Reader(字符流),Configuration(类),为入参。
4.1.2 SqlSession的工厂—SqlSessionFactory
1.SqlSessionFactory的作用
SqlSessionFactory就是创建SqlSession实例的工厂。所有的MyBatis应用都是以SqlSessionFactory实例为中心,SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder的实例获得。有了SqlSessionfFactory之后就可以使用他提供的openSession()方法来获取SqlSession实例。
openSession()方法的参数为boolean值时,若传入true表示关闭失误控制,自动提交;若传入false表示开启事务控制。若不传入参数,默认为true.
2.SqlSessionFactory的生命周期
SqlSessionFactory对象一旦创建,就会在整个应用运行过程中始终存在。没有理由去销毁或者再创建他,并且在应用运行中也不建议多次创建SqlSessionFactory。因此SqlSessionFacotry的最佳作用域是Application.对于这种只需要存在一个对象实例的情况,可以使用单例模式:
(1)创建SqlSessionUtil.java的工具类,在静态代码块中创建SqlSessionFactory对象。代码如下:
public class SqlSessionUtil {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
//读取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlsession(boolean autocommit){
return sqlSessionFactory.openSession(autocommit);
}
//关闭会话方法
public static void colseSqlSession(SqlSession sqlSession){
sqlSession.close();
}
}
1、SqlSession的作用
SqlSession是用于持久化操作的对象,类似于JDBC中的Connection,他提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句:方法如下
2、SqlSession的生命周期和作用域:
SqlSession对应着一次数据库会话,由于数据库会话不是永久的,因此SqlSession的生命周期也不是永久的,但每次访问数据库时都需要创建它。创建SqlSession对象的方式只有一个,那就是使用SqlSessionFacotry对象的openSession()方法。
每个线程都有自己的SqlSession实例,SqlSession实例不能被共享,也不是线程安全的。因此最佳的作用域范围是request作用域或者方法体作用域。
每次使用完SqlSession对象后必须确保SqlSession在finally语句块中正常关闭。
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
//do work
} finally {
sqlSession.close();
}
一,SqlSession.SelectOne(mapper+selectid)/SqlSession.SelectList(mapper+selectid)/SqlSession.SelectMap(mapper+selectid)
SqlSession直接调用mapper文件的SQL语句,不需要接口以及接口的实现类,就可以实现对数据库的操作。这种方式中,Mapper的命名空间属性的作用就是区分不同的mapper,保证mapper的唯一性。
二,SqlSession.getMapper(xxxMaper.class).getXXXList()
面向接口的编程方式,需要接口名与mapper的命名空间属性值保持一致,从而将接口与mapper文件对应起来。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句。因此namespace的命名必须跟接口同名。
这里由于路径设置两种思路的不同,常常会引起一些路径名上问题。
一种思路是,Mapper文件和接口同属于DAO层,故在代码结构上,Mapper文件与该DAO接口应放置在同一package下,并且习惯上都已Mapper结尾。
还有一种思路是,把Mapper.xml文件看作配置文件,而放在resoures的目录下。如此Mapper.class与Mapper.xml的根路径就不同了,这里一定要注意。
5.1掌握核心配置文件
MyBatis 的基本要素—核心配置文件
MyBatis 核心配置文件( mybatis-config.xml),该文件配置了 MyBatis 的一些全局信息,包含数据库连接信息和 MyBatis 运行时所需的各种特性,以及设置和影响 MyBatis 行为的一些属性。
mybatis-config.xml 文件结构
mybatis-config.xml 文件需配置一些基本元素,需要注意的是,该配置文件的元素节点是有先后顺序的,其层次结构如下图:
说明
1、从上图中可以看出,configuration 元素是整个 XML 配置文件的根节点,其角色就相当于是 MyBatis 的总管, MyBatis 所有的配置信息都会存放在它里面。 MyBatis 还提供了设置这些配置信息的方法。 Configuration 可从配置文件里获取属性值,也可以通过程序直接设置。Configuration 可供配置的内容如下。
2、mybatis-config.xml 文件的元素节点是有一定顺序的,节点位置若不按顺序排位,那么 XML 文件会报错。
1、properties 元素
properties 元素描述的都是外部化、可替代的属性。那么这些属性如何获取?有以下两种方式实现。
(1)可通过外部指定的方式,将数据库连接相关信息配置在典型的 Java 属性配置文件中(如 database. properties),并使用这些属性对配置项实现动态配置。即通过 resource 属性从外部指定 properties 属性文件( database.properties ),该属性文件描述数据库连接的相关配置(数据库驱动、连接数据库的 url ,数据库用户名,数据库密码),位置也是在/ resources 目录下。代码如下:
复制代码
①database. properties:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/smbms?userUnicode=true&characterEncoding=utf-8&&zeroDateTimeBehavior=convertToNull
username=root
password=root
②mybatis-config.xml 部分内容:
......
说明:上述代码中,driver、url、username、password 属性将会用包含进来的 database. properties 文件中的值来替换。
复制代码
(2)直接配置为 xml ,并使用这些属性对配置项实现动态配置,代码如下:
复制代码
mybatis-config.xml 部分内容:
······
说明:上述代码中,driver、url、username、password 将会由 properties 元素中设置的值来替换。
复制代码
问题思考:若两种方式同时都用了,那么哪种方式优先?如下代码所示:
复制代码
分析:这个例子中的 property 子节点设置的 username 和 password 的值会先被读取,由于 database properties 中也设置了这两个属性,所以 resource 中同名属性将会覆盖 property 子节点的值。
结论: resource 属性值的优先级高于 property子节点配置的值。
复制代码
2、settings 元素
settings 元素的作用是设置一些非常重要的设置选项,用于设置和改变 MyBatis 运行中的行为,比如此处设置 MyBatis 的 log 日志实现为 LOG4J,即使用 log4j 实现日志功能。
常用配置如下表:
设置项 描述 允许值 默认值
cacheEnabled 对在此配置文件下的所有 cache 进行全局性开/关设置 true/false true
lazyLoadingEnabled 全局性设置懒加载。如果设为 false ,则所有相关联的都会被初始化加载 true/false true
autoMappingBehavior MyBatis对于resultMap自动映射匹配级别 NONE /PARTIAL: /FULL PARTIAL
logImpl 指定 Mybatis 所用日志的具体实现,未指定时将自动查找 SLF4J | LOG4J | LOG4J2 |… Not set
autoMappingBehavior 讲解
Mybatis的自动映射策略默认是开启的,而且默认是只对非嵌套的resultMap进行自动映射。这是通过Mybatis的全局配置autoMappingBehavior参数配置的。它一共有三种取值,分别是NONE、PARTIAL和FULL。
NONE:表示不启用自动映射
PARTIAL:表示只对非嵌套的resultMap进行自动映射
FULL:表示对所有的resultMap都进行自动映射
3、typeAliases 元素
typeAliases 元素的作用是配置类型别名,通过与 MyBatis 的 SQL 映射文件相关联,减少输入多余的完整类名,以简化操作。具体配置如下:
以上这种写法的弊端在于如果一个项目中有多个 POJO 的时候,需要一一进行配置,所以有更加简化的写法,就是通过 package 的 name 属性直接指定包名, MyBatis 会自动扫描指定包下的 JavaBean ,并默认设置一个别名,默认名称为 JavaBean 的非限定类名。具体配置如下:
说明:
1、配置了 typeAliases 元素,在 Mapper.xml 中的 resultType 属性无须写完全限定名com.smbms.pojo.User,只需要写 User 或 user 不区分大小写。
2、对于基础数据类型, MyBatis 已经为许多常见的 Java 类型内建了相应的类型别名,一般都是与其映射类型一致,并且它们都是大小写不敏感的,
比如映射的类型 int、Boolean、String、Integer 等,它们的别名就是 int 、Boolean或boolean、String或string、Integer或integer。
4、environments 元素
表示配置 MyBatis 的多套运行环境,MyBatis 可以配置多套运行环境,如开发环境、测试环境、生产环境等,我们可以灵活选择不同的配置,从而将 SQL 映射应用到不同的数据库环境上。这些不同的运行环境,就可以通过 environments 元素来配置。environments 元素节点下通过配置多个 environment 子元素节点,实现配置多套运行环境,但是不管增加几套运行环境,都必须要明确选择出当前的唯一一个运行环境(即默认运行环境:通过 default 指定)。这是因为毎个数据库都是对应一个 SqlSessionFactorγ 实例的,需要指明哪个运行环境将被创建,并把运行环境中设置的参数传递给 SqlSessionFactoryBuilder。具体配置如下:
复制代码
··········
environment:配置 MyBatis 的一套运行环境,需指定运行环境 ID、事务管理、数据源配置等相关信息。
复制代码
注意点:
1、默认的运行 ID :通过 default 属性来指定当前的运行环境 ID 为 development ,对于环境 ID 的命名要确保唯一。
2、transactionManager 事务管理器,设置其类型为 JDBC(MyBatis 有两种事务管理类型,即JDBC、MANAGED),直接使用 JDBC 的提交和回滚功能,依赖于从数据源获得连接来管理事务的生命周期。
3、dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。 MyBatis 提供了三种数据源类型(UNPOOLED、POOLED、JNDI),这里我们使用 POOLED 数据源类型。该类型的实现利用 “池” 的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间,是 MyBatis 实现的简单的数据库连接池类型,它使数据库连接可被复用,不必在每次请求时都去创建一个物理连接。这对于高并发的 Web 应用是一种流行的处理方式,有利于快速响应请求。
5、mappers 元素
mappers:映射器,在 中有两个子元素 、 ,用来定义 SQL 的映射语句,我们只需要告诉 MyBatis 去哪里找到这些 SQL 语句(即去哪里找相应的 SQL 映射文件),整个项目中可以有1个或多个SQL 映射文件。可以使用类资源路径或者 URL 等,具体代码如下:
方式一:使用类资源路径获取资源(推荐使用)
复制代码
......
mapper: mappers 的子元素节点,具体指定 SQL 映射文件的路径,其中 resource 属性的值表述了 SQL 映射文件的路径(类资源路径)。
复制代码
方式二:使用 URL 获取资源
eclipse 查看文件 URL:右击要查看的文件 >> Properties >> Resource >> 右侧 Location 即为文件位置(复制粘贴路径即可)
方式三:使用 获取资源
注意:这种方式必须保证接口名和 SQL 映射文件名相同,还必须在同一个包中。
方式四:
复制代码
注意:
1、这种方式必须保证接口名和 SQL 映射文件名相同,还必须在同一个包中。
2、使用此方式对于接口方法使用注解方式来说,没有同包同名的限制条件。