架构师修炼系列【MyBatis体系结构及配置】

本文介绍了MyBatis的持久化解决方案,将用户从原始JDBC访问中解放出来。详细阐述了MyBatis体系结构,包括SqlSessionFactory和SqlSession。还深入讲解了MyBatis配置文件结构,如properties属性、settings设置等,以及各部分的作用和配置方法。
部署运行你感兴趣的模型镜像

MyBatis的持久化解决方案将用户从原始的JDBC访问中解放出来, 用户只需要定义需要操作的SQL语句,无须关注底层的JDBC操作,就可以以面向对象的方式进行持久层操作。底层数据库连接的获取、数据 访问的实现、事务控制和数据库连接的关闭等都无须用户关心,从而将应用层从底层的JDBC/JTA API抽取出来。通过配置文件管理JDBC连接,让MyBatis完成持久化访问的实现。

MyBatis 体系结构

MyBatis中的常用对象有SqlSessionFactory和SqlSession

SqlSessionFactory

SqlSessionFactory是MyBatis的关键对象,它是单个数据库映射关系经过编译后的内存镜像SqlSessionFactory 对象的实例可以通过SqlSessionFactoryBuilder 对象来获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例
每一个MyBatis的应用程序都以一个 SqlSessionFactory对象的实例为核心。其也是线程安全的, SqlSessionFactory 一旦被创建,应该在应用执行期间都存在。在应用运 行期间不需要重复创建多次,建议使用单例模式。SqlSessionFactory是创建SqlSession的工厂

// SqlSessionFactory的常用方法
SqlSession openSession()// 创建SqlSession对象

SqlSession

SqlSession是MyBatis的关键对象,它是执行持久化操作的对象, 类似于JDBC中的Connection。它是应用程序与持久存储层之间执行交互操作的一个单线程对象,也是MyBatis执行持久化操作的关键对象。 SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法, 它的底层封装了JDBC连接,可以用SqlSession实例来直接执行已映射的SQL语句。每个线程都应该有它自己的SqlSession实例。SqlSession的实 例不能被共享,也是线程不安全的,绝对不能将 SqlSession 实例的引用 放在一个类的静态字段甚至是实例字段中。也绝不能将 SqlSession 实例 的引用放在任何类型的管理范围中,比如 Serlvet 当中的 HttpSession 对 象中。使用完SqlSession之后关闭 Session很重要,应该确保使用finally 块来关闭它。

SqlSession的常用方法如下

// 插入方法,参数statement是在配置文件中定义的<insert.../>元素的id,返回执行SQL语句所影响的行数
int insert(String statement)
// 插入方法,参数statement是在配置文件中定义的<insert.../>元素的id,parameter是插 入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数
int insert(String statement, Object parameter)
// 更新方法,参数 statement 是在配 置文件中定义的<update.../>元素的id,返回执行SQL语句所影响的行数
int update(String statement)
// 更新方法, 参数statement是在配置文件中定义的<update.../>元素的id,parameter 是插入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数
int update(String statement, Object parameter)
// 删除方法,参数statement是在配置 文件中定义的<delete.../>元素的id。返回执行SQL语句所影响的行数
int delete(String statement)
// 删除方法,参 数statement是在配置文件中定义的<delete.../>元素的id,parameter是插 入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数
int delete(String statement, Object parameter)


