目录:
- Mybatis的核心配置 :
- 一、MyBatis的 “核心对象”
- 1.1 SqlSessionFactory
- 1.2 SqlSession :
- SqlSession对象中的操作数据库的方法 :
- \
T selectOne ( String statement ) - \
T selectOne( String statement , Object parameter ) - \
List\ selectList ( String statement ) - \
List\ selectList ( String statement , Object parameter ) - \
List\ selectList ( String statement , Object parameter , RowBounds rowBounds ) - void select ( String statement , Object parameter , ResultHandler handler )
- int insert ( String statement )
- int insert ( String statement , Object parameter )
- int update( String statement )
- int update( String statement , Object parameter)
- int delete( String statement )
- int delete( String statement , Object parameter)
- int commit( )
- void rollback( )
- void close( )
- \
T getMapper( Class\ type ) - Connection getConnection( )
- \
- 使用工具类创建 “SqlSession” / SqlSession工具类
- 二、MyBatis的 “配置文件”
- “映射文件”中的 “主要元素”
- \
元素 - \
元素 - \
元素 - \
元素 - \
元素 - \
元素 - \
元素 - \
元素
- \
- 三、MyBatis的 “映射文件”
- “配置文件”中的 “主要元素”
- \
- \
元素 - \
元素和\ 元素 - \
元素 - \
元素 (可解决“属性名” 和 “字段名”不一样导致的数据无法映射成功的问题)
Mybatis的核心配置 :
一、MyBatis的 “核心对象”
- 在使用MyBatis框架时,主要涉及 两个核心对象 : SqlSessionFactory 和 SqlSession,它们在MyBatis框架中起着至关重要的作用。
1.1 SqlSessionFactory
SqlSessionFactory是MyBatis 框架中十分重要的对象,它是单个数据库映射关系经过编泽后的内存镜像,其主要作用是 创建SqlSession。
SqlSessionFactory 对象的实例可以通过 SqlSessionFactoryBuilder对象 来构建,而SqlSessionFactoryBuilder对象 则可以通过 XML配置文件 或一个预先定义好的 Configuration实例 构建出SqlSessionFactory的实例。
以下内容讲解的是 :就是 通过XML配置文件 构建出的SqlSessionFactory实例,其实现代码如下:
InputStream inputStream = Resources.getResourceAsStream("配置文件的位置"); //通过SqlSessionFactoryBuilder的 build()方法 + 配置文件来创建 SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory对象 是 线程安全 的,它一旦被创建,在整个应用执行期间都会存在。如果我们多次地创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。为了解决此问题,通常每一个数据库都会只对应一个 SqlSessionFactory, 所以在 构建SqlSessionFactory实例时,建议使用单列模式。
1.2 SqlSession :
SqlSession 是MyBatis 框架中另一个重要的对象, 它是 应用程序 与 持久层之间执行与操作的一个单线程对象,其主要作用是 执行持久化操作。
SqlSession对象包含数据库中所有执行SOL操作的方法 (SqlSession中有很多操作数据库的方法),由于其底层封装了JDBC连接,所以可以直接使用SqlSession实例来 执行已映射的SQL语句
(可用SqlSession来执行 “映射文件” 中的sql语句)。
每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例 是 线程不安全 的,因此 其使用范围 最好在 一次请求或一个方法 中,绝不能将其放在一个类的静态字段、实例字段 或 任何类型的管理范围 (如Servlet的HttpSession)中使用。
使用完SqlSession对象之后,要及时地关闭它,通常可以将其放在fnally块中关闭。
//通过 sqlSessionFactory对象获得"SqlSession" SqlSession sqlSession = sqlSessionFactory.openSession(); try{ //此处执行持久化操作 }finally{ sqlSession.close(); }
SqlSession对象中的操作数据库的方法 :
<T> T selectOne ( String statement )
<T> T selectOne ( String statement ) : 查询方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素 的 id 。
目的是 : 获得映射文件中的 “<select>元素下所代表的 sql语句 作为selectOne( )方法的参数 ”)。使用该方法后,会返回执行SQL语句查询结果的 一条泛型对象。
<T> T selectOne( String statement , Object parameter )
<T> T selectOne ( String statement, Object parameter ) :查询方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素 的 id 。 parameter是查询所需的 参数。使用该方法后,会返回执行SQL语句查询结果的 一条泛型对象。
<E> List<E> selectList ( String statement )
<E> List<E> selectList ( String statement ) : 查询方法 : 参数 statement 是在 “映射文件” 中定义的 <select>元素 的 id 。使用该方法后,会返回执行SQL语句查询结果的 泛型对象的集合。
<E> List<E> selectList ( String statement , Object parameter )
<E> List<E> selectList ( String statement , Object parameter ) : 查询方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素 的 id , parameter 是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的 泛型对象的集合。
<E> List<E> selectList ( String statement , Object parameter , RowBounds rowBounds )
<E> List<E> selectList ( String statement , Object parameter ) : 查询方法 : 参数==statement==是在 “ 映射文件” 中定义的 <select>元素 的 id , parameter 是查询所需的参数,rowBounds是用于分页的参数对象。使用该方法后会返回执行SQL语句查询结果的 泛型对象的集合。
void select ( String statement , Object parameter , ResultHandler handler )
void select ( String statement, Object parameter,ResultHandler handler ) : 查询方法 : 参数statement是在配置文件中定义的 <select>元素的id,parameter 是查询所需的 参数, ResultHandler对象用于处理查询返回的复杂结果集。 (通常用于多表查询)
int insert ( String statement )
int insert ( String statement ) : 插入方法 : 参数 statement是在 “映射文件” 中定义的 <select>元素 的 id ,使用该方法后,会返回执行 SQL语句所影响的行数。
int insert ( String statement , Object parameter )
int insert ( String statement , Object parameter ) : 插入方法 : 参数 statement 是在 “ 映射文件” 中定义的 <select>元素 的 id ,parameter 是查询所需的参数。使用该方法后,会返回执行 SQL语句所影响的行数。
int update( String statement )
int update ( String statement ) : 更新方法 : 参数 statement 是在 “ 映射文件” 中定义的 <update>元素 的 id ,使用该方法后,会返回执行 SQL语句所影响的行数。
int update( String statement , Object parameter)
int update ( String statement , Object parameter ) : 更新方法 : 参数 statement 是在 “ 映射文件” 中定义的 <update>元素 的 id ,parameter 是更新所需的参数。使用该方法后,会返回执行 SQL语句所影响的行数。
int delete( String statement )
int delete ( String statement ) : 删除方法 : 参数 statement 是在 “映射文件” 中定义的 <delete>元素 的 id ,使用该方法后,会返回执行 SQL语句所影响的行数。
int delete( String statement , Object parameter)
int delete ( String statement , Object parameter ) : 删除方法 : 参数 statement 是在 “ 映射文件” 中定义的 <delete>元素 的 id ,parameter 是删除所需的参数使用该方法后,会返回执行 SQL语句所影响的行数。
int commit( )
int commit ( ) : 提交事务 的方法。
void rollback( )
int rollback ( ) : 回滚事务 的方法。
void close( )
int close ( ) : 关闭SqlSession 对象。
<T> T getMapper( Class<T> type )
- <T> T getMapper ( Class<T> type ) : 该方法会返回 Mapper接口 的 代理对象,该对象关联了SqlSession对象,开发人员可以使用该对象直接调用方法操作数据库。参数type是Mapper的接口类型。MyBatis官方推荐通过
Mapper对象访问MyBatis。- 该方法 : getMapper( ) 的目的是根据传入的 类类型 :
type
返回一个与该类型匹配的对象。具体实现可能涉及反射机制,用于 创建并返回一个与传入类类型相匹配的实例。
Connection getConnection( )
Connection getConnection( ) : 获取 JDBC数据库连接对象 的方法。
使用工具类创建 “SqlSession” / SqlSession工具类
使用工具类创建 “SqlSession”对象 :
package com.myh.utils; 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 java.io.IOException; import java.io.InputStream; /** * 工具类 */ public class SqlSessionUtils { //获得SqlSession的"工具类" private static SqlSessionFactory sqlSessionFactory = null; //初始化 SqlSessionFactory 对象 static { //静态代码块 try { //使用Mybatis提供的Resources类加载mybatis-config.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); //构建SqlSessionFactory工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } /** * 获得SqlSession对象的静态方法 */ public static SqlSession getSession() { return sqlSessionFactory.openSession(); } }
这样,我们在使用时就 只创建了一个SqlSessionFactory 对象,并且可以通过工具类的 getSession( ) 方法, 来 获取SqlSession对象。
二、MyBatis的 “配置文件”
MyBatis的核心配置文件中,包含了很多影响MyBatis行为的重要信息。这些信息通常在一个项目中只会在一个配置文件中编写,并且编写后也不会轻易改动。
“映射文件”中的 “主要元素”
在 MyBatis 框架的 核心配置文件 (即 mybatis-config.xml )中,<configuration> 元素 是配置文件的 根元素,其他元素都要在 <configuration> 元素内配置。
Mybatis配置文件中 主要元素图 :(要熟悉 <configuration>元素各个子元素的配置。)
ps :
==<Cofgnaion>的子元素必须按照图中由上到下==的顺序进行配置,否则Mybatis在解新xml配置文件的时候会报错。
<properties>元素
- <properties>是一个配置属性的元素,该元素通常用于将内部的配置 “外在化”,即通过外部的配置来动态地替换内部定义的属性
(直接的使用 : 将外部的 Xxx.properties文件中的属性用于 mybatis配置文件中 )。
例如,数据库的连接等属性,就可以通过典型的 Java属性文件 ( .properties文件 )中的配置来替换。ps :
当我们在mybatis配置文件中 使用 <properties>元素导入 .properties文件时,即可在mybatis配置文件中,即直接使用 .properties文件中的数据 。db.properties
jdbc.driver = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/mybatis jdbc.username = root jdbc.password = root
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"> <configuration> <!-- properties属性 --> <!-- 通过properties属性引入 .properties配置文件, mybatis配置文件中则可直接使用 .properties中的数据,进行"动态替换" --> <properties resource="db.properties"/> <!-- environments属性 --> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!-- 通过“properties属性”来将 以下的driver、url、username、password 和 .properties配置文件 中的数据进行“动态替换” --> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> </configuration>
完成上述配置后,dataSource中连接数据库的4个属性 ( driver、url、usermame和password值将会由db.properties文件中对应的值来动态替换。这样就为配置提供了诸多灵活的选择。
除了可以像上述通过外部配置文件来定义属性值外,还可以通过配置 <properties>元素的子元素 <property>,以及通过方法参数传递的方式来获取属性值。由于使用properties配置文件来配置属性值可以方便地在多个配置文件中使用这些属性值,并且方便日后的维护和修改,所以在实际开发中,使用.properties文件来配置属性值是最常用的方式。
<settings>元素
<settings>元素主要用于改变MyBatis运行时的行为,例如 开启二级缓存、开启延迟加载 等。
虽然不配置<settings>元素,也可以正常运行MyBatis, 但是熟悉<settings>的配置内容以及它们的作用还是十分必要的。常见的**<settings>属性配置在 “配置文件” 中的使用** :
<settings> <setting name="cacheEnabled" value="true" /> <setting name="lazyLoadingEnabled" value="true" /> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false" /> <setting name="autoMappingBehavior" value="PARTIAL"/> ..... </settings>
<typeAliases>元素
<typeAliases>元素 用于为配置文件中的Java类型设置一个简短的名字,即 设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。 如 : 可用 <typeAliases>元素 为POJO类设置一个 “别名”。
<?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> <!-- 定义别名 --> <typeAliases> <!-- typeAlias元素 为 typeAliases元素的 "子元素" --> <typeAlias alias="user" type="com.myh.po.Customer"/> </typeAliases> </configuration>
上述示例中,<typeAliases> 元素的子元素 <typeAlias> 中的type属性用于指定需要被定义别名的类的全限定名; alias属性的属性值user 就是自定义的别名,它可以代替com.myh.po.Customer使用在MyBatis文件的任何位置。如果省略alias属性,MyBatis 会默认将类名首字母 小写后的名称作为别名。
当POJO类过多时,还可以通过自动扫描包 的 形式自定义别名 (此时以类名首字母小写后的名称为 “别名”),具体示例如下 :
<?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> <!-- 定义别名 --> <typeAliases> <!-- 使用自动扫描包来定义“别名” --> <!-- Mybatis会将所用 com.myh.po包中POJO类以首字母小写的名称 作为“别名” --> <!-- 如: Customer 的 默认设置的别名为: customer --> <package name="com.myh.po"/> </typeAliases> </configuration>
需要注意的是,上述方式的别名只适用于没有使用注解的情况。如果在程序中使用了注解,则别名为其注解的值, 具体如下 :
//使用注解来为该POJO类设置在 mybatis-config.xml配置文件中使用的 "别名" @Alias(value = "customer") public class Customer { ..... }
除了可以使用 <typeAliases>元素自定义别名外,MyBatis框架还默认为许多常见的Java类型(如数值、 字符串、日期和集合等 )提供了 相应的类型别名。(可使用时查询常见的Java类型的别名是什么)
<typeHandler>元素
MyBatis在 预处理语句( PreparedStatement )中 设置一个参数或者从结果集 ( ResultSet )中取出一个值 时,都会用其框架内部注册了的 typeHandler ( 类型处理器 ) 进行相关处理。
typeHandler的作用就是将预处理语句 中传入的参数从 javaType( Java类型) 转换为 jdbcType
( JDBC类型),或者从数据库取出结果时将 jdbcType 转换为 javaType。为了方便转换,Mybatis框架提供了一系列默认的类型处理器。
类型处理器 Java 类型 JDBC 类型 BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN ByteTypeHandler java.lang.Byte, byte 数据库兼容的 NUMERIC 或 BYTE ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERIC 或 SMALLINT IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGER LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERIC 或 BIGINT FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERIC 或 FLOAT DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLE BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMAL StringTypeHandler java.lang.String CHAR, VARCHAR ClobReaderTypeHandler java.io.Reader - ClobTypeHandler java.lang.String CLOB, LONGVARCHAR NStringTypeHandler java.lang.String NVARCHAR, NCHAR NClobTypeHandler java.lang.String NCLOB BlobInputStreamTypeHandler java.io.InputStream - ByteArrayTypeHandler byte[] 数据库兼容的字节流类型 BlobTypeHandler byte[] BLOB, LONGVARBINARY DateTypeHandler java.util.Date TIMESTAMP DateOnlyTypeHandler java.util.Date DATE TimeOnlyTypeHandler java.util.Date TIME SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP SqlDateTypeHandler java.sql.Date DATE SqlTimeTypeHandler java.sql.Time TIME ObjectTypeHandler Any OTHER 或未指定类型 EnumTypeHandler Enumeration Type VARCHAR 或任何兼容的字符串类型,用来存储枚举的名称(而不是索引序数值) EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERIC 或 DOUBLE 类型,用来存储枚举的序数值(而不是名称)。 SqlxmlTypeHandler java.lang.String SQLXML InstantTypeHandler java.time.Instant TIMESTAMP LocalDateTimeTypeHandler java.time.LocalDateTime TIMESTAMP LocalDateTypeHandler java.time.LocalDate DATE LocalTimeTypeHandler java.time.LocalTime TIME OffsetDateTimeTypeHandler java.time.OffsetDateTime TIMESTAMP OffsetTimeTypeHandler java.time.OffsetTime TIME ZonedDateTimeTypeHandler java.time.ZonedDateTime TIMESTAMP YearTypeHandler java.time.Year INTEGER MonthTypeHandler java.time.Month INTEGER YearMonthTypeHandler java.time.YearMonth VARCHAR 或 LONGVARCHAR JapaneseDateTypeHandler java.time.chrono.JapaneseDate DATE 当MyBatis框架所提供的 这些类型处理器不能够满足需求时,还可以通过自定义的方式对类型处理器进行扩展 ( 自定义类型处理器可以通过实现TypeHandler 接口 或者 继承 BaseTypeHandle类来定义)。
<typeHandler> 元素就是用于在配置文件中注册自定义的类型处理器的。它的使用方式有两种 :
① 注册一个类的类型处理器
②注册一个包中所有的类型处理器CustomertypeHandler.java
package com.myh.type; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class CustomertypeHandler implements TypeHandler { @Override public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { } @Override public Object getResult(ResultSet rs, String columnName) throws SQLException { return null; } @Override public Object getResult(ResultSet rs, int columnIndex) throws SQLException { return null; } @Override public Object getResult(CallableStatement cs, int columnIndex) throws SQLException { return null; } }
mybatis-config.xml
<!-- 注册一个类的类型处理器 --> <typeHandlers> <!-- 以单个类的形式配置 --> <typeHandler handler="com.myh.type.CustomertypeHandler"/> </typeHandlers> <!-- 注册一个包中所有类的类型处理器 --> <typeHandlers> <!-- 注册一个包中所有的typeHandler,系统在启动时会自动扫描包下的所有文件 --> <package name="com.myh.type"/> </typeHandlers>
<objectFactory>元素
MyBatis框架每次创建 结果对象的新实例 时,都会使用一个对象工厂( ObjectFactory )的实例来完成。MyBatis中默认的 ObjectFactory的作用 就是 实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。
在通常情况下, 我们使用默认的ObjectFactory即可,MyBatis 中默认的ObjectFactory是由org.apache.ibatis rflection.factory.DefaultObjectFactory来提供服务的。大部分场景下都不用配置和修改,但如果想覆盖ObjectFactory的默认行为,则可以通过自定义ObjectFactory来实现。
MyObjectFactory.java
package com.myh.objFactory; import org.apache.ibatis.reflection.factory.DefaultObjec