• myBatis的核心配置


    MyBatis的设计思路

    ORM(Object Relation Mapping)模型将数据库存储数据与POJO对象进行映射,从而简化数据转化的复杂度;如果说Hibernate是完全封装的ORM框架,则myBatis则是半完全封装的ORM框架,因为myBatis需要手动映射SQL返回结果与POJO对象的映射;

    java连接mysql一般有四种方式,不基于连接池的jdbc和基于连接池的dbcp, c3p0, jndi:
    #1 jdbc:不使用连接池,每次进行DB操作都通过java.sql.DriverManager.getConnection获取一个新的connection,并通过openSession()获取一个交互session;
    #2 dbcp:基于org.apache.commons.dbcp.BasicDataSource并创建connection pool,BasicDataSourceFactory.createDataSource获取DBCP数据源,然后获取可重复使用的connection;
    #3 c3p0:基于DataSource并创建connection pool,ComboPooledDataSource.getConnection获取可重复使用的connection。
    #4 jndi:基于DataSource并创建connection pool,InitialContext.getConnection获取connection。

    myBatis解决了原生JDBC访问DB的几大问题:

    #1 DB Connection频繁的开启和关闭会造成资源的浪费,所以使用DB Connection Pool通过重复利用Connection可以极大降低DB资源的消耗;connection创建session并开启transaction,session结束后transaction也关闭,并将connection归还给pool;
    #2 使用可配置的方式兼容多种DataSource(jndi, c3p0, dbcp)的连接池;
    #3 越来越多的业务需要根据数据来动态生成sql语句,传统的preparedStatement都是基于固定的sql来填充参数,mybatis提供if-else等标签根据业务数据动态生成并组装sql;
    #4 mybatis提供ResultMap等自动映射的方式对查询结果进行解析,并提供[sql + params]作为key的方式将查询结果进行缓存;
    #5 mybatis提供<sql />标签将一些共用的sql片段抽取出来,供多个地方引用;

    对比MyBatis和Hibernate

    #1 myBatis中的SQL是在开发的时候就已经写好的,并且可以细粒度的优化SQL语句,hibernate则是完全根据Object生成SQL,性能上会有一些影响;但同时hibernate的DB关联性低,可移植性高,myBatis由于定制化了大量的SQL,则在迁移DB的时候需要考虑兼容性;

    Mybatis可接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发;但缺点是mybatis无法做到数据库无关性,如果需要实现支持多种数据库则需要自定义多套sql映射文件,myBatis同样支持通过java bean定义逆向生成CRUD操作对应的SQL。

    #2 Hibernate提供的是一种全表映射的模型,因此在做关联查询的时候hibernate会将相关表的所有字段都加载到内存,然后再将数据封装成需要的对象;而myBatis会根据resultMap仅仅将需要的数据加载到内存,并自动转化成需要的对象,可以极大提升效率。

    #3 Hibernate有一整套DAO对象的状态管理机制,myBatis则没有完整的DAO管理机制,需要手动维护DAO对象的数据更新操作;

    #4 Hibernate的ORM映射关系是固定的,如果某些字段或者某些查询条件需要动态生成则只能通过HQL实现(性能较差),而myBatis天然支持SQL的动态生成,可以支持table名字或者column名字动态变化的场景;

    #5 Hibernate不能有效支持存储过程,myBatis天然支持存储过程,store procedure的优势在于将业务逻辑封装到DB端,更安全稳定、执行性能也高,但劣势在于bug tracking和可移植性;

    在spring中集成myBatis

    首先在spring配置文件service.xml中配置 DBCP数据源,TxManager 和SqlSession的封装。

     1 <beans xmlns="http://www.springframework.org/schema/beans">
     2   <bean id="dbcpDataSource"
     3     class="org.apache.commons.dbcp.BasicDataSource">
     4     <property name="driverClassName">
     5       <value>com.mysql.jdbc.Driver</value>
     6     </property>
     7     <property name="url">
     8       <value>jdbc:mysql://localhost:3306/ychenDemo</value>
     9     </property>
    10     <property name="username">
    11       <value>root</value>
    12     </property>
    13     <property name="password">
    14       <value>password</value>
    15     </property>
    16   </bean>
    17 
    18   <bean id="mybatisTxManager"
    19     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    20     <property name="dataSource" ref="dbcpDataSource" />
    21   </bean>
    22 
    23   <bean id="sqlSessionFactory"
    24     class="org.mybatis.spring.SqlSessionFactoryBean">
    25     <property name="dataSource" ref="dbcpDataSource" />
    26     <property name="configLocation"
    27       value="mybatis/mybatis-config.xml"></property>
    28   </bean>
    29 
    30   <bean id="myBatisBaseMapper"
    31     class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true"
    32     lazy-init="true">
    33     <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    34   </bean>
    35 
    36   <bean id="userMapper" parent="myBatisBaseMapper">
    37     <property name="mapperInterface"
    38       value="ychen.demo_mybatis.mapper.UserMapper" />
    39   </bean>
    40 
    41   <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    42     <constructor-arg index="0" ref="sqlSessionFactory" />
    43   </bean>
    44 </beans>

    mybatis提供两种DB操作的接口:
    -1 通过sqlSessionTemplate提供统一接口,并在参数中指定statementID和parameterList的方式;

     1 public List<Person> getPersonById(Long personId) {
     2     Map<String, Long> params = Maps.newHashMap();
     3     params.put("personId", personId);
     4     List<Person> result = template.selectList("getPersonById", params);
     5     return result;
     6 }
     7 
     8 >>>>>>>>>>>>>
     9 <mapper namespace="personMapper">
    10   <select id="getPersonById" resultType="com.ychen.Person">
    11     SELECT * FROM person WHERE id = #{personId}
    12   </select>
    13 </mapper>

    -2 通过定义mapper interface,并使用SqlSessionFactoryBean和MapperFactoryBean动态代理的方式生成mapper实现类,mapper interface中可以自定义多个DB访问接口,内部实现依旧是转换成sqlSessionTemplate统一接口的方式,只是封装性更好。

     1 @Component
     2 public interface UserMapper {
     3     void insert(UserEntity user);
     4     UserEntity getOne(Long id);
     5 }
     6 
     7 >>>>>>>>>
     8 <mapper namespace="ychen.demo_mybatis.mapper.UserMapper">
     9   <select id="getOne" parameterType="Long" resultMap="BaseResultMap">
    10     SELECT  <include refid="Base_Column_List" />
    11     FROM payment_session
    12     WHERE id = #{id}
    13   </select>
    14 </mapper>
    15 
    16 >>>>>>>>>
    17 UserMapper userMapper = 
    18     applicationContext.getBean("userMapper", UserMapper.class);
    19   UserEntity userEntity = userMapper.getOne(1L);

    构建sqlSessionFactory所需的myBatis-config.xml配置

     1 <configuration>
     2   <!-- resource属性引入外部定义的key/value变量,也可通过property标签定义内部变量 -->
     3   <properties resource="org/mybatis/example/mybatis-config.properties"> 
     4     <property name="username" value="dev_user"/> 
     5     <property name="password" value="F2Fa3!33TYyg"/> 
     6   </properties>
     7   <!-- 定义mybatis的运行变量 -->
     8   <settings>
     9     <setting name="cacheEnabled" value="true"/>
    10     <setting name="lazyLoadingEnabled" value="true"/>
    11     <setting name="multipleResultSetsEnabled" value="true"/>
    12     <setting name="useColumnLabel" value="true"/>
    13     <setting name="useGeneratedKeys" value="false"/>
    14     <setting name="autoMappingBehavior" value="PARTIAL"/>
    15     <!-- SIMPLE|REUSE|BATCH -->
    16     <setting name="defaultExecutorType" value="SIMPLE"/>
    17     <setting name="defaultStatementTimeout" value="25"/>
    18     <setting name="defaultFetchSize" value="100"/>
    19     <setting name="safeRowBoundsEnabled" value="false"/>
    20     <setting name="mapUnderscoreToCamelCase" value="false"/>
    21     <setting name="localCacheScope" value="SESSION"/>
    22     <setting name="jdbcTypeForNull" value="OTHER"/>
    23     <setting name="lazyLoadTriggerMethods" 
    24       value="equals,clone,hashCode,toString"/>
    25   </settings>
    26   <!-- 定义常用类型的简写别名,同时mybatis为java常用类型提供了缺省别名 -->
    27   <typeAliases>
    28     <typeAlias type="leo.chen.domain.UserAccount" alias="UserAccount" />
    29     <typeAlias type="leo.chen.domain.SpecialCar" alias="SpecialCar" />
    30   </typeAliases>
    31   <!-- 处理参数和返回结果在java-type和db-type间的转换,同时myBatis提供常用类型的handler -->
    32   <!-- 通过继承BaseTypeHandler类或者实现TypeHandler接口,可以定制化转换方法 -->
    33   <typeHandlers>
    34     <typeHandler handler="com.active.services.endurance.mybatis.UUIDTypeHandler" 
    35       javaType="java.util.UUID" jdbcType="VARCHAR"/>
    36   </typeHandlers>
    37   <!-- myBatis创建结果对象实例时使用默认的工厂类实现,通过objectFactory可以替换默认的工厂 -->
    38   <objectFactory type="leo.chen.manager.CustomizedObjectFactory">
    39     <property name="property1" value="value1">
    40   </objectFactory>
    41   <!-- 用于对mybatis处理流程中某些方法的扩展处理,如缓存一致性,如分页 -->
    42   <plugins>
    43     <plugin interceptor="org.mybatis.example.validationPlugin"> 
    44       <property name="isThrowExp" value="true"/> 
    45     </plugin> 
    46   </plugins>
    47   <!-- 定义mybatis的执行环境,包括事务管理、数据源等配置 -->
    48   <environments default="development">
    49     <environment id="development"> 
    50       <transactionManager type="JDBC"> </transactionManager> 
    51       <dataSource type="POOLED"> 
    52         <property name="driver" value="${driver}"/> 
    53         <property name="url" value="${url}"/> 
    54         <property name="username" value="${username}"/> 
    55         <property name="password" value="${password}"/> 
    56         <property name="defaultTransactionlsoltionLevel" value="${txLevel}"/>
    57         <property name="poolMaximumActiveConnection" value="10"/>
    58         <property name="poolMaximumldleConnection" value="10"/>
    59         <property name="poolMaximumCheckoutTime" value="20000"/>
    60         <property name="poolTimeToWait" value="20000"/>
    61         <property name="poolPingQuery" value="NOPINGQUERYSET"/>
    62         <property name="poolPingEnabled" value="false"/> 
    63         <property name="poolPingConnectionsNotUsedFor" value="0"/> 
    64       </dataSource> 
    65     </environment>
    66   </environments>
    67   <!-- 数据库厂商标识 -->
    68   <databaseIdProvider type=""></databaseIdProvider>
    69   <!-- 定义mapper映射文件 -->
    70   <mappers>
    71     <mapper resource="mybatis/productMapper.xml" />
    72   </mappers>
    73 </configuration>

    #1 mybatis提供两种事务管理配置,JDBC和MANAGED,前者使用正常的JDBC的事务管理,也就是对java.sql.Connection事务管理的封装,依赖于从data source获取的连接来管理实务;后者将事务管理交由WEB容器进行管理,也就是说调用ManagedTransaction的commit和rollback并不会有任何动作;如果myBatis跟spring集成,则不需要配置此项。

    #2 mybatis提供三种数据源的的配置,POOLED, UNPOOLED和JNDI,POOLED是在UNPOOLED的封装上添加了connection缓存管理的实现,UNPOOLED的实现仅仅是打开和关闭连接;而JNDI则是通过jndi服务查找代理的data source实现;如果myBatis跟spring集成,则也不需要配置此项。

    #3 localCacheScope表示设置一级缓存的使用范围,缺省为SESSION,如果设置为STATEMENT则表示一级缓存仅限于一次statement使用,也就是禁用缓存。鉴于mybatis一级缓存实现不完整,容易造成数据一致性问题,因此建议使用STATEMENT。

    #4 <plugins>标签允许在mybatis内部的四个大的处理流程中插入自定义的处理方法:
    -1 Executor:处理mybatis的整个流程和二级缓存的使用
    -2 ParameterHandler:处理mybatis对sql传入参数的赋值,
    -3 StatementHandler:处理mybatis与db进行交互的规则和一级缓存的修改,
    -4 ResultSetHandler:处理mybatis对结果集的映射规则;
    具体的实现类需要实现Interceptor接口及对应的方法。

    1 public interface Interceptor {   
    2    //通过invocation.getTarget()可以定制不同阶段的plugin
    3    Object intercept(Invocation invocation) throws Throwable;       
    4    Object plugin(Object target);    
    5    void setProperties(Properties properties);
    6 }
  • 相关阅读:
    python常用运维脚本实例
    数据库优化方案整理
    Python第一章概述与环境安装
    九阴真经
    常用的kubectl命令
    第7篇管理存储资源
    第8篇NFS PersistentVolume
    第10篇用 ConfigMap 管理配置
    第11篇Kubernetes部署微服务电商平台
    第12篇Kubernetes 监控
  • 原文地址:https://www.cnblogs.com/leo-chen-2014/p/10664932.html
Copyright © 2020-2023  润新知