// 查询方法,参数statement 是在配置文件中定义的<select.../>元素的 id。返回执行 SQL语句查询 结果的泛型对象,通常查询结果只有一条数据时才使用
<T> T selectOne(String statement) 
// 查询 方法,参数statement是在配置文件中定义的<select.../>元素的 id, parameter 是查询所需的参数,通常是对象或者Map,返回执行SQL语句 查询结果的泛型对象,通常查询结果只有一条数据时才使用
<T> T selectOne(String statement, Object parameter)
//查询方法,参数 是在配置文件中定义的<select.../>元素的id,返回执行SQL语句查询结 果的泛型对象的集合
<E> List<E> selectList(String statement) 
//查询方法,参数statement是在配置文件中定义的<select.../>元素的 id,parameter 是查询所需的参数,通常是对象或者 Map,返回执行SQL语句查询结果的泛型对象的集合
<E>List<E>selectList(String statement, Object parameter) 
// 查询方法,参数statement是在配置文件中 定义的<select.../>元素的id,parameter是查询所需的参数,通常是对象 或者Map。RowBounds对象用于分页,它的两个属性:offset指查询的当 前页数;limit指当前页显示多少条数据。返回执行SQL语句查询结果的泛型对象的集合
<E>List<E>selectList(String statement, Object parameter, RowBounds rowBounds) 
// 查询方法,参数statement是在配置文件中定义的<select.../>元素的id,mapKey是返回数据的其中一个列名,执行 SQL 语句查询 的结果将会被封装成一个 Map 集合返回,key 就是参数mapKey传入的 列名,value是封装的对象
<K, V> Map<K,V> selectMap(String statement, String mapKey)
// 查询方法,参数statement是在配置文件中定义的<select.../>元素的id,parameter是查询所需的参数,通常是对 象或者Map,mapKey是返回数据的其中一个列名,执行SQL语句查询的 结果将会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value是封装的对象
<K, V>Map<K, V>selectMap(String statement, Object parameter, String mapKey)
// 查询方法, 参数statement是在配置文件中定义的<select.../>元素的id,parameter是查询所需的参数,通常是对象或者Map,mapKey是返回数据的其中一个列名,RowBounds对象用于分页。执行SQL语句查询的结果将会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value是封装的对象
<K, V>Map<K,V>selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds)
// 查询方法,参数statement是在配置文件中定义的<select.../>元素的id, ResultHandler对象用来处理查询返回的复杂结果集,通常用于多表查询
void select(String statement, ResultHandler handler)
// 查询方法,参数statement是在配置文件中定义的<select.../>元素的id,parameter是查询所需的参数,通常是对象或者Map,ResultHandler对象用来处理查询返回的复杂结果集,通常用于多表查询
void select(String statement,Object parameter,ResultHandler handler)
// 查询方法,参数statement是在配置文件中定义的<select.../>元素的id,parameter是查询所需的参数,通常是对象或者Map,RowBounds对象用于分页,ResultHandler对 象用来处理查询返回的复杂结果集,通常用于多表查询
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) 
// 提交事务
void commit()
// 回滚事务
void rollback()
// 关闭SqlSession对象
void close()
// 获得JDBC的数据库连接对象。 <T> T getMapper(Class<T> type)。 返回mapper接口的代理对象,该对象关联了SqlSession对象,开发者可以通过该对象直接调用方法操作数据库,参数type是Mapper的接口类型。MyBatis官方手册建 议通过mapper对象访问MyBatis。
Connection getConnection()

在实际应用中很少会直接使用DriverManager来获取数据库连接,通常都会使用DataSource来获取数据库连接,SqlSessionFactory底层封装了 DataSource

深入MyBatis的配置文件

MyBatis的持久化操作离不开 SqlSessionFactory对象,这个对象是整个数据库映射关系经过编译后的 内存镜像,该对象的openSession()方法可以打开SqlSession对象。该对象由SqlSessionFactoryBuilder加载MyBatis的配置文件产生

// 读取mybatis-config.xml文件
InputStream inputStream = Resouces.getResourceAsStream("mybatis-config.xml");
// 初始化MyBatis, 创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建Session实例
SqlSession session = sqlSessionFactory.openSession();

根据配置文件mybatis-config.xml,创建 SqlSessionFactory对象,然后产生SqlSession,执行SQL语句,而SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)是怎样的一个过程?SqlSessionFactoryBuilder 根据传入的输入流生成Configuration 对象,然后根据Configuration对象创建默认的SqlSessionFactory实例

  • 调用SqlSessionFactoryBuilder对象的build(inputStream)方法
  • SqlSessionFactoryBuilder会根据输入流inputStream等信息创建 XMLConfigBuilder对象
  • SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法
  • XMLConfigBuilder对象解析XML配置文件返回Configuration对象
  • SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory 对象
  • SqlSessionFactoryBuilder返回DefaultSessionFactory对象给客户端,供客户端使用

由此可见,SqlSessionFactory是根据MyBatis的配置文件mybatis-config.xml创建的

在这里插入图片描述

MyBatis的配置文件结构

MyBatis的配置文件包含了影响MyBatis行为的信息:

  • 顶层configuration 配置
  • properties 属性
  • settings 设置
  • typeAliases 类型命名
  • typeHandlers 类型处理器
  • objectFactory 对象工厂
  • plugins 插件
  • environments 环境
  • environment 环境变量
  • transactionManager 事务管理器
  • dataSource 数据源
  • databaseIdProvider 数据库厂商标识
  • mappers 映射器
properties属性

这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过properties元素的子元素来传递,可以在CLASSPATH中增加一个db.properties的Java属性文件

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/mybatis
username=root
password=root

