Mybatis入门

目录

 

第一部分:基本配置内容

第二部分:Mapper文件基本语法

第三部分:动态SQL标签的使用

第四部分:Mybatis高级映射查询

第五部分:Mybatis存储过程调用

第六部分:Mybatis缓存配置

第七部分:细节注意事项

第八部分:附录


第一部分:基本配置内容

                     首先创建一个最简单的maven webapp项目,web.xml文件中需要添加的内容如下,用于引入SpringMVC以及Spring

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

然后添加Spring+SpringMVC+mybatis对应的配置文件

首先是Spring.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/tx  
        http://www.springframework.org/schema/tx/spring-tx.xsd  
        http://www.springframework.org/schema/aop  
        http://www.springframework.org/schema/aop/spring-aop.xsd  
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd">
        
        <context:component-scan base-package="com.zk.demo" />
        
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <array>
                    <value>classpath:datasource.properties</value>
                </array>
            </property>
        </bean>
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </bean>
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mapperLocations" value="classpath:mappers/*.xml"></property>
            <property name="configLocation" value="classpath:spring-mybatis.xml"></property>
        </bean>
        
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.zk.demo.mapper" />
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        </bean>
        
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
        
        <tx:annotation-driven transaction-manager="transactionManager"/>
        
        <aop:config>
            <aop:pointcut id="targetMethod" expression="execution(* com.zk.demo.service.*.*(..))" />
            <aop:advisor pointcut-ref="targetMethod"  advice-ref="transactionAdvice"/>
        </aop:config>
        
        <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
                <tx:method name="*" propagation="REQUIRED" read-only="true"/>
            </tx:attributes>
        </tx:advice>
</beans>

然后是SpringMVC对应的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd">

    <mvc:annotation-driven/>
    
    <context:component-scan base-package="com.zk.demo.controller" />

</beans>

最后是mybatis配置文件

<?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>
    <settings>
        <setting name="aggressiveLazyLoading" value="false"/>
        <setting name="cacheEnabled" value="true"/>
        <setting name="logImpl" value="SLF4J" />
    </settings>
    
    <typeHandlers>
        <package name=""/>
    </typeHandlers>
    <databaseIdProvider type="DB_VENDOR">
        <property name="SQL SERVER" value="sqlserver"/>
        <property name="Oracle" value="oracle"/>
        <property name="MYSQL" value="mysql"/>
    </databaseIdProvider>
</configuration>

中心思想:Spring中配置了myabtis配置文件位置和mapper文件所在位置(mybatis配置文件配置比较死板),数据源交给spring 管理,因为涉及到了事务,mybatis配置文件只是负责其他mybatis就好了比如全局设置,类型转换设置,还有一个比较重要的就是数据库类型设置,目前使用比较多的关系型数据库就是mysql oracle  sqlserver这三类,我打算都兼容下,作为练习吧,毕竟公司换数据库的情况还不是很多,有的时候大家写sql通常只会兼容一种数据库,具体的下面再说。

Mapper接口使用的MapperScanConfigure自动扫描,同时mapper接口需要添加@Mapper注解,实体类别名需要使用@Alias注解

第二部分:Mapper文件基本语法

                              配置完以上内容基本上就能跑起来了,但是mybatis还有一个比较重要的配置就是SQL映射文件mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zk.demo.mapper.DatabaseHealthMapper">

    <select id="isAlive" resultType="Integer" databaseId="mysql">
        SELECT COUNT(*)
        FROM DUAL
    </select>
</mapper>

mapper标签的namespace很重要。对应的是Java的接口路径,下面就是增删改查的各种标签了

select标签

基本的标签属性就不讲解了id      resultType    resultMap  这些的,其中比较特殊的是resultMap这个标签

里面可以添加association collection  discriminator(根据结果值来判定使用哪个映射)   case某些值的结果映射(这些后面讲)。

另外rsultMap的result字标签还可以添加typeHandler内容

 

insert标签

标签内容不常用的如

flushCache  清空一级一级二级缓存,这个默认就是true可以不用关注

timeout指的是驱动程序等待数据库的响应时间,单位是秒

statementType:包含三种类型Statement prepared callable默认是prepared

useGeneratedKeys:默认是false,如果是true的话会调用JDBC的getGeneratedkeys(),不是所有的数据库都支持主键自增的,oracle就是使用的序列。

databseId是用来区分数据库的,如果都存在,没有标注databaseId的将被胡略

update以及delete标签就没啥新鲜的了。

 

第三部分:动态SQL标签的使用

if标签

<if test="userName!=null and userName!=''">
 </if>

choose标签

<choose>
            <when test="id!=null">
            </when>
            <otherwise>
            </otherwise>
 </choose>

where  set   trim标签

咋说呢,where和set标签都是trim标签的一种具体简化,换句话说就是where标签和set标签都可以用trim实现

where和set标签会自动去掉相应位置的 and   逗号之类的

 

foreach标签

foreach可以处理三种集合   list   array    map

<foreach collection="list" open="(" close=")" separator="," item="item">
</foreach>

以下是map轮询

<foreach collection="_parameter.keys" item="key" open="(" close=")" separator="," >  

 ${key}  

 </foreach>  

 values   

<foreach collection="_parameter.keys"  item="key" open="(" close=")" separator=",">  

#{params[${key}]}  

</foreach>

<foreach collection="_parameter" index="key" item="value" separator=",">
 </foreach>

bind标签

做这个标签就是定义一个变量<bind name="" value=""/>

这样下面就可以使用#{name}作为数据了

注意collection的值,当列表的时候填写list数组的时候填写array  map的时候需要填写_parameter  但是如果使用了@param注解则需要填写对应的名称

第四部分:Mybatis高级映射查询

可以使用mybatis  ognl表达式实现自动映射,也可以通过下面的配置实现映射。

一对一映射association

直接将字段值根据ognl表达式绑定到对应的字段上。

<resultMap type="" id="">
        <association property="role" resultMap="com.zk.demo.mapper.RoleMapper.roleMap" columnPrefix="role_"/>
        <association property="role" resultMap="com.zk.demo.mapper.RoleMapper.roleMap"  select="" column="{id=role_id}"/>
    </resultMap>

一对多映射collection配置内容和association是一样的

鉴别器映射(discriminator),类似于switch这么个东西,这个标签有column   javaType两个属性,这个标签有多个case子标签,

子标签包含value resultType  resultmap三个属性。

不太建议用这个东西,感觉业务逻辑被写到了sql中,以后变化是个问题。

第五部分:Mybatis存储过程调用

<select id="" statementType="CALLABLE" useCache="false">
        {
            call select_power(
                #{id,mode=IN}
            )
        }
    </select>

存储过程需要加上statementType="CALLABLE",另外存储过程不支持二级缓存,因此需要加上userCache=false

另外mode=OUT的参数都需要指定jdbcType,如果入参可能存在null的情况,则也需要提供jdbcType

数据库类型BLOB对应java的byte[],但是这时候java可能默认的是byte类型,因此遇到这种情况还需要指定javaType

 

带有游标的存储过程(Mysql不支持游标参数 oracle支持)

使用游标需要将jdbcType设置为CURSOR javaType设置为ResultSet,结果是一个多列的内容,需要resultMap映射

{
            call select_cuscor(
                #{list,mode=OUT,jdbcType=CUSCOR,javaType=ResultSet,resultMap=}
            )
        }

注意其中的list是看响应的结果内容是什么,其实不太建议使用游标,毕竟不是所有的数据库都支持。

通过枚举实现,首先需要添加对应的TypeHandler,然后再Mybatis配置文件中加上转换器扫描就可以了。

第六部分:Mybatis缓存配置

Mybatis默认开启一级缓存,一级缓存指的是一次会话之中的请求会缓存,二级缓存指的是整个项目启动过程中会是缓存。

如果想避免一级缓存导致的问题可以在查询sql的时候设置select 标签中的flushCache=true,实际上使用的时候如果你在controller连续两次调用service在调用mapper你会发现还是重复查询两次数据库,但是在service中重复调用mapper你就会发现只会调用一次数据库,这是由差别的。另外每次执行insert  update   delete都会清除一级缓存。

 

二级缓存配置首先需要在Mybatis配置文件中添加

<setting name="cacheEnabled" value="true"/>
然后需要在对应的mapper.xml配置文件中添加

<cache eviction="LRU" flushInterval="60000" size="1024" readOnly="true"/>

非只读的缓存每次响应的时候会通过序列化响应缓存内容的副本,Mybatis默认使用的缓存是基于Map的缓存,同样可以集成其他的缓存框架。

 

使用ehcache缓存框架,分布式缓存,并且支持内存硬盘双模式

首先需要添加对应的依赖,然后添加ehcache.xml配置文件

pom.xml添加

<dependency>
        <groupId>org.mybatis.caches</groupId>
        <artifactId>mybatis-ehcache</artifactId>
    </dependency>

ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false"
        monitoring="autodetect"
        dynamicConfig="true">
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="20000"
        eternal="false"
        copyOnRead="true"
        copyOnWrite="true"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        diskPersistent="false"
    />
</ehcache>

最后需要在Mapper.xml文件中添加

<cache type="org.springframework.cache.ehcache.EhCacheCache"./>

使用redis实现二级缓存

需要添加对jedis的支持以及mybatis-redis支持

<dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.caches</groupId>
        <artifactId>mybatis-redis</artifactId>
    </dependency>

然后添加mybatis-redis配置文件redis.properties

host=127.0.0.1
port=6379
password=
connectionTimeout=5000
soTimeout=5000
database=
clientName=

最后修改mapper.xml中的内容

<cache type="org.mybatis.caches.redis.RedisCache"/>

另外多表查询的时候有可能会产生脏数据,因为他们的命名空间是不一样的,因此一个命名空间内容修改了并不能更新另一个命名空间的缓存,因此会产生脏数据。

第七部分:细节注意事项

                 1.主键自增

                      如果数据库支持主键自增

<!-- 主键联合索引需要设置keuColume="key1,key2" 同样keyproperty -->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    </insert>

如果数据库不支持主键自增

<!-- mysql是AFTER oracle是before  因为支持主键自增的都是插入完了以后才能获取到主键,不支持主键自增的,需要先查询序列因此是before -->
        <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="long">
        </selectKey>

selectKey是用来获取主键的,当批量向oracle这种只能通过查询序列获取主键的时候可以这样使用

<selectkey>

</selectKey>

insert  XXX

foreach的形式就可以了。

                  2.为了防止HTTP请求中的数据有啥编码问题,加入如下内容

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>*</url-pattern>
    </filter-mapping>

                3.目前mybatis可以自动区分出来参数的内容,因此所有的标签parameterType可以不用配置

                4.数据库datetime类型的字段可以保存date timestamp两种类型的数据,但是没办法保存time数据

                5.写参数的时候直接在接口Mapper上面使用@Param注解,会自动创建Map的。

                6.${value}这种东西不能避免SQL注入

第八部分:附录

                  1.项目依赖打算使用Maven

                   2.数据库使用Mysql

                   3.使用SpringMVC4+spring4+mybatis3整合的形式运行代码

                   4.JDK我要求至少1.7,我家里用的10

本文章不推荐将SQL语句注解到Java类的mapper接口上去,不想修改一个sql还要重新编译一遍,思想是Xml配置+注解,我也不打算讲解代码生成器那些东西,我知道Mybatis有响应的插件,因为以后维护起来可能会比较麻烦。

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值