当前位置: 首页 > news >正文

电脑网站制作教程网络公司做网站赚钱码

电脑网站制作教程,网络公司做网站赚钱码,哪个网站做译员好,9377霸主传奇网页版1、全局配置文件 前面我们看到的Mybatis全局文件并没有全部列举出来#xff0c;所以这一章我们来详细的介绍一遍#xff0c;Mybatis的全局配置文件并不是很复杂#xff0c;它的所有元素和代码如下所示#xff1a; ?xml version1.0 encodingUTF-8所以这一章我们来详细的介绍一遍Mybatis的全局配置文件并不是很复杂它的所有元素和代码如下所示 ?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtdconfiguration !--配置--properties/ !--属性--settings/ !--全局配置参数--typeAliases/ !--类型别名--typeHandlers/ !--类型处理器--objectFactory/!--对象工厂--plugins/!--创建--environments default!--环境配置--environment id!--环境变量--transactionManager type/!--事务管理器--dataSource type/!--数据源--/environment/environmentsdatabaseIdProvider type/!--数据库厂商标识--mappers/!--映射器-- /configuration 注意Mybatis的配置文件的顺序是严格按照从上至下的顺序声明不颠倒顺序如果颠倒了它们的顺序那么Mybatis在启动阶段就会产生异常导致程序无法运行 2、properties属性 properties 的作用是引用java属性文件中的配置信息比如加载连接数据库的各种属性的配置文件。 mybatis提供了三种方式使用properties属性 property子元素不推荐就是在properties属性中增加子属性property从而设置一些配置的key-value。properties文件就是直接使用properties引入外部配置文件相当于将子属性抽取成一个独立的外部文件引入例如db.properties。程序代码传递参数就是通过代码的方式设置该配置相关的信息如数据库配置文件中的用户名和密码一般是密文但是连接数据库时需要对配置进行解密此时就只能通过程序代码的方式配置了。 2.1、property子元素不推荐 以上一章的例子为基础使用property子元素将数据库的连接配置信息进行改写如下所示 ?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtdconfigurationproperties!--property子元素定义--property namedatabase.driver valuecom.mysql.cj.jdbc.Driver/property namedatabase.url valuejdbc:mysql://localhost:3306/user?serverTimezoneGMT%2B8useUnicodetruecharacterEncodingutf-8/property namedatabase.username valueroot/property namedatabase.password valueroot//propertiesenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/transactionManagerdataSource typePOOLED!--配置连接数据库的4个基本信息--property namedriver value${database.driver}/property nameurl value${database.url}/property nameusername value${database.username}/property namepassword value${database.password}//dataSource/environment/environments /configuration 这种配置方式时有缺点的虽然这样定义一次可以到处引用但是如果配置项很多那么就会让配置文件显得很庞大所以使用这种方式显然不是一个很好的选择为了解决这个缺点我们可以使用下面的配置方式也就是使用properties文件的方式。 2.2、properties文件 使用properties文件的方式在我们的开发中是比较常用主要的这种方式简单方便日后的维护和修改。首先将上述配置中的所有property属性提取到一个叫做 databse.properties 的配置文件中 如下代码所示 #数据库连接配置 database.drivercom.mysql.cj.jdbc.Driver database.urljdbc:mysql://localhost:3306/user?serverTimezoneGMT%2B8useUnicodetruecharacterEncodingutf-8 database.usernameroot database.passwordroot 然后在Mybatis配置文件中使用元素的resource属性来引入properties文件。 properties resourcedatabase.properties /这样就相当于将 database.properties 中的所有配置都加载到MyBatis的配置文件中了然后再按照 ${database.username} 的方式引入properties文件的属性参数即可。但是这种使用方式也存在它的缺点当外部配置文件中的值需要加密时如连接数据库的用户名和密码无法在配置文件中进行解密所以只能通过程序代码传递的方式就是要介绍的第三种如下。 2.3、程序代码传递参数 在真实的开发环境中数据库的用户名和密码对开发人员和其他人员是保密的。而运维人员为了数据保密一般都会把数据库的用户名和密码进行加密处理会把加密后的数据配置到properties文件中。所以开发人员就必须用解密后的用户名和密码连接数据库不可能用加密的数据进行连接。此时就需要使用到此种方式来对配置文件进行解密。其实这种方式一般会和第二种配合使用作用对特殊配置进行覆盖或重写以上面的database.properties为例在使用到数据库配置信息时对配置中的用户名和密码进行解密。这里举个MyBatis中获取SqlSessionFactory的例子代码如下 public static SqlSessionFactory getSqlSessionFactoryByXml() {synchronized (Lock) {if (null ! sqlSessionFactory) {return sqlSessionFactory;}String resource mybatis-config.xml;InputStream inputStream;InputStream is null;try {// 加载数据库配置文件is Resources.getResourceAsStream(database.properties);Properties properties new Properties();properties.load(is);// 获取加密信息String username properties.getProperty(database.username);String password properties.getProperty(database.password);// 解密用户名和密码并重置属性properties.setProperty(database.username, CyperTool.decodeByBase64(username));properties.setProperty(database.password, CyperTool.decodeByBase64(password));// 读取mybatis配置文件inputStream Resources.getResourceAsStream(resource);// 通过SqlSessionFactoryBuilder类的builder方法进行构建并使用程序传递的方式覆盖原有属性sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream, properties);} catch (IOException e) {e.printStackTrace();return null;}return sqlSessionFactory;}}我们为了保证数据的准确性加了synchronized锁。首先使用Resources对象读取了database.properties配置文件然后获取了它原来配置的用户和密码进行解密操作最后使用SqlSessionFactoryBuilder的build方法传递多个properties参数来完成。这将覆盖之前加密的配置这样就可以连接数据库了同时也能满足因为人员对数据库的用户名和密码的安全要求。 3、settings属性 settings是MyBatis中最复杂的配置它能深刻影响MyBatis底层的运行但是大部分情况下使用默认值便可以运行所以在大部分情况下不需要大量配置只需要修改一些常用的规则即可。常用规则有自动映射、驼峰命名映射、级联规则、是否启动缓存、执行器类型等。 所有配置可参考MyBatis官方文档https://mybatis.org/mybatis-3/zh/configuration.html#settings。可以看到settings的配置项非常之多但是我们真正使用的并不会太多我们只需把常用的搞清楚就可以了。比如关于缓存的CacheEnabled关于级联的lazyLoadingEnabled和aggressiveLazyLoading关于自动映射的autoMappingBehavior和mapUnderscoreToCamelCase关于执行器类型的defaultExecutorType等。本文列出重要的几个配置项及意义并挑几个常用配置加以说明 settings!--缓存配置的全局开关如果这里设置成false那么即便在映射器中配置开启也无济于事 --setting namecacheEnabled valuetrue /!--延时加载的全局开关 --setting namelazyLoadingEnabled valuefalse /!-- 是否允许单一语句返回多结果集 --setting namemultipleResultSetsEnabled valuetrue /!-- 使用列标签代替列名需要兼容驱动 --setting nameuseColumnLabel valuetrue /!-- 允许JDBC自动生成主键需要驱动兼容。如果设置为true则这个设置强制使用自动生成主键尽管一些驱动不能兼容但仍能正常工作 --setting nameuseGeneratedKeys valuefalse /!-- 指定MyBatis该如何自动映射列到字段或属性NONE表示取消自动映射PARTIAL表示只会自动映射没有定义嵌套结果集和映射结果集FULL会自动映射任意复杂的结果集无论是否嵌套 --setting nameautoMappingBehavior valuePARTIAL /!-- 指定发现自动映射目标未知列或未知属性类型的行为。NONE: 不做任何反应WARNING: 输出警告日志FAILING: 映射失败 (抛出 SqlSessionException) --setting nameautoMappingUnknownColumnBehavior valueWARNING /!-- 配置默认的执行器SIMPLE是普通的执行器REUSE会重用预处理语句BATCH会重用语句并执行批量更新 --setting namedefaultExecutorType valueSIMPLE /!--设置超时时间它决定驱动等待数据库响应的秒数,任何正整数--setting namedefaultStatementTimeout value25/!--设置数据库驱动程序默认返回的条数限制此参数可以重新设置,任何正整数 --setting namedefaultFetchSize value100 /!-- 允许在嵌套语句中使用分页RowBounds --setting namesafeRowBoundsEnabled valuefalse /!-- 是否开启自动驼峰命名规则即从a_example到aExample的映射 --setting namemapUnderscoreToCamelCase valuetrue /!-- 本地缓存机制防止循环引用和加速重复嵌套循环 --setting namelocalCacheScope valueSESSION /!-- 当没有为参数提供特定JDBC类型时为空值指定JDBC类型。某些驱动需要指定列的JDBC类型多数情况直接用一般类型即可如NULL/VARCHAR/OTHER --setting namejdbcTypeForNull valueOTHER /!-- 指定触发延迟加载的方法如equals/clone/hashCode/toString --setting namelazyLoadTriggerMethods valueequals / /settings4、typeAlianses属性 typeAlianses属性就是起个别名是为了在映射文件中更方便的编写输入参数类型和输出结果类型因为平时的输入输出映射的全限定名显得很长在使用过程中不是很方便所以MyBatis中允许我们使用一种简写的方式来代替全限定名这样可以提高我们的开发效率。 别名分为系统别名和自定义别名系统别名就是系统默认给我们起的别名例如我们在输入一个数值型的参数是可以直接写parameterType”int”这是因为系统将Integer的Java类型起的别名为int。我们可以通过Mybatis的官方文档来查看https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases。而自定义别名是自己定义的名称后面会介绍如何使用。 4.1、系统定义的别名 Mybatis本身给我们定义了大量的别名包括有基本数据类型包装类、对象型、集合和Map等等。系统定义的别名是通过TypeAliasRegistry类来定义的所以我们既可以通过这个对象获取系统中已经定义好的别名也能自定义别名先通过一段代码来获取系统中都预定义了哪些别名。 /*** 获取系统别名配置*/ public static void getTypeAlias() {try {InputStream stream getResourceAsStream(mybatis-config.xml);SqlSessionFactory factory new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession factory.openSession();//获取TypeAliasRegistry对象TypeAliasRegistry typeAliasRegistry sqlSession.getConfiguration().getTypeAliasRegistry();MapString, Class? tarMap typeAliasRegistry.getTypeAliases();int i 0;for (String key : tarMap.keySet()) {//这个i统计数量System.out.println(i*****tarMap.get(key).getSimpleName()*****key);}System.out.println(系统定义的别名个数为i);} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {getTypeAlias(); }输出结果就不贴出来了有点长可以自行运行。通过运行结果可以发现系统自定义的别名一共有72个这72个别名的使用不区分大小写。所以我们可以使用别名代替冗长的全限定名比如在MyBatis的映射文件中我们设置一个SQL语句的参数类型或返回类型的时候如果这个类型是字符串我们完全可以用string代替java.lang.String。但是这就会有一个问题我怎么知道哪个类型的别名是什么呢在不知道的情况下有两种方式可以知道 保险的方法将系统别名打印出来或者找官方文档查询 寻规律其实从上面的结果可以发现一个规律就是如果类名以大写开头则只要将大写变为小写就是该类的别名而如果类名本来就是小写只需要在小写前面加上下划线即可。 4.2、自定义别名 我们在平时的开发中系统中会有大量的类比如User类需要对其进行反复的使用而这些类系统并没有给我们取别名难道我们要反复的编写很长的全限定名吗NOMybatis给我们提供了用户自定义别名的规则我们可以通过配置文件、包扫描或者注解进行注册。下面来介绍一下如何使用 ①、使用配置文件的typeAliases属性 !--配置别名-- typeAliases!--对类单独进行别名设置 --typeAlias aliasuser typecom.thr.pojo.User/typeAliastypeAlias aliasstudent typecom.thr.pojo.Student/typeAlias /typeAliases这样我们就为两个类定义好了别名但是这种方式有个缺点如果多个类需要配置别名时就显得很麻烦所以这种方式显然不行。 ②、通过package自动扫描 !--配置别名-- typeAliases!-- 对包进行扫描可以批量进行别名设置设置规则是获取类名称将其第一个字母变为小写 --package namecom.thr.pojo1/package namecom.thr.pojo2/package namecom.thr.pojo3/ /typeAliases这种方式会为扫描到的包下的所有类起一个别名别名的命名规则为将类名的第一个字母变为小写作为别名比如com.thr.pojo.User变为别名为user。但是使用这种方式还有缺点就是如果两个不同的包下出现了同名的类那么在扫描的时候就会出现异常通常不会出现这种情况。这个时候可以通过注解Alians(“user1”)来进行区分。 ③、通过注解 这种方式比较简单只要在对应包下的对应类上面使用注解Alias(别名)即可如下package com.thr.pojo; import org.apache.ibatis.type.Alias;Alias(user) public class User {省略...... } 这样就能够避免因为避免重复而导致扫描失败的问题。 5、typeHandlers属性了解 typeHandlers叫类型处理器在JDBC中需要在PreparedStatement中设置预编译SQL所需的参数。在执行SQL后会根据结果集ResultSet对象得到数据库的数据需要将数据库中的类型和java中字段的类型进行转换一样这些操作在MyBatis中通过typeHandler来实现。在typeHandler中包含有javaType和jdbcType两种类型其中javaType用来定义Java类型jdbcType用来定义数据库类型那么typeHandler的作用就是承担javaType和jdbcType两种类型的转换如下图所示。 MyBatis中的typeHandlers存在系统定义的和自定义两种MyBatis会根据javaType和jdbcType来决定采用哪个typeHandler来处理这些转换规则而且系统定义的能满足大部分需求但是有些情况是不够用的比如我们的特殊转换规则枚举类型这时我们就需要自定义的typeHandlers了。下面分别介绍这两种typeHandler的使用。 5.1、系统定义的typeHandler Mybatis内部定义了许多有用的typeHandler我们可以参考Mybatis的官方文档查看https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers也可以自己通过程序代码进行打印代码如下 /*** 获取类型处理器*/ public static void getTypeHandlers() {//SqlSession代码省略......TypeHandlerRegistry typeHandlerRegistry sqlSession.getConfiguration().getTypeHandlerRegistry();CollectionTypeHandler? handlers typeHandlerRegistry.getTypeHandlers();System.out.println(handlers.size());int i 0;for (TypeHandler? typeHandler : handlers) {System.out.println(i*****typeHandler.getClass().getName());} }执行结果就不列出来了Mybatis一共定义了39个类型处理器。在大部分情况下我们不需要显示的声明JavaType和jdbcType因为Mybatis会自动探测到。 在Mybatis中typeHandler都需要实现接口org.apache.ibatis.type.TypeHandler所以我们来看看这个接口长啥样。源代码如下 public interface TypeHandlerT {void setParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;T getResult(ResultSet var1, String var2) throws SQLException;T getResult(ResultSet var1, int var2) throws SQLException;T getResult(CallableStatement var1, int var2) throws SQLException; }简单介绍一下内部定义了内容 其中T表示泛型专指JavaType比如我们需要String类型的参数那么实现类就是可以写成implement TypeHandler。 setParameter方法是使用typeHandler通过PreparedStatement对象进行设置SQL参数的时候使用的具体方法其中i是请查收在SQL的下标parameter是参数jdbcType为数据库类型。 其中三个getResult的方法它的作用是从JDBC结果集中获取数据进行转换要么使用列名要么使用下标来获取数据库的数据其中最后一个方法是存储过程专用的方法。 既然学习了TypeHandler接口那么接着来学习它的实现了BaseTypeHandler类。源代码如下只贴出少量 public abstract class BaseTypeHandlerT extends TypeReferenceT implements TypeHandlerT {......public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {......}public T getResult(ResultSet rs, String columnName) throws SQLException {......}public T getResult(ResultSet rs, int columnIndex) throws SQLException {......}public T getResult(CallableStatement cs, int columnIndex) throws SQLException {......}public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException;public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException;public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;}简单分析一下 setParameter方法当参数parameter和jdbcType同时为空时Mybatis将抛出异常。如果能目前jdbcType则会继续空设置如果参数不为空那么他将曹勇setNonNullParameter方法设置参数。getResult方法非空结果集是通过getNullableResult方法获取的。如果判断为空则返回null。getNullableResult方法用于存储过程。 在Mybatis中使用最多的typeHandler为StringTypeHandler。它用于字符串的转换所以我们来学习一下。源代码如下 public class StringTypeHandler extends BaseTypeHandlerString {public StringTypeHandler() {}public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, parameter);}public String getNullableResult(ResultSet rs, String columnName) throws SQLException {return rs.getString(columnName);}public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return rs.getString(columnIndex);}public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return cs.getString(columnIndex);} }从上述代码可以看出它继承了BaseTypeHandler类并且实现了BaseTypeHandler的4个抽象方法方法如下 setNonNullParameter这个方法是用来将javaType转换成jdbcTpe。getNullableResult这个方法用来将从结果集根据列名称获取到的数据的jdbcType转换成javaType。getNullableResult这个方法用来将从结果集根据列索引获取到的数据的jdbcType转换成javaType。getNullableResult这个方法用在存储过程中。 这里Mybatis把JavaType和jdbcType进行互换那么他们是怎么进行注册的呢在Mybatis中采用TypeHandlerRegistry类对象的register方法来进行则。 public TypeHandlerRegistry(Configuration configuration) {......this.register((Class)Boolean.class, (TypeHandler)(new BooleanTypeHandler()));this.register((Class)Boolean.TYPE, (TypeHandler)(new BooleanTypeHandler()));this.register((JdbcType)JdbcType.BOOLEAN, (TypeHandler)(new BooleanTypeHandler()));this.register((JdbcType)JdbcType.BIT, (TypeHandler)(new BooleanTypeHandler()));......}这样就是实现了用代码的形式注册typeHandler。但是注意自定义的typeHandler一般不会使用代码进行注册而是通过配置或者扫描使用下面我们来学习如何自定义typeHandler。 5.2、自定义typeHandler 我们知道在大部分场景下Mybatis的typeHandler都能应付但是有时候也会不够用比如枚举类型这个时候就需要自定义typeHandler来进行处理了。从系统定义的typeHandler可以知道要实现typeHandler就需要去实现接口typeHandler或者实现baseTypeHandler。 下面我们使用实现TypeHandler接口的方式创建一个MyTypeHandler用来完成javaType中的String类型与jdbcType中的类型之间的转化。 public class MyTypeHandler implements TypeHandlerString {Logger log Logger.getLogger(MyTypeHandler.class);Overridepublic void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {log.info(设置string参数parameter);ps.setString(i,parameter);}Overridepublic String getResult(ResultSet rs, String columnName) throws SQLException {String result rs.getString(columnName);log.info(读取string参数1result);return result;}Overridepublic String getResult(ResultSet rs, int columnIndex) throws SQLException {String result rs.getString(columnIndex);log.info(读取string参数2result);return result;}Overridepublic String getResult(CallableStatement cs, int columnIndex) throws SQLException {String result cs.getString(columnIndex);log.info(读取string参数3result);return result;} }我们定义的泛型为String则表示我们要把数据库类型的数据转化为String类型然后实现设置参数和获取结果集的方法。但是这个时候还没有启动typeHandler。还需要在配置文件中配置一下。 typeHandlerstypeHandler jdbcTypeVARCHAR javaTypestringhandlercom.typeHandler.MyTypeHandler/ /typeHandlers配置完成之后系统才会读取它这样就注册完毕了当JavaType和jdbcType能与MyTypeHandler对应的时候它就会启动MyTypeHandler。我们有两种方式来使用自定义的typeHandler。 !-- 模糊查询根据username字段查询用户-- select idselectUserByName parameterTypestring resultTypeuserselect * from t_user where username like concat (%,#{username,typeHandlercom.typeHandler.MyTypeHandler},%); /select或者 select idselectUserByName parameterTypestring resultTypeuserselect * from t_user where username like concat (%,#{username,javaTypestring,jdbcTypeVARCHAR},%); /select注意要么指定了与自定义typeHandler一致的jdbcType和JavaType要么直接使用typeHandler指定的具体实现类。在一些因为数据库返回为空导致无法判定采用哪个typeHandler来处理而又没有注册对应的JavaType的typeHandler是Mybatis无法找到使用哪个typeHandler来转换数据。 有时候类很多的时候我们还可以采用包扫描的方式。 typeHandlerspackage namecom.typeHandler/ /typeHandlers但是这样会无法指定jdbcType和JavaType不过我们可以通过注解来处理它们我们把MyTypeHandler类修改一些即可。 MappedTypes(String.class) MappedJdbcTypes(JdbcType.VARCHAR) public class MyTypeHandler implements TypeHandlerString {...... }最后在我们的日常开发中一般都不需要定义使用默认的就可以除非是像枚举这种特殊类型就需要自己实现。 6、objectFacotry属性了解 objectFacotry表示为对象工厂。对象工厂我们只需了解即可因为到时候与spring整合后都会由spring来管理。 我们在使用MyBatis执行查询语句的时候通常都会有一个返回类型这个是在mapper文件中给sql增加一个resultType(或resultMap)属性进行控制。resultType和resultMap都能控制返回类型只要定义了这个配置就能自动返回我想要的结果于是我就很纳闷这个自动过程的实现原理想必大多数人刚开始的时候应该也有和我一样的困惑和好奇那么今天我就把自己的研究分享一下。在JDBC中查询的结果会保存在一个结果集中其实MyBatis也是这个原理只不过MyBatis在创建结果集的时候会使用其定义的对象工厂DefaultObjectFactory来完成对应的工作。 7、plugins属性了解 插件是Mybatis中最强大和灵活的组件同时也是最复杂、最难使用的组件并且它十分的危险因为它将覆盖Mybatis底层对象的核心方法和属性。如果操作不当将产生非常严重的后果甚至是摧毁Mybatis框架所以我们在不了解Mybatis的底层结构的情况下千万不要去碰这个插件属性。如果你想研究一下插件那么前提是要清楚掌握Mybatis底层的结构和运行原理否则将难以安全高效的使用它。而我们平时使用Mybatis的常规功能完全满足日常的开发所以这里就不介绍了有兴趣的可以自行去学习。 8、environments属性 environments属性表示的是运行环境主要的作用是配置数据库的一些信息我们可以配置多个数据库但只能选择一个。它里面分为两个可配置的元素事务管理器(transactionManager)、数据源(DataSource)。而在我们的日常开发中这些都会交给Spring来管理不用在全局配置中编写这些会在后面Mybatis整合Spring中进行讲解。我们先来看看environments环境配置的配置代码吧。 configuration!-- 配置环境.--environments defaultdevelopment!-- id属性必须和上面的default一致 --environment iddevelopment!--配置事务的类型--transactionManager typeJDBC/transactionManager!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 --dataSource typePOOLED!--配置连接数据库的4个基本信息--property namedriver value${database.driver}/property nameurl value${database.url}/property nameusername value${database.username}/property namepassword value${database.password}//dataSource/environment/environments /configuration下面我们主要来详细介绍 transactionManager 和 DataSource 这两个元素。 8.1、transactionManager事务管理 在MyBatis中transactionManager提供了两个实现类它们都需要实现接口Transaction所以我们可以查看以下Transaction的源代码 public interface Transaction {Connection getConnection() throws SQLException;void commit() throws SQLException;void rollback() throws SQLException;void close() throws SQLException;Integer getTimeout() throws SQLException; }从上面的方法可知它主要的工作就是提交commit、回滚rollback、关闭close数据库的事务。MyBatis中为Transaction接口提供了两个实现类分别是 JdbcTransaction 和 ManagedTransaction。如下图所示 并且分别对应着 JdbcTransactionFactory 和 ManagedTransactionFactory 两个工厂这两个工厂实现了 TransactionFactory 这个接口当我们在配置文件中通过 transactionManager 的type属性配置事务管理器类型的时候Mybatis就会自动从对应的工厂获取实例。我们可以把事务管理器配置成为以下两种方式 transactionManager typeJDBC/ transactionManager typeMANAGED/下面说一下这两者的区别 JDBC使用JdbcTransactionFactory工厂生成的JdbcTransaction对象实现以JDBC的方式进行数据库的提交、回滚等操作。 MANAGED使用ManagedTransactionFactory工厂生成的ManagedTransaction对象实现它的提交和回滚不需要任何操作而是把事务交给容器进行处理默认情况下会关闭连接如果不希望默认关闭只要将其中的closeConnection属性设置为false即可。 transactionManager typeMANAGEDproperty namecloseConnection valuefalse/ /transactionManager在测试的过程中发现的最明显的区别就是如果我使用JDBC的事务处理方式当我向数据库中插入一条数据时在调用完插入接口执行SQL之后必须 执行sqlSession.commit();进行提交否则虽然插入成功但是数据库中还是看不到刚才插入的数据而使用MANAGED方式就不一样了只需调用接口即可无需手动提交。 当然除了使用默认的我们还可以根据需要自定义一个事务管理器需要以下三步 第一步创建一个自定义事务工厂MyTransactionFactory需要实现TransactionFactory接口代码如下 /*** 创建自定义事务工厂*/ public class MyTransactionFactory implements TransactionFactory {Overridepublic void setProperties(Properties props) {}Overridepublic Transaction newTransaction(Connection connection) {//后面我们会创建这个类它自定义的事务类return new MyTransaction(connection);}Overridepublic Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean b) {return new MyTransaction(dataSource,level,b);} }这里就实现了TransactionFactory所有定义的工厂方法了这时还要一个自定义的事务类下面我们来创建。 第二步创建一个自定义事务类MyTransaction用来实现Transaction接口代码如下。 MyTransaction 第三步配置自定义事务管理器 transactionManager typecom.transaction.MyTransactionFactory/注意这个地方配置的是自定义的工厂类而不是事务管理类因为mybatis是根据配置的工厂获取具体实例对象的。 8.2、DataSource数据源 在Mybatis中数据库是通过PooledDataSourceFactory、UnpooledDataSourceFactory和JndiDataSourceFactory三个工厂类来提供前两者分别产生PooledDataSource和UnpooledDataSource类对象第三个则会根据JNDI的信息拿到外部容器实现的数据库连接对象但是不管怎样它们最后都会生成一个实现了DataSource接口的数据库连接对象。 因为有三种数据源所以它们的配置信息如下 dataSource typePOOLED dataSource typeUNPOOLED dataSource typeJNDI下面介绍一下这三种数据源的意义 ①、UNPOOLED UNPOOLED采用非数据库池的管理方式每次请求都会新建一个连接所以性能不是很高使用这种数据源的时候UNPOOLED类型的数据源可以配置以下属性 driver数据库驱动名url数据库连接URLusername用户名password密码defaultTransactionIsolationLevel默认的事务隔离级别如果要传递属性给驱动则属性的前缀为driver ②、POOLED POOLED采用连接池的概念将数据库链接对象Connection组织起来可以在初始化时创建多个连接使用时直接从连接池获取避免了重复创建连接所需的初始化和认证时间从而提升了效率所以这种方式比较适合对性能要求高的应用中。除了UNPOOLED中的配置属性之外还有下面几个针对池子的配置 poolMaximumActiveConnections任意时间都会存在的连接数默认值为10poolMaxmumIdleConnections可以空闲存在的连接数poolMaxmumCheckoutTime在被强制返回之前检查出存在空闲连接的等待时间。即如果有20个连接只有一个空闲在这个空闲连接被找到之前的等待时间就用这个属性配置。 poolTimeToWait等待一个数据库连接成功所需的时间如果超出这个时间则尝试重新连接。 还有其他的一些配置不详述了。 ③、JNDI JNDI数据源JNDI的实现是为了能在如EJB或应用服务器这类容器中使用容器可以集中或在外部配置数据源然后放置一个JNDI上下文的引用。这种数据源只需配置两个属性 initial_context用来在InitialContext中寻找上下文。可选如果忽略data_source属性将会直接从InitialContext中寻找data_source引用数据源实例位置上下文的路径。当提供initial_context配置时data_source会在其返回的上下文进行查找否则直接从InitialContext中查找。 除了上述三种数据源之外Mybatis还提供第三方数据源如DBCP但是需要我们自定义数据源工厂并进行配置这一点暂时不做研究。 9、databaseIdProvider属性了解 databaseIdProvider元素主要是为了支持不同厂商的数据库这个元素不常用。比如有的公司内部开发使用的数据库都是MySQL但是客户要求使用Oracle那麻烦了因为Mybatis的移植性不如Hibernate但是Mybatis也不会那么蠢在Mybatis中我们可以使用databaseIdProvider这个元素实现数据库兼容不同厂商即配置多中数据库。 下面以Oracle和MySQL两种数据库来介绍它们要配置的属性如下 !--数据库厂商标示 -- databaseIdProvider typeDB_VENDORproperty nameOracle valueoracle/property nameMySQL valuemysql/property nameDB2 valued2/ /databaseIdProviderdatabaseIdProvider的type属性是必须的不配置时会报错。上面这个属性值使用的是VendorDatabaseIdProvider类的别名。 property子元素是配置一个数据库其中的name属性是数据库名称value是我们自定义的别名通过别名我们可以在SQL语句中标识适用于哪种数据库运行。如果不知道数据库名称我们可以通过以下代码获取connection.getMetaData().getDatabaseProductName()来获取代码如下 /*** 获取数据库名称*/ public static void getDbInfo() {SqlSession sqlSession null;Connection connection null;try {InputStream stream Resources.getResourceAsStream(mybatis-config.xml);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(stream);sqlSession sqlSessionFactory.openSession();connection sqlSession.getConnection();String dbName connection.getMetaData().getDatabaseProductName();String dbVersion connection.getMetaData().getDatabaseProductVersion();System.out.println(数据库名称是 dbName 版本是 dbVersion);} catch (SQLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} }我的输出结果是数据库名称是MySQL版本是5.7.28-log 然后下面我们就可以在自己的sql语句中使用属性databaseId来标示数据库类型了。配置如下 !-- 查询所有用户 -- select idselectAllUser resultTypecom.thr.User databaseIdoracleselect * from t_user /select注意在上面的SQL中我配置的databaseId是oracle但是我的实际的数据库是mysql结果最后肯定会报BindingException异常但是我这个代码不知道为什么报的另一种异常就很奇怪百度了好久无果。如果我们把databaseId”oracle”换成mysql的就能获取正确结果了。除上述方法之外我们还可以不在SQL中配置databaseId这样mybatis会使用默认的配置也是可以成功运行的。 过上面的实践知道了使用多数据库SQL时需要配置databaseIdProvider 属性。当databaseId属性被配置的时候系统会优先获取和数据库配置一致的SQL否则取没有配置databaseId的SQL可以把它当默认值如果还是取不到就会抛出异常。 除了系统自定义的标识外我们也可以自定义一个规则需要实现MyBatis提供的DatabaseIdProvider接口如下 MyDatabaseIdProvider 然后在databaseIdProvider中做如下配置 !--数据库厂商标示 -- databaseIdProvider typecom.databaseidprovider.MyDatabaseIdProvider /property属性可以不做配置了其它都一样。 10、mappers属性 mapper属性是用来加载映射文件的也就是加载我们配置的SQL映射文件。它有四种方式加载 用文件路径引入 使用URL方式引入 用类注册引入 用包名引入推荐 10.1、用文件路径引入 mappersmapper resourcecom/thr/mapper/UserMapper.xml /mapper resourcecom/thr/mapper/StudentMapper.xml /mapper resourcecom/thr/mapper/TeacherMapper.xml / /mappers这种方式是相对路径相对于项目目录下所以得用 / 分开。 10.2、使用URL方式引入 mappersmapper urlD:/mappers/UserMapper.xml /mapper urlD:/mappers/StudentMapper.xml / /mappers这种方式是绝对路径就是从我们的磁盘读取映射文件一般不会使用这种方式。 10.3、用类注册引入 mappersmapper classcom.thr.mapper.UserMapper /mapper classcom.thr.mapper.StudentMapper /mapper classcom.thr.mapper.TeacherMapper / /mappers这种方式使用Mapper接口的全限定名不用管路径问题让Mybatis自己通过全限定名去找映射文件。但是前提是Mapper接口的名称必须与映射文件的名称相同并且要在同一个包名下否则会找不到。比如UserMapper.java接口—UserMapper.xml映射文件。关于Mapper接口对应的Mapper映射文件后面会详细介绍。 10.4、用包名引入推荐 mapperspackage namecom.thr.mapper/ /mappers推荐使用这种方式表示引入该包下的所有mapper接口这里引入了com.thr.mapper包下的所有接口文件然后让Mybatis自己通过全限定名去找映射文件。 注意这种方式的要求同样是Mapper接口和Mapper的映射文件的名称要相同并且要放在相同的包名下否则会导致找不到。
http://www.dnsts.com.cn/news/198573.html

