MyBatis(二)--------核心配置、日志
4、配置解析
4.1 核心配置文件
mybatis-config.xml
- MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息
configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
4.2 环境变量(environments)
- MyBatis 可以配置成适应多种环境
- 不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境
- MyBatis默认的事务管理器就是JDBC ,默认连接池:POOLED
- 学会使用配置多套运行环境
事务管理器(transactionManager)
-
默认管理器:JDBC
-
MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]")
-
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
-
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
数据源(dataSource)
-
默认连接池:POOLED
-
链接数据库,有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]")
4.3 属性(properties)
- 我们可以通过properties属性来实现引用配置文件
- 这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。(典型的Java属性文件—db.properties)
在xml中所有标签都可以规定其顺序,要按顺序写
- 第一步:编写一个数据库配置文件(db.properties)
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username = root
password = 123456
- 第二步:在核心配置文件中引入(这样环境中的property就不用写定值,可以从外部引入)
<?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>
<!--第一种方式-->
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/zmt/dao/UserMapper.xml"/>
</mappers>
</configuration>
<!--第二种方式-->
<!--在配置文件中不写全,也可以在properties中用property写-->
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
- 可以直接引入外部文件
- 可以在其中增加一些属性配置
- 如果两个文件有同一个字段,优先使用外部配置文件的
4.4 类型别名(typeAliases)
- 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
- 第一种方式
<typeAliases>
<typeAlias type="com.zmt.pojo.User" alias="User"/>
</typeAliases>
- 也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
- 扫描实体类的包,默认别名就是这个类的类名,首字母小写。比如
domain.blog.Author
的别名为author
;若有注解,则别名为其注解的值。 - 第二种方式
<typeAliases>
<package name="com.zmt.pojo"/>
</typeAliases>
- 如何选择:在实体类比较少的时候,使用第一种方式;如果实体类十分多,建议使用第二种
- 区别:第一种可以自定义别名;第二种不行,如果非要改,需要在实体上增加注解。
@Alias("author")
public class Author {
...
}
4.5 设置(Setting)
-
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
-
具体前往官网查看:mybatis – MyBatis 3 | 配置
4.6 其他配置
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins 插件:
- mybatis-generator-core:根据数据库名字,自动生成mybatis的增删改查代码
- mybatis-plus:mybatis第三方插件,可以提高效率
- 通用mapper
4.7 映射器(mappers)
-
MapperRegistry:注册绑定我们的Mapper文件;
-
方法一:【推荐使用】
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="com/zmt/dao/UserMapper.xml"/>
</mappers>
- 方法二:使用class文件绑定注册
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="com.zmt.dao.UserMapper"/>
</mappers>
<!-- 注意点: -->
<!-- 接口名和他的Mapper配置文件必须同名 -->
<!-- 接口和他的Mapper配置文件必须在同一个包下 -->
- 方法三:使用扫描包进行注入绑定
<mappers>
<package name="com.zmt.dao"/>
</mappers>
<!-- 注意点: -->
<!-- 接口名和他的Mapper配置文件必须同名 -->
<!-- 接口和他的Mapper配置文件必须在同一个包下 -->
4.8 作用域和生命周期
- 生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBulider:
- 一旦创建了SqlSessionFactory,就不再需要它了
- 局部变量
SqlSessionFactory(核心):
- 说白了就是可以想象为:数据库连接池
- SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建一个实例。
- 因此SqlSessionFactory的最佳作用域是应用作用域(ApplocationContext)。
- 最简单的就是使用单例模式或静态单例模式。
SqlSession:
- 连接到连接池的一个请求
- SqlSession的实例不是线程安全的,因此是不能被共享的
- 所以它的最佳的作用域是请求或方法的作用域
- 用完之后需要赶紧关闭,否则资源被占用
5、ResultMap,解决属性名和字段名不一致的问题
5.1 问题
- 数据库中的字段
- 新建一个项目,拷贝之前的,情况测试实体类字段不一致的情况
public class User {
private int id;
private String name;
private String password;
}
- 测试出现问题
// select * from user where id = #{id}
// 类型处理器
// select id,name,pwd from user where id = #{id}
解决方法
- 起别名(不常用,一般用ResultMap)
<select id="getUserById" resultType="user" parameterType="int">
select id,name,pwd as password from mybatis.user where id = #{id}
</select>
5.2 ResultMap
-
结果集映射
-
数据库:id name pwd
-
pojo:id name password
<!-- 结果集映射 id:对应的resultMap名字 type:想要转化的对象-->
<resultMap id="UserMap" type="User">
<!-- column:数据库中的字段 property:实体类中的属性-->
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserById" resultMap="UserMap" parameterType="int">
select * from mybatis.user where id = #{id}
</select>
- resultMap 元素是 MyBatis 中最重要最强大的元素。
- ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
- ResultMap 的优秀之处在于你完全可以不用显式地配置它们。
- 如果这个世界总是这么简单就好了。
6、日志
6.1 日志工厂
- 如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的助手
- 曾经有其他方式:sout,debug
- 现在用:日志工厂(logImpl)
种类
- SLF4J
- LOG4J 【掌握】
- LOG4J2
- JDK_LOGGING(Java自带的工具输出)
- COMMONS_LOGGING(工具包)
- STDOUT_LOGGING (控制台输出)【掌握】
- NO_LOGGING(没有日志输出)
- 在MyBatis中具体使用哪一个日志实现,在设置中设定
- STDOUT_LOGGING:标准日志输出
配置
- 在mybatis-config.xml中配置,使用不同日志只需要修改value的值
- 标准的日志工厂实现
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
6.2 LOG4J
什么是LOG4J
-
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件。
-
我们也可以控制每一条日志的输出格式。
-
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
-
可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
使用步骤
- 第一步:先导入LOG4J的包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 第二步:编写log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/zmt.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sq1.PreparedStatement=DEBUG
- 第三步:在mybatis-config.xml中配置log4j为日志的实现
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
- 第四步:log4j的使用,直接测试运行刚才的查询
log4j的简单使用
-
注意不要导错包
-
将Logger放在全局,
-
第一步:在使用Log4j的类中,导入包,
import org.apache.log4j.Logger;
-
第二步:日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);
- 第三步:测试
@Test
public void testLog4j(){
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");
}
日志级别
- info:普通输出信息
- debug:用来调试的信息
- error:错误信息