在配置文件中配置<properties…/>属性 <properties resource="db.properties"/>
其中的属性就可以在整个配置文件中使用来替换需要动态配置的属性值

<dataSource type="POOLED">
<property name="driver" value = "${driver}"/>
<property name="url" value = "${url}"/>
<property name="username" value = "${username}"/>
<property name="password" value = "${password}"/>
</dataSource>

driver、url、username和password 属性将会由db.properties文件中对 应的值来替换。这样就为配置提供了诸多灵活选择

settings设置

settings设置是MyBatis中极为重要的调整设置,它会改变MyBatis的运行时行为,如下表描述了设置中各项的参数、默认值等等

设置参数描述有效值默认值
cacheEnabled该配置影响所有映射器中配置的缓存的全局开关```truefalse```
lazyLoadingEnabled延迟加载的全局开关,当开启时,所有关联对象都会延迟加载,特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态```truefalse```
aggressiveLazyLoading当启动时,对任意延迟属性的调用会使带有延迟加载属性的对象完全加载,反之每种属性将会按需加载```truefalse```
multipleResultSetsEnabled是否允许单一语句返回多结果集(需要兼容驱动)```truefalse```
useColumnLabel使用列标签代替列名,不同的驱动会有不同的表现```truefalse```
useGeneratedKeys允许JDBC支持自动生成主键,需要驱动兼容,如果设置为true则这个设置强制使用自动生成的主键```truefalse```
autoMappingBehavior指定MyBatis应如何自动映射列到字段或属性,NONE标识取消自动映射,PARTIAL只会自动映射没有定义嵌套结果集映射的结果集,FULL会自动映射任意复杂的结果集(无论是否嵌套)```NONEPARTIAL
autoMappingUnknownColumnBehaviorNONE:什么都不干,WARNING:输出警告,FAILING:映射失败抛出SqlSessionException```NONEWARNING
defaultExecutorType配置默认的执行器,SIMPLE就是普通的执行器,REUSE执行器会重用预处理语句(prepared statements),BATCH执行器将重用语句并执行批量更新```SIMPLEREUSE
defaultStatementTimeout设置超时时间,它决定驱动等待数据库响应的秒数integer没有设置(null)
defaultFetchSize默认返回的结果集大小integer没有设置(null)
safeRowBoundsEnabled允许在嵌套语句中使用分页(RowBounds)```turefalse```
mapUnderscoreToCamelCase是否开启自动驼峰命名规则(camelcase)映射```truefalse```
localCacheScopeMyBatis利用本地缓存机制(LocalCache)防止循环引用(circular references)和加速重复嵌套查询,SESSION这种情况下会缓存一个会话中执行的所有查询,若设置为STATEMENT则本地会话仅用在语句执行上,对相同的SqlSession的不同调用将不会共享数据```SESSIONSTATEMENT```
jdbcTyepForNull当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型,某些驱动需要指定列的JDBC类型,多数情况下直接使用一般类型即可,比如NULL、VARCHAR或OTHER```NULLVARCHAR
lazyLoadTriggerMethods指定哪个对象的方法触发一次延迟加载方法名的list集合equals,clone,hashCode,toString
defaultScriptingLanguage指定动态SQL生成的默认语言一个类型别名或完全限定类名org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver
callSettersOnNulls指定当结果集中值为null时是否调用映射对象的setter(map对象时为put)方法,这对于有Map.keySet()依赖或null值初始化时是有用的,注意基本类型(int、boolean等)不能设置为null```truefalse```
logPrefix指定MyBatis增加到日志名称的前缀String没有设置(null)
logImpl指定MyBatis所用日志的具体实现,未指定时将自动查找```SLF4JLOG4J
proxyFactory指定MyBatis创建具有延迟加载能力的对象所用到的代理工具```CGLIBJAVASSIST```
配置实例
<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"/>
	<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
	<setting name="defaultExecutorType" value="SIMPLE"/>
	<setting name="defaultStatementTimeout" value="25"/>
	<setting name="defaultFetchSize" value="100"/>
	<setting name="safeRowBoundsEnabled" value="false"/>
	<setting name="mapUnderscoreToCamelCase" value="false"/>
	<setting name="localCacheScope" value="SESSION"/>
	<setting name="jdbcTypeForNull" value="OTHER"/>
	<setting name="lazyLoadTriggerMethods" value="equals,close,hashCode,toString"/>
</settings>
typeAliases类型命名

类型别名是为Java类型设置的一个短的名字,它只和XML配置有关,存在的意义仅在于用来减少类完全限定名的冗余

<typeAliases>
	<typeAlias alias="user" type="org.davieyang.domain.User">
</typeAliases>	

当这样配置时,user可以用在任何使用org.davieyang.domain.User的地方,也可以指定一个包名,MyBatis会在包名下面搜索需要的JavaBean

<typeAliases>
	<package name="org.davieyang.domain">
</typeAliases>

每一个在包org.davieyang.domain中的JavaBean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名。比如 org.davieyang.domain.User的别名为user;若有注解,则别名为其注解值

@Alias("user")
public class User{
	...
}

MyBatis已经为许多常见的Java类型内建了相应的类型别名,它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator
typeHandlers类型处理器

无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合 适的方式转换成Java 类型,如下表描述了一些默认的类型处理器

类型处理器Java类型JDBC类型
BooleanTypeHandlerjava.lang.Boolean, boolean数据库兼容的BOOLEAN
ByteTypeHandlerjava.lang.Byte, byte数据库兼容的NUMERIC或BYTE
ShortTypeHandlerjava.lang.Short, short数据库兼容的NUMERIC或SHORT INTEGER
IntegerTypeHandlerjava.langInteger, int数据库兼容的NUMERIC或INTEGER
LongTypeHandlerjava.lang.Long, long数据库兼容的NUMERIC或LONG INTEGER
FloatTypeHandlerjava.lang.Float, float数据库兼容的NUMERIC或FLOAT
DoubleTypeHandlerjava.langDouble, double数据库兼容的NUMERIC或DOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal数据库兼容的NUMERIC或DECIMAL
StringTypeHandlerjava.lang.StringCHAR、VARCHAR
ClobReaderTypeHandlerjava.io.Reader
ClobTypeHandlerjava.lang.StringCLOB、LONGVARCHAR
NStringTypeHandlerjava.lang.StringNVARCHAR、NCHAR
NClobTypeHandlerjava.lang.StringNCLOB
BlobInputStreamTypeHandlerjava.io.InputStream
ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型
BlobTypeHandlerbyte[]BLOG,LONGVARBINARY
DateTypeHandlerjava.util.DateTIMESTAMP
DateOnlyTypeHandlerjava.util.DateDATE
TimeOnlyTypeHandlerjava.util.DateTIME
SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
SqlDateTypeHandlerjava.sql.DateDATE
SqlTimeTypeHandlerjava.sql.TimeTIME
ObjectTypeHandlerAnyOTHER或未指定类型
EnumTypeHandlerEnumeration TypeVARCHAR,任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandlerEnumerationType任何兼容的NUMERIC或DOUBLE类型,存储枚举的索引(而不是名称)
objectFactory对象工厂

MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建 自己的对象工厂来实现.

// 自定义对象工厂
public class ExampleObjectFactory extends DefaultObjectFactory{
	public Object create(Class type){
		return super.create(type);
	}
	public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs){
		return super,create(type, constructorArgTypes, constructorArgs);
	}
	public void setProperties(Properties properties){
		super.setProperties(properties);
	}
	public <T> boolean isCollection(Class<T> type){
		return Collection.class.isAssignableFrom(type);
	}
}

在MyBatis配置文件中配置自定义对象工厂

<objectFactory type="org.davieyang.factory.ExampleObjectFactory">
	<property name="someProperty" value="100">
</objectFactory>

ObjectFactory接口很简单,它包含两个创建方法:一个是处理默认 构造方法的;另外一个是处理带参数的构造方法的。最后,setProperties方法可以被用来配置ObjectFactory,在初始化ObjectFactory实例后, objectFactory元素体中定义的属性会被传递给setProperties方法

environments配置环境

MyBatis的环境配置实际就是数据源的配置。MyBatis可以配置多种 环境,这种机制使得MyBatis可以将 SQL 映射应用于多种数据库中。例如,开发、测试和生产环境需要有不同的配置;多个生产数据库想使用 相同的SQL映射等等

尽管可以配置多个环境,但是每个 SqlSessionFactory 实例只能选择一个环境,即每个数据库对应一个 SqlSessionFactory 实例。所以,如果 你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数 据库对应一个。而如果是三个数据库,就需要三个实例,依此类推

环境配置如下

<environments default="development">
  <environment id="development">
	<transactionManager type="JDBC">
		<property name="..." value="..."/>
	</transactionManager>
	<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>

注意这里的关键点:

默认的环境id(比如,default=”development“),每个environment 元素定义的环境id(比如,id=“development”)、事务管理器的配置(比如,type=”JDBC“)、数据源的配置(比如,type=“POOLED”) ,其中环境id可以随意命名,建议简洁有意义,而默认环境一定要匹配定义的其中一个环境id


<transactionManager…/>表示事务管理器配置,在 MyBatis 中有JDBC 和 MANAGED 两种类型的事务管理器:

  • JDBC:这个配置直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围
  • MANAGED:这个配置几乎没做什么,它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如Java EE应用服务器的上下文),默认情况下它会关闭连接,然而一些容器并不希望这样,可以将closeConnection属性设置为false来阻止它默认的关闭行为,transactionManager的MANAGED配置示例如下
   <transactionManager type="MANAGED">
   		<property name="closeConnection" value="false"/>
   	</transactionManager>

如果开发者使用Spring+MyBatis,则没有必要配置事务管理器,因为Spring模块会使用自带的管理器来覆盖MyBatis的事务管理器配置<dataSource…/>表示数据源配置,在 MyBatis 中有UNPOOLED、 POOLED和JNDI三种数据源类型:

  • UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连 接。它对没有性能要求的简单应用程序是一个很好的选择。不同的数据 库在这方面表现也是不一样的。UNPOOLED 类型的数据源仅仅需要配 置以下5种属性:

    • driver:这是 JDBC 驱动的 Java 类的完全限定名(并不是JDBC驱 动中可能包含的数据源类)
    • url:这是数据库的JDBC URL地址
    • username:登录数据库的用户名
    • password:登录数据库的密码
    • defaultTransactionIsolationLevel:默认的连接事务隔离级别
  • POOLED: 这种数据源的实现利用“池”的概念将JDBC连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。这是 一种使得并发Web应用快速响应请求的流行处理方式。除了上述提到的 UNPOOLED的5种属性外,还可以使用更多属性来配置 POOLED 的数据源:

    • poolMaximumActiveConnections:在任意时间可以存在的活动(也就是正在使用)连接数量,默认值是10
    • poolMaximumIdleConnections:任意时间可能存在的空闲连接
      数。
    • poolMaximumCheckoutTime:在被强制返回之前,池中连接被 检出(checked out)时间,默认值为20000 ms(即20 s)
    • poolTimeToWait:这是一个底层设置,如果获取连接花费相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静地失败),默认值为20000ms(即20s)
    • poolPingQuery。 发送到数据库的侦测查询,用来检验连接是否
      处在正常工作秩序中并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
    • poolPingEnabled。 是否启用侦测查询。若开启,也必须使用一个 可执行的SQL语句设置 poolPingQuery 属性(最好是一个非常快的SQL),默认值为false
    • poolPingConnectionsNotUsedFor:配置poolPingQuery的使用频度,其可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值为0(即所有连接每一时刻都被侦测,当然仅当poolPingEnabled为true时适用)

• JNDI。 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。这种数据源配置只需要两个属性:

  • initial_context:这个属性用来在InitialContext中寻找上下文(即initialContext.lookup(initial_context))这是个可选属性,如果忽略,那么data_source属性将会直接从InitialContext 中寻找
  • data_source:这是引用数据源实例位置的上下文路径。若提供了 initial_context配置则会在其返回的上下文中进行查找,没有提供则直接在 InitialContext中查找。dataSource的JDNI配置示例如下:
<dataSource type="JNDI">
	<property name="initial_context" value="java:/comp/env"/>
	<property name="data_source" value="davieyangjavads"/>
</dataSource>

其中“java:/comp/env”是Tomcat服务器的前缀,每个Web服务器的 前缀都不一样,具体请查看Web服务器相关文档

mapper映射器

MyBatis需要开发者自己写SQL语句,mapper映射器告诉 MyBatis 到哪里去找映射文件,进而找到这些SQL语句。在实际开发中可以使用相对于类路径的资源引用或完全限定资源定位符(包括 file:///的 URL),以及类名和包名等,例如

<!--使用类路径查找资源文件-->
<mappers>
	<mapper resource="org/davieyang/mapper/UserMapper.xml"/>
</mappers>
<!--使用本地文件-->
<mappers>
	<mapper url="file:///c:/mapper/UserMapper.xml"/>
</mappers>
<!--使用接口类-->
<mappers>
	<mapper class="org.davieyang.mapper.UserMapper"/>
</mappers>

mapper映射器会告诉MyBatis去哪里找映射文件,剩下的细节就是 每个SQL映射文件了

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Davieyang.D.Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值