相关文章:

  • 梧州网站优化网站建设费用计入什么科目
  • 如何制作网站建设三亚做网站的公司
  • 曲靖住房和城乡建设局网站网站导航菜单兰
  • 企业网站建设要点wordpress api 路径
  • 网站备案信息核验单怎么上海工商网上办事大厅官网
  • 做企业网站 目的网站建设方案多少钱
  • 网站前台设计模板网页设计于制作课程标准
  • 网站被攻击空间关了怎么办ps素材库
  • 软件企业公司网站模板下载专门做国外网站
  • 山西建设局网站首页seo是什么意思呢
  • 网站设计制作公司需要什么资质网站关键字排名怎么做
  • 一个产品有两个品牌怎么做网站软件销售
  • 龙岩网站设计价格机关门户网站 建设 方案
  • 鼎豪网站建设做问卷调查的网站有啥
  • 海南做网站公司网站字体一般是什么字体
  • 做网站服务器哪种好网站开发的英文书有什么
  • 网站建设维护兼职东营招标建设信息网
  • flash做网站的流程wordpress前台打开慢
  • 河南做网站那家最好wordpress wp_register_script
  • 鞋材加工东莞网站建设电商平台推广
  • 全屏网站 欣赏网站反链和外链的区别
  • 珠海做企业网站多少钱长沙口碑最好的装修公司排名
  • 怎么给网站做seo汕头教育学会网站建设
  • 网站建设述职报告拼多多运营怎么做
  • 北京高端网站建设宣传汉中住房和城乡建设部网站
  • 江苏城市建设职业学院网站长沙教育网站建设
  • 广州企业网站建设公司合肥公共资源交易中心
  • .net电商网站开发专业网页设计价格
  • 京津冀协同发展规划图谷歌外贸seo
  • 温州网站建设咨询有人模仿qq音乐做的h5网站吗