官方手册:https://mybatis.org/mybatis-3/zh/configuration.html
1、全局配置文件mybatis-config.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--dtd是xml文件的约束,不规范就会报错,与spring中xsd类似-->
1.1、<properties>元素配置外部属性资源文件,通过${}进行引用;也可以在内部声明属性 生成资源文件放在根路径
resource:项目路径下的资源
url:磁盘上的资源
<!--
配置外部属性资源文件,通过${}进行引用;也可以在内部声明属性
生成资源文件放在根路径
resource:项目路径下的资源
url:磁盘上的资源
-->
<properties resource="db.properties">
<!--相当于在内部 声明一个变量,在下面被引用-->
<!--<property name="mysql.username" value="root"/>-->
</properties>
1.1.1、db.properties
mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
mysql.username=xxx
mysql.password=xxx
1.2、<settings>元素:mybatis设置选项,可以改变mybatis运行时行为
useColumnLabel:是否可以用列别名,默认是允许,设置别名后,会根据SQL的别名和属性名进行映射
useGeneratedKeys:主键是否自动增长
autoMappingUnknownColumnBehavior:数据库字段名与pojo属性名自动映射不匹配时,进行的动作
默认:NONE: 不做任何反应
WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN
FAILING: 映射失败 (抛出 SqlSessionException)
defaultExecutorType:配置默认的执行器。
(默认)SIMPLE 就是普通的执行器,每次执行都会预编译;
REUSE 执行器会重用预处理语句(PreparedStatement);
BATCH 执行器不仅重用语句还会执行批量更新。
也可以在openSession的参数中设置
defaultStatementTimeout:设置查询超时时间,它决定数据库驱动等待数据库响应的秒数。
mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
即数据库蛇形命名映射为java驼峰命名
qin_qing_ao 蛇形 - - > qinQingAo 驼峰
jdbcTypeForNull:当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。
当往数据库插入数据时,某个数据值为null时,映射到数据库的类型
默认:OTHER mysql是可以识别出OTHER类型的
NULL 如果是ORACLE一定要设置为NULL,因为ORACLE不能识别OTHER类型
VARCHAR 当属性值为空时,为数据库设置一个空字符串
logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
加入mybatis中实现了多个日志框架,可以用logImpl指定使用哪个日志框架
如果使用了SLF4J,可以不用设置该选项,因为SLF4J本身就是负责选择哪种日志实现框架的
如果没有使用SLF4J的情况下,使用了多个日志实现框架,最好设置需要使用的日志框架
1.3、<typeAliases>
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
通常重命名只重命名pojo包下面的类
<!--
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
通常重命名只重命名pojo包下面的类
-->
<typeAliases>
<!--
根据包名设置包里面所有类的别名:会将类的名字设置别名,并且忽略大小写
还可以在包里的类中使用@Alias()注解为类单独设置个性别名(那么默认地以类的名字的别名便会失效)
除了可以设置自定义的类的别名以外,mybatis还内置了很多常见的类型别名
常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格
-->
<package name="cn.qqa.pojo"/>
</typeAliases>
1.4、 <environments default="development">复数可以多个环境
属性default:设置默认的数据库类型
1.4.1.1、<environment id="development">
environment:配置数据库环境
属性id 指定当前数据库环境的唯一表示 ,会被default属性设置
可以设置多个:比如开发库、测试库、上线正式库
1.4.1.2、<transactionManager type="JDBC"/>
事务管理器类型
type = JDBC 使用jdbc的事务管理(提交和回滚)
MANAGED 不适用事务
1.4.1.3 <dataSource type="POOLED">
数据源
type 指定连接池
POLLED 指定使用mybatis的连接池
UNPOOLED 不使用连接池
JNDI JNDI连接池 可以在Tomcat中使用
相应的修改要改一下POOLED的实现类
集成SSM:gradle连接池
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
1.5、<databaseIdProvider type="DB_VENDOR">:数据库厂商标识(databaseIdProvider):mybatis提供用于跨数据平台,根据不同的数据库执行不同的sql
mybatis基于sql语句驱动
type="DB_VENDOR" 利用数据库的厂商名称来区分
步骤:
1.为需要跨数据库设置不同的厂商标识
2.编写不同的sql语句,databaseId必须等于厂商的value
1.6、<mappers>:设置映射器
4种映射方式
1.设置<mapper resource 设置一个xxxMapper.xml 适用以前的staementID进行操作
2.设置<mapper class 设置一个xxxMapper接口 适用接口绑定的方式
3.设置<mapper url 适用磁盘绝对路径(基本不用)
4.设置<package 根据包设置包下面的所有xxxMapper接口,这种方式适用接口绑定的方式和注解
<mappers>
<!-- XML mapper files should be listed here -->
<!--<mapper resource="cn/qqa/mapper/EmpMapper.xml" />-->
<!--<mapper class="cn.qqa.mapper.EmpMapper"/>-->
<package name="cn.qqa.mapper"/>
</mappers>
1.7、mybatis-config.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">
<!--dtd是xml文件的约束,不规范就会报错,与spring中xsd类似-->
<!--
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
-->
<!--
就是!DOCTYPE后面对应的根节点
-->
<configuration>
<!-- Setup the transaction manager and data source that are
appropriate for your environment
-->
<!--
配置外部属性资源文件,通过${}进行引用;也可以在内部声明属性
生成资源文件放在根路径
resource:项目路径下的资源
url:磁盘上的资源
-->
<properties resource="db.properties">
<!--相当于在内部 声明一个变量,在下面被引用-->
<!--<property name="mysql.username" value="root"/>-->
</properties>
<!--mybatis设置选项,可以改变mybatis运行时行为-->
<settings>
<!--name属性
useColumnLabel:是否可以用列别名,默认是允许,设置别名后,会根据SQL的别名和属性名进行映射
useGeneratedKeys:主键是否自动增长
autoMappingUnknownColumnBehavior:数据库字段名与pojo属性名自动映射不匹配时,进行的动作
默认:NONE: 不做任何反应
WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN
FAILING: 映射失败 (抛出 SqlSessionException)
defaultExecutorType:配置默认的执行器。
(默认)SIMPLE 就是普通的执行器,每次执行都会预编译;
REUSE 执行器会重用预处理语句(PreparedStatement);
BATCH 执行器不仅重用语句还会执行批量更新。
也可以在openSession的参数中设置
defaultStatementTimeout:设置查询超时时间,它决定数据库驱动等待数据库响应的秒数。
mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
即数据库蛇形命名映射为java驼峰命名
qin_qing_ao 蛇形 - - > qinQingAo 驼峰
jdbcTypeForNull:当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。
当往数据库插入数据时,某个数据值为null时,映射到数据库的类型
默认:OTHER mysql是可以识别出OTHER类型的
NULL 如果是ORACLE一定要设置为NULL,因为ORACLE不能识别OTHER类型
VARCHAR 当属性值为空时,为数据库设置一个空字符串
logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
加入mybatis中实现了多个日志框架,可以用logImpl指定使用哪个日志框架
如果使用了SLF4J,可以不用设置该选项,因为SLF4J本身就是负责选择哪种日志实现框架的
如果没有使用SLF4J的情况下,使用了多个日志实现框架,最好设置需要使用的日志框架
-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
通常重命名只重命名pojo包下面的类
-->
<typeAliases>
<!--
根据包名设置包里面所有类的别名:会将类的名字设置别名,并且忽略大小写
还可以在包里的类中使用@Alias()注解为类单独设置个性别名(那么默认地以类的名字的别名便会失效)
除了可以设置自定义的类的别名以外,mybatis还内置了很多常见的类型别名
常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格
-->
<package name="cn.qqa.pojo"/>
</typeAliases>
<!-- mybatis-config.xml -->
<!--
插件:可以把他理解成mybatis的拦截器,可以拦截四大对象
可以拦截sql,给sql加一些公共的功能
自定义插件
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
-->
<!--
<environments>:复数可以多个环境
default:默认的数据库类型
-->
<environments default="development">
<!--
environment 配置数据库环境 id 指定当前数据库环境的唯一表示 ,会被default属性设置
可以设置多个:比如开发库、测试库、上线正式库
-->
<environment id="development">
<!--事务管理器 类型
type = JDBC 使用jdbc的事务管理(提交和回滚)
MANAGED 不适用事务
-->
<transactionManager type="JDBC"/>
<!--
数据源
type 指定连接池
POLLED 指定使用mybatis的连接池
UNPOOLED 不使用连接池
JNDI JNDI连接池 可以再Tomcat中使用
相应的修改要改一下POOLED的实现类
集成SSM:gradle连接池
-->
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<environment id="test">
<!--事务管理器 类型
type = JDBC 使用jdbc的事务管理(提交和回滚)
MANAGED 不适用事务
-->
<transactionManager type="JDBC"/>
<!--
数据源
type 指定连接池
POLLED 指定使用mybatis的连接池
UNPOOLED 不使用连接池
JNDI JNDI连接池 可以再Tomcat中使用
相应的修改要改一下POOLED的实现类
集成SSM:gradle连接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/shop?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="521.james"/>
</dataSource>
</environment>
</environments>
<!--数据库厂商标识(databaseIdProvider):mybatis提供用于跨数据平台,根据不同的数据库调用不同的sql-->
<!--
mybatis基于sql语句驱动
type="DB_VENDOR" 利用数据库的厂商名称来区分
步骤:
1.为需要跨数据库设置不同的厂商标识
2.编写不同的sql语句,databaseId必须等于厂商的value
-->
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
<!--设置映射器-->
<!--
4种映射方式
1.设置<mapper resource 设置一个xxxMapper.xml 适用以前staementID进行操作
2.设置<mapper class 设置一个xxxMapper接口 适用接口绑定的方式
3.设置<mapper url 适用磁盘绝对路径(基本不用)
4.设置<package 根据包设置包下面的所有xxxMapper接口,这种方式适用接口绑定的方式和注解
-->
<mappers>
<!-- XML mapper files should be listed here -->
<!--<mapper resource="cn/qqa/mapper/EmpMapper.xml" />-->
<!--<mapper class="cn.qqa.mapper.EmpMapper"/>-->
<package name="cn.qqa.mapper"/>
</mappers>
</configuration>
2.映射器配置文件xxxMapper.xml
2.1、<mapper namespace="cn.qqa.mapper.EmpMapper">
<mapper>只用一个属性就是命名空间,一般情况下一个mapper映射文件对应一个不同的命名空间,利于管理和维护。
书写:默认情况下可以随意书写,但是如果使用接口绑定的形式就必须要书写对应的接口的完整限定名。
2.2.1、<insert>、<delete>、<update>元素
id:在命名空间中唯一的标识符,可以被用来引用这条语句。
注意:如果是接口绑定的方式,一定要保证接口方法名与id相同
同一个命名空间只能有一个唯一的id,除非有不同的databaseId
parameterType:将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,
因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,
默认值为未设置(unset)。
用途:mybatis会根据id找到对应的方法以及参数,所以一般不用
statementType:
STATEMENT:jdbc Statement 不支持参数预解析
PREPARED:jdbc PreparedStatement (支持参数预解析【sql语句中含有?】,默认的,#{}预解析为?)
CALLABLE:jdbc CallableStatement 执行存储过程【不利于数据库维护与移植】
默认值:PREPARED。
用途:设置当前的statement(因为mybatis是对jdbc的封装)
useGeneratedKeys:(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的
getGeneratedKeys 方法来取出由数据库内部生成的主键
(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),
默认值:false。
keyProperty:(仅适用于 insert 和 update)指定能够唯一识别对象的属性,
MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,
默认值:未设置(unset)。
如果生成列不止一个,可以用逗号分隔多个属性名称。
用途(前提:数据库支持自动增长的功能):与useGeneratedKeys配合使用,也就是将自动增长的主键赋值到指定属性
应用场景:当插入主表并且要插入从表时
用途:获取更新后自动增长的主键 useGeneratedKeys="true" keyProperty="id"
keyColumn:(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,
当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
有可能存在组合主键,指定获取哪一个字段
databaseId:如果配置了数据库厂商标识(databaseIdProvider),
MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;
如果带和不带的语句都有,则不带的会被忽略。
2.2.2、<selectKey order="BEFORE" keyProperty="id" resultType="int">元素
如果数据库不支持自动增长的功能:
selectKey元素可以在增删改之前或之后执行
针对于ORACLE等不支持自动增长的情况
order: BEFORE 或 AFTER 在增删改之前 或 之后运行
keyProperty:与上面相同,指定能够唯一识别对象的属性,将当前查询结果放到哪个pojo属性中
resultType:返回值类型
statementType:这会让 MyBatis 分别使用 Statement(一句一句执行),PreparedStatement(预编译) 或 CallableStatement(存储过程),默认值:PREPARED。
相当于嵌套查询,所以要有resultType
<selectKey order="BEFORE" keyProperty="id" resultType="int">
SELECT MAX(id)+1 FROM EMP
</selectKey>
2.3、<select >:与增删改元素不同属性
属性resultSetType:jdbc取出结果集的数据,需要调用next方法,一般会释放上一条,当我们还需要上一条或者首条时,可以设置该属性
属性resultSets:适用于多结果集(存储过程)
2.4、EmpMapper.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">
<!--dtd是xml文件的约束,不规范就会报错,与spring中xsd类似-->
<!--<mapper>只用一个属性就是命名空间,一般情况下一个mapper映射文件对应一个不同的命名空间,利于管理和维护
书写:默认情况下可以随意书写,但是如果使用接口绑定的形式就必须要书写对应的接口的完整限定名
-->
<!--<mapper namespace="cn.qqa.pojo.EmpMapper">-->
<mapper namespace="cn.qqa.mapper.EmpMapper">
<!--根据id查询Emp对应实体(数据库字段)-->
<!--
resultSetType:jdbc取出结果集的数据,需要调用next方法,一般会释放上一条,当我们还需要上一条或者首条时,可以设置该属性
resultSets:适用于多结果集(存储过程)
-->
<select id="selectEmp" resultType="emp" >
SELECT * FROM EMP WHERE id = #{id}
</select>
<!--
id:在命名空间中唯一的标识符,可以被用来引用这条语句。
注意:如果是接口绑定的方式,一定要保证接口方法名与id相同
同一个命名空间只能有一个唯一的id,除非有不同的databaseId
parameterType:将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,
因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,
默认值为未设置(unset)。
用途:mybatis会根据id找到对应的方法以及参数,所以一般不用
statementType:
STATEMENT:jdbc Statement 不支持参数预解析
PREPARED:jdbc PreparedStatement (支持参数预解析【sql语句中含有?】,默认的,#{}预解析为?)
CALLABLE:jdbc CallableStatement 执行存储过程【不利于数据库维护与移植】
默认值:PREPARED。
用途:设置当前的statement(因为mybatis是对jdbc的封装)
useGeneratedKeys:(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的
getGeneratedKeys 方法来取出由数据库内部生成的主键
(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),
默认值:false。
keyProperty:(仅适用于 insert 和 update)指定能够唯一识别对象的属性,
MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,
默认值:未设置(unset)。
如果生成列不止一个,可以用逗号分隔多个属性名称。
用途(前提:数据库支持自动增长的功能):与useGeneratedKeys配合使用,也就是将自动增长的主键赋值到指定属性
应用场景:当插入主表并且要插入从表时
用途:获取更新后自动增长的主键 useGeneratedKeys="true" keyProperty="id"
keyColumn:(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,
当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
有可能存在组合主键,指定获取哪一个字段
databaseId:如果配置了数据库厂商标识(databaseIdProvider),
MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;
如果带和不带的语句都有,则不带的会被忽略。
-->
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="id" >
<!--
如果数据库不支持自动增长的功能:
selectKey元素可以在增删改之前或之后运行
针对于ORACLE等不支持自动增长的情况
order: BEFORE 或 AFTER 在增删改之前或之后运行
keyProperty:与上面相同,指定能够唯一识别对象的属性,将当前查询结果放到哪个pojo属性中
resultType:返回值类型
statementType:这会让 MyBatis 分别使用 Statement(一句一句执行),PreparedStatement(预编译) 或 CallableStatement(存储过程),默认值:PREPARED。
-->
<!--相当于嵌套查询,所以要有resultType-->
<!--
<selectKey order="BEFORE" keyProperty="id" resultType="int">
SELECT MAX(id)+1 FROM EMP
</selectKey>
-->
INSERT INTO
EMP(username)
VALUES ( #{username});
</insert>
<update id="updateEmp">
update emp
set username = #{username}
where id = #{id}
</update>
<delete id="deleteEmp">
delete
from Emp
where id=#{id}
</delete>
</mapper>
3、SqlSessionFactory+SqlSession详解
步骤:
3.1.根据mybatis-config.xml全局配置文件构建SqlSessionFactory
3.2.将xml构建成输入流,因为SqlSessionFactory只接受输入流。
3.3.新建SqlSessionFactory工厂,是比较重量级的:将全局配置文件以及所有的mapper全部加载到Configuration对象中
3.4.调用SqlSessionFactory.openSession(),连接数据库
* 给openSession传入不同的参数会给SqlSession后续的数据库操作造成不同的影响
* 默认的 openSession() 方法没有参数,它会创建具备如下特性的 SqlSession:
* 事务作用域将会开启(也就是不自动提交)。
* 将由当前环境配置的 DataSource 实例中获取 Connection 对象。
* 事务隔离级别将会使用驱动或数据源的默认设置。
* 预处理语句不会被复用,也不会批量处理更新。
* 参数:
* boolean autoCommit:可以设置事务为自动提交,否则需要手动提交
* Connection connection:可以动态切换连接
* TransactionIsolationLevel level:可以设置事务隔离级别
* ExecutorType exectype:预处理语句(就是预编译后,带?的sql语句)是否复用,是否批量处理更新
*
* ExecutorType.SIMPLE:该类型的执行器没有特别的行为。它为每个语句的执行创建一个新的预处理语句。
* ExecutorType.REUSE:该类型的执行器会复用预处理语句。
* ExecutorType.BATCH:该类型的执行器会批量执行所有更新语句,如果 SELECT 在多个更新中间执行,将在必要时将多条更新语句分隔开来,以方便理解。
3.5.SqlSession负责执行具体的数据库操作
3.6.获得映射器
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
·EmpMapper是接口,为什么能被实例化?
Mybatis在调用getMapper时,底层会创建jdk动态代理!
4、日志配置
* 1.导入pom依赖
<!--日志导入logbackjar包-->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
* 2.添加logback配置文件
logback.xml
<configuration>
<!--
追加器 日志以哪种方式进行输出
name 取名
class 不同实现类会输出到不同的地方 Console控制台
ch.qos.logback.core.ConsoleAppender 输出到控制台
-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--
encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by
default
-->
<encoder>
<!--配置日志输出格式-->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{100} - %msg%n</pattern>
</encoder>
</appender>
<!--控制所有的日志级别-->
<root level="error">
<!--设置将当前日志级别输出到哪个追加器上面-->
<appender-ref ref="STDOUT" />
</root>
<!--cn.qqa.mapper 为包专门配置日志-->
<!--通过<logger>标签配置更细粒度的日志级别-->
<logger name="cn.qqa.mapper" level="debug"></logger>
<!--<logger name="org.apache.ibatis.transaction" level="debug"></logger>-->
</configuration>
* 3.在某个类下加入声明
Logger logger = LoggerFactory.getLogger(this.getClass());
5、EmpMapper.java
package cn.qqa.mapper;
import cn.qqa.pojo.Emp;
/**
* 注意
* xxxMapper.xml文件中,同一个命名空间只能有一个唯一的id,
* 所以在接口中也只能有唯一一个方法名,虽然java中可以函数重载,但是mybatis不支持
*/
public interface EmpMapper {
//查询
Emp selectEmp(Integer id);
//插入
Integer insertEmp(Emp emp);
//更新
Integer updateEmp(Emp emp);
/**
* 赠删改的返回值 除了可以声明int(Integer)还可以声明bool(Boolean) 如果大于1就返回ture
* @param id
* @return
*/
//删除
Boolean deleteEmp(Integer id);
}
6、MybatisTest.java
package cn.qqa.tests;
import cn.qqa.mapper.EmpMapper;
import cn.qqa.pojo.Emp;
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 org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
/**
* 日志配置
* 1.导入pom依赖
* 2.添加logback配置文件
* 3.在某个类下加入声明
*/
public class MybatisTest {
Logger logger = LoggerFactory.getLogger(this.getClass());
SqlSessionFactory sqlSessionFactory;
@Before
public void before(){
//从XML中构建SqlSeesionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
}catch (IOException e){
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test01() throws IOException, SQLException {
//根据mybatis-config.xml全局配置文件构建SqlSessionFactory
String config = "mybatis-config.xml";
//将xml构建成输入流,因为SqlSessionFactory只接受输入流
InputStream inputStream = Resources.getResourceAsStream(config);
//新建SqlSessionFactory工厂,是比较重量级的:将全局配置文件以及所有的mapper全部加载到Configuration对象中
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//SqlSession负责执行具体的数据库操作
/**
*
* 给openSession传入不同的参数会给SqlSession后续的数据库操作造成不同的影响
* 默认的 openSession() 方法没有参数,它会创建具备如下特性的 SqlSession:
* 事务作用域将会开启(也就是不自动提交)。
* 将由当前环境配置的 DataSource 实例中获取 Connection 对象。
* 事务隔离级别将会使用驱动或数据源的默认设置。
* 预处理语句不会被复用,也不会批量处理更新。
*
* 参数:
* boolean autoCommit:可以设置事务为自动提交,否则需要手动提交
* Connection connection:可以动态切换连接
* TransactionIsolationLevel level:可以设置事务隔离级别
* ExecutorType exectype:预处理语句(就是sql语句)是否复用,是否批量处理更新
*
* ExecutorType.SIMPLE:该类型的执行器没有特别的行为。它为每个语句的执行创建一个新的预处理语句。
* ExecutorType.REUSE:该类型的执行器会复用预处理语句。
* ExecutorType.BATCH:该类型的执行器会批量执行所有更新语句,如果 SELECT 在多个更新中间执行,将在必要时将多条更新语句分隔开来,以方便理解。
*/
SqlSession sqlSession = sqlSessionFactory.openSession();
String databaseProductName = sqlSession.getConnection().getMetaData().getDatabaseProductName();
System.out.println(databaseProductName);
//EmpMapper是接口,为什么能被实例化?
//Mybatis在调用getMapper时,底层会创建jdk动态代理
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
try{
Emp emp = mapper.selectEmp(1);
System.out.println(emp);
}catch (Exception ex){
System.out.println("查询失败!");
}
sqlSession.commit();
sqlSession.close();
}
/**
* 日志级别
* TRACE < DEBUG < INFO < WARN < ERROR
* 1 2 3 4 5
* 设置为2时,大于等于2的都会输出
*/
@Test
public void test02(){
logger.trace("跟踪级别");
logger.debug("调试级别");
logger.info("信息级别");
logger.warn("警告级别");
logger.error("异常级别");
}
/**
* 插入
* 注意要提交事务
*/
@Test
public void insert(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setUsername("xxx");
try{
Integer result = mapper.insertEmp(emp);
System.out.println(result);
System.out.println(emp);
sqlSession.commit();
}catch (Exception ex){
System.out.println("插入失败");
sqlSession.rollback();;
}finally {
sqlSession.close();
}
}
/**
* 更新
* 注意要提交事务
*/
@Test
public void update(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setId(5);
emp.setUsername("xxx");
try{
Integer result = mapper.updateEmp(emp);
System.out.println(result);
sqlSession.commit();
}catch (Exception ex){
System.out.println("插入失败");
sqlSession.rollback();;
}finally {
sqlSession.close();
}
}
/**
* 删除
* 注意要提交事务
*/
@Test
public void delete(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
try{
boolean result = mapper.deleteEmp(7);
System.out.println(result);
sqlSession.commit();
}catch (Exception ex){
System.out.println("删除失败");
sqlSession.rollback();;
}finally {
sqlSession.close();
}
}
}