Java框架之Mybatis(二)

Wesley13
• 阅读 404

本文主要介绍 Mybatis(一)之后剩下的内容:

1 mybatis 中 log4j的配置

2 dao层的开发(使用mapper代理的方式)

3 mybatis的配置详解

4 输入输出映射对应的类型 ( parameterType 和 resultType )

5 mybatis 动态 sql

6 mybatis 中的一级缓存

7 mybatis 中的二级缓存

8 mybatis 和 缓存框架的整合

9 mybatis 中二级缓存使用时注意的问题

10 mybatis 和 spring 整合

11 mybatis + spring mvc

一、mybatis 中 log4j 的配置

在 config 文件夹下,新建 log4j.properties ,其内容如下:  即可

log4j.rootLogger=DEBUG, Console

#Console

log4j.appender.Console=org.apache.log4j.ConsoleAppender

log4j.appender.Console.layout=org.apache.log4j.PatternLayout

log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n        

log4j.logger.java.sql.ResultSet=INFO

log4j.logger.org.apache=INFO

log4j.logger.java.sql.Connection=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

二、dao层的开发(使用mapper代理的方式)

使用mapper代理的方式 ,只需要mapper接口(相当于dao接口)即可,不用完实现类了。

程序员只需要写 mapper接口 ,必须遵守一定的规范

-- UserMapper.xml , namepsace 属性 等于接口的全路径名

-- mapper接口中的方法名,要和映射文件中的sql的id相同 (statement 的 id)

-- mapper接口中方法的参数类型和返回值类型也要和映射文件中的  parameterType, resultType 一致

mybatis 就可以自动生成mapper接口实现类的代理对象

  1. 创建mapper接口

    //相当于IUserDao public interface UserMapper { UserInfo getuser_byid(int id); int add_user(UserInfo user); //其实这里用int 型的返回值也行,能返回来 }

 2)创建配置文件 UserMapper.xml

和原来的UserInfo.xml配置基本一样,只要改动下面的这句即可

<mapper namespace="cat.mapper.UserMapper">

不要忘了在主配置文件中引入

<mappers>
        <mapper resource="mapper/UserMapper.xml" />
</mappers>

3)使用

static void test() throws IOException{
                                InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                                SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                                SqlSession session =factor.openSession();
                                
                                //由mybatsi生成一个UserMapper的实现类的一个对象
                                UserMapper userMapper=session.getMapper(UserMapper.class);
                                UserInfo user=userMapper.getuser_byid(2);        
                                System.out.println(user);
                        
                                session.close();
                            }
                                  
                                  
                        //附注: 如果方法的参数,有多个, parameterType 要怎么写 ?可以使用pojo类型,或 使用 map

三、mybatis的配置详解

properties : 用于配置属性信息

settings : 用于配置mybatis的运行方式

typeAliases : 用于配置类型别名

typeHandlers:用于配置类型处理器

plugins :配置拦截器

environments :用于配置数据源,连接池,事务属性等

mappers : 配置sql映射文件

  1. properties

这些是外部化的, 可替代的属性, 这些属性也可以配置在典型的 Java 属性配置文件中, 或者通过 properties 元素的子元素来传递。例如:

<properties resource="org/mybatis/example/config.properties">
            <property name="username" value="dev_user"/>
            <property name="password" value="F2Fa3!33TYyg"/>
</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>

这个例子中的 username 和 password 将会由 properties 元素中设置的值来替换。 driver 和 url 属性将会从包含进来的 config.properties 文件中的值来替换。这里提供很多配置的选项。

如果在这些地方,属性多于一个的话,MyBatis 按照如下的顺序加载它们:

在 properties 元素体内指定的属性首先被读取。从类路径下资源或 properties 元素的 url 属性中加载的属性第二被读取,它会 覆盖已经存在的完全一样的属性。作为方法参数传递的属性最后被读取, 它也会覆盖任一已经存在的完全一样的 属性,这些属性可能是从 properties 元素体内和资源/url 属性中加载的。因此, 最高优先级的属性是那些作为方法参数的, 然后是资源/url 属性, 最后是 properties 元素中指定的属性。

  1. settings 用于配置mybatis的运行方式

  2. typeAliases 配置类型别名

    //单个别名的定义

    //批量别名的定义,会把beans包下的所有的类名定义成别名,首字母大小写均可 -->

  3. typeHandlers:用于配置类型处理器

mybatis 中通过它完成java类型和jdbc类型的转换,通常mybatis提供的都够用,不用自定义。

  1. plugins  略

  2. environments

    //例

  3. mappers 用于引入sql配置文件的

    //例如 // 有几下几种方式

    // 1.相对于类路径的引入方式

    //2.使用全路径引入

    //3.使用类名包等

    //命名规范 类名必须是 UserMapper 这样的,而且映射文件要和接口文件放在同一个文件夹下

    //3.使用mapper方式批量加载

    批量加载 cat.mapper包下的所有mapper

四、输入输出映射对应的类型 ( parameterType 和 resultType )

  1. 输入参数的类型 parameterType

    insert into userInfo (userName,password,note) values (#{userName},#{password}, #{note} )

这里的 parameterType 可以传的类型有几以下几种

1.简单类型

2.pojo

3.hashmap

4.包装过的pojo

//例子 使用 hashmap 做为 parameterType
<select id="get_login_user" parameterType="java.util.HashMap" resultType="userInfo" >
        select * from userInfo where userName=#{userName} and password= #{password}
</select>
                        
        static void test2() throws IOException{
                            InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                            SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                            SqlSession session =factor.openSession();
                            UserMapper userMapper=session.getMapper(UserMapper.class);
                            HashMap map=new HashMap();
                            map.put("userName", "高洪喜");
                            map.put("password", "admin");
                            UserInfo user=userMapper.get_login_user(map);
                            System.out.println(user);
                            session.close();
                        }

附:

<select id="get_login_user" parameterType="java.util.HashMap" resultType="userInfo" >
        select userName,password as pwd,note  from userInfo where userName=#{userName} and password= #{password}
</select>
                        
//上面的查询,对于 password 多了一个as pwd,结果发现查询出来的目标对象的password是null 
//只要有一个属性和类中的属性对上了,它就创建类对象

2)输出参数的类型  resultType

输出参数的类型有两种  一仩是 resultType  一个是  resultMap

//resultMap的使用
<select id="get_login_user" parameterType="java.util.HashMap" resultMap="userInfoResultMap" > //这里的返回类型 resultMap
        select userName as uname,password as pwd,note  from userInfo where userName=#{userName} and password= #{password}
</select>
       
<resultMap id="userInfoResultMap" type="userInfo">
        <id property ="id" column="id" />  //这列特殊,用来指定id
        <result property="userName" column="uname" />
        <result property="password" column="pwd" />
</resultMap>
                       
//说明: 如果 userInfoResultMap 是配置在别的配置文件中的,在使用的时候要加上它的namespace

五、mybatis 动态 sql

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。

MyBatis中用于实现动态SQL的元素主要有:

if

choose(when,otherwise)

trim

where

set

foreach

1)if

<select id="get_userList" parameterType="userInfo" resultType="userInfo" >
        select * from userInfo where 1 = 1
        <if test="id != 0">
            and id = #{id}
        </if>
        <if test="userName != null and userName !='' " >
            and userName = #{userName}
        </if>
        <if test="password != null and password!=''">
            and password = #{password}
        </if>
</select>

 2)foreach

主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。

item  集合中每一个元素进行迭代时的别名,

index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,

open  该语句以什么开始,

separator 每次进行迭代之间以什么符号作为分隔符,

注意:close 在什么结束?

在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须的,不同情况下,值是不同的,主要有 3 种情况:

如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

如果传入的是单参数且参数类型是一个array 数组的时候,collection的属性值为array

如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key。

/* 以下面个写法来自网上,没有测试 
<select id="dynamicForeachTest" resultType="Blog">
        select * from t_blog where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
        #{item}
</foreach>
</select>
                                
        <if test="ids!=null">
<foreach collection="ids" item="userid" open=" and (" close=")" separator="or">
        <!-- 遍历拼接的串 -->
        id=#{id}
</foreach>
        </if>
                            
         比如 where id in(1,3,6)
                            
          <if test="ids!=null">
               <foreach collection="ids" item="userid" open=" and id in (" close=")" separator=",">
               <!-- 遍历拼接的串 -->
               #{id}
               </foreach>
          </if>
*/

//例子
<select id="getuser_by_ids" resultType="cat.beans.UserInfo" parameterType="list">  //注意,这里的 parameterType 给的是list
        select * from UserInfo where id in
        <foreach collection="list" item="userid" open=" (" close=")" separator=",">
        #{userid}
        </foreach>                     
</select>
                                
//上面的写法 collection = ids 这样写可能是因为 它的paramenter type指定成 dto 中的 ids了     
  1. where 主要用来简化where语句中的条件判断

就是把if 那个例子中的  where 1=1 换成了

<where>
      <if test="id != 0">
          and id = #{id}
      </if>
      <if test="userName != null and userName !='' " >
          and userName = #{userName}
      </if>
      <if test="password != null and password!=''">
          and password = #{password}
     </if>
< /where>

sql片段:

// 声明一个sql片段 在这个片断中尽量不要写where 
<sql id="query_user_condation">
     <if test="id != 0">
         and id = #{id}
     </if>
     <if test="userName != null and userName !='' " >
         and userName = #{userName}
     </if>
     <if test="password != null and password!=''">
         and password = #{password}
     </if>
</sql>
                   
//引用sql片段
<select id="get_userlist" parameterType="userInfo"  resultType="userInfo" >
        select * from userInfo
        <where>
               <include refid="query_user_condation" /> 
                        and note ='这是note'
        </where> 
</select>

六、mybatis 中的一级缓存

mybatis 中的一级缓存是在一个Session域内, session未关闭的时候执行查询会根据sql的key进行缓存,如果对缓存的数据进行了增删改等操作,会清除缓存

mybatis 默认支持一级缓存。

static void test4() throws IOException{
                InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
                SqlSessionFactory factor=new SqlSessionFactoryBuilder().build(in);
                SqlSession session =factor.openSession();
                
                UserMapper userMapper=session.getMapper(UserMapper.class);
                
                UserInfo user=userMapper.getuser_byid(2); 
                UserInfo user2=userMapper.getuser_byid(2);  //输出一条查询语句,证明用了一级缓存
                
                session.close();
            }

七、mybatis 中的二级缓存

二级缓存和一级缓存的机制相同,默认也是采用 PerpetualCache (其实就是mybatis 中Cache 这个的接口的实现类)它也是用hashmap进行存储,它和一级缓存的不同 是它的作用域 Mapper ( namespace ) 就是同一个 namespace 共享一份缓存,可以自定义存储源 比如Ehcache 等。

对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

代码实例:二级缓存测试

  1. 开启二级缓存

    //这样就可以开启 ....

2)代码

static void test5() throws IOException{
                        InputStream in = Test.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");    
                        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
                        
                        SqlSession session1=factory.openSession();
                        SqlSession session2=factory.openSession();  //用的是两个不同的session
                        
                        
                        UserMapper userMapper1=session1.getMapper(UserMapper.class);
                        UserMapper userMapper2=session2.getMapper(UserMapper.class);
                        
                        UserInfo user=userMapper1.getuser_byid(2);
                        
                        session1.close();
                        UserInfo user2=userMapper2.getuser_byid(2);  //结果就输出一条查询语句,可以证明使用的是二级缓存
                        
                        session2.close();
                        
                        System.out.println(user);
                }
  1. 关于二级缓存的说明

== 要进行缓存的实体类要实现  Serializable 接口

== 映射文件中的所有的select 语句都会被缓存

== 映射文件中的所有的inser,updage,delete 相关的语句都会清除缓存

== 缓存会使用Last Recently Used(LRU,最近最少使用的)算法来收回

== 缓存会根据指定的时间间隔来刷新

== 缓存默认会存储1024个对象

  1. catch 标签的常用属性

    <cache eviction="FIFO" //回收策略为先进先出 flushInterval="60000" //自动刷新时间60s size="512" //最多缓存512个引用对象 readOnly="true" //只读 // type="org.mybatis.caches.ehcache.LoggingEhcache" 可以用type属性指定缓存提供者 />

5)  MyBatis中有flushCache、useCache这两个配置属性,分为下面几种情况

(1)当为select语句时:

flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。

useCache默认为true,表示会将本条语句的结果进行二级缓存。

(2)当为insert、update、delete语句时:

flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。

useCache属性在该情况下没有。

上面的信息来自 MyBatis官方文档。如果有必要,那么就需要人工修改配置,修改结果类似下面:

<select id="save" parameterType="XXXXXEO" statementType="CALLABLE" flushCache="true" useCache="false">
                                ……
</select>

八、mybatis 和 缓存框架的整合

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。

Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

Ehcache最初是由Greg Luck于2003年开始开发。2009年,该项目被Terracotta购买。软件仍然是开源,但一些新的主要功能。(例如,快速可重启性之间的一致性的)只能在商业产品中使用,例如Enterprise EHCache and BigMemory。, 维基媒体Foundationannounced目前使用的就是Ehcache技术。

mybatis 和 eache 的整合

  1. 导包

mybatis-ehcache-1.0.3.jar

ehcache-core-2.6.8.jar

slf4j-api-1.6.1.jar

<mapper namespace="cat.mapper.UserMapper" >
//mybatis ehcache缓存配置 -->
//以下两个<cache>标签二选一,第一个可以输出日志,第二个不输出日志
    <cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
    <cache type="org.mybatis.caches.ehcache.EhcacheCache" /> 
                                 
    ....
</mapper>

附加说明 : mybatis 提供了Cache 这样一个接口,它自己的默认实现类是 PerpetualCache

public abstract interface org.apache.ibatis.cache.Cache { 
                                      public abstract java.lang.String getId();
                                      public abstract void putObject(java.lang.Object arg0, java.lang.Object arg1);
                                      public abstract java.lang.Object getObject(java.lang.Object arg0);
                                      public abstract java.lang.Object removeObject(java.lang.Object arg0);
                                      public abstract void clear();
                                      public abstract int getSize();
                                      public abstract java.util.concurrent.locks.ReadWriteLock getReadWriteLock();
                                }

3)  ehcache 的配置文件 ehcache.xml  (这是全部内容) // 放在config目录下(类路径下)即可

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false">
    <diskStore path="java.io.tmpdir/mybatis/g" />  //如果往磁盘上放,默认放在哪个目录
                                
    <!-- DefaultCache setting. -->
    <defaultCache
                 maxEntriesLocalHeap="10000"
                 eternal="false"
                 timeToIdleSeconds="300"
                 timeToLiveSeconds="600"
                 overflowToDisk="true"
                 maxEntriesLocalDisk="100000"
                 memoryStoreEvictionPolicy="LFU"/>
                                    
    <!-- security entity-->
                 <cache
                        name="entityCache"
                        maxEntriesLocalHeap="10000"
                        eternal="true"
                        overflowToDisk="true"
                        maxEntriesLocalDisk="1000000" />
                 </ehcache>

九、mybatis 中二级缓存使用时注意的问题

  1. 只能在【只有单表操作】的表上使用缓存

不只是要保证这个表在整个系统中只有单表操作,而且和该表有关的全部操作必须全部在一个namespace下。

  1. 在可以保证查询远远大于insert,update,delete操作的情况下使用缓存。这一点不需要多说,所有人都应该清楚。记住,这一点需要保证在1的前提下才可以!

可能会有很多人不理解这里,二级缓存带来的好处远远比不上他所隐藏的危害。

缓存是以namespace为单位的,不同namespace下的操作互不影响。

insert,update,delete操作会清空所在namespace下的全部缓存。通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。

为什么避免使用二级缓存 ?

在符合【Cache使用时的注意事项】的要求时,并没有什么危害。

其他情况就会有很多危害了。

1)针对一个表的某些操作不在他独立的namespace下进行。

例如在UserMapper.xml中有大多数针对user表的操作。但是在一个XXXMapper.xml中,还有针对user单表的操作。这会导致user在两个命名空间下的数据不一致。如果在UserMapper.xml中做了刷新缓存的操作,在XXXMapper.xml中缓存仍然有效,如果有针对user的单表查询,使用缓存的结果可能会不正确。

更危险的情况是在XXXMapper.xml做了insert,update,delete操作时,会导致UserMapper.xml中的各种操作充满未知和风险。有关这样单表的操作可能不常见。但是你也许想到了一种常见的情况。

多表操作一定不能使用缓存 为什么不能?

首先不管多表操作写到那个namespace下,都会存在某个表不在这个namespace下的情况。

例如两个表:role和user_role,如果我想查询出某个用户的全部角色role,就一定会涉及到多表的操作。

<select id="selectUserRoles" resultType="UserRoleVO">
        select * from user_role a,role b where a.roleid = b.roleid and a.userid = #{userid}
</select>

像上面这个查询,你会写到那个xml中呢??

不管是写到RoleMapper.xml还是UserRoleMapper.xml,或者是一个独立的XxxMapper.xml中。如果使用了二级缓存,都会导致上面这个查询结果可能不正确。

如果你正好修改了这个用户的角色,上面这个查询使用缓存的时候结果就是错的。这点应该很容易理解。在我看来,就以MyBatis目前的缓存方式来看是无解的。多表操作根本不能缓存。如果你让他们都使用同一个namespace(通过)来避免脏数据,那就失去了缓存的意义。看到这里,实际上就是说,二级缓存不能用。整篇文章介绍这么多也没什么用了。

十、mybatis 和 spring 整合

最主要的,就是把 SessionFactory 的创建交给Spring

  1. 导jar包

  2. 工程结构

  3. 配置spring的主配置文件 applicationContext.xml

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <context:property-placeholder location="classpath:mydbconfig.properties" />

    //数据源

    //配置sqlSessionFacory

  4. 配置 mybatis  的主配置文件 SqlMapConfig.xml

       <mappers>
         <package name="cat.mapper" />    
       </mappers>
    
  5. 配置映射文件  UserMapper.xml //和过去一样,没有任何区别

           <mapper namespace="cat.mapper.UserMapper" >
           <cache/>
                                
    
           <sql id="query_user_condation">
            <if test="id != 0">
                 and id = #{id}
            </if>
            <if test="userName != null and userName !='' " >
                  and userName = #{userName}
            </if>
            <if test="password != null and password!=''">
                  and password = #{password}
            </if>
            </sql>
                                
            <!--    引用sql片断 -->
            <select id="get_userlist" parameterType="userInfo"  resultType="userInfo" >
                  select * from userInfo
              <where>
                  <include refid="query_user_condation" /> 
                           and note ='这是note'
              </where>
                                      
            </select>
                                
            <resultMap id="userInfoResultMap" type="userInfo">
                       <id property ="id" column="id" />
                       <result property="userName" column="uname" />
                       <result property="password" column="pwd" />
            </resultMap>
                                
                       <select id="getuser_byid"  parameterType="int" resultType="userInfo" >
                               select * from userInfo where id=#{id} 
                       </select>
                                            <select id="getuser_biname" parameterType="string" resultType="userInfo">
                               select * from userInfo where userName like  '%${value}%' 
                       </select>
                                 
            <!-- 对于添加这类方法,是没有resultType的 -->
                       <insert id="add_user" parameterType="userInfo"  >
                       <selectKey order="AFTER" keyProperty="id" resultType="int">  
                                select  last_insert_id()
                       </selectKey>
                                insert into userInfo (userName,password,note) values (#{userName},#{password}, #{note} ) 
                       </insert>
                                 
                       <select id="get_login_user" parameterType="java.util.HashMap" resultMap="userInfoResultMap" >
                                select userName as uname,password as pwd,note  from userInfo where userName=#{userName} and password= #{password}
                       </select>
                                 
                       <insert id="add_user_new" parameterType="userInfo"  >
                         <selectKey order="BEFORE" keyProperty="id" resultType="string">  
                                  select  uuid()
                         </selectKey>
                                     insert into userInfo (id,userName,password,note) values (#{id},#{userName},#{password}, #{note} ) 
                       </insert>
                                 
                       <delete id="deluser_byid" parameterType="int" > 
                                     delete from userInfo where id=#{id}
                       </delete>
                                 
                       <update id="update_user" parameterType="cat.beans.UserInfo" > <!-- 传过来的userInfo对象中要有id -->
                                    update userInfo set userName= #{userName},password= #{password}, note =#{note} where id= #{id}
                       </update>
                             
    
  6. 接口 UserMapper.java  //和过去一样

    public interface UserMapper { UserInfo getuser_byid(int id); int add_user(UserInfo user); //其实这里用int 型的返回值也行,能返回来 UserInfo get_login_user(HashMap map); Listget_userlist(UserInfo user); }

7)测试

ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
                    UserMapper userMapper=(UserMapper)context.getBean("userMapper");
                    
                    UserInfo user=userMapper.getuser_byid(2);
                    System.out.println(user);

 说明,关于spring中加载mapper

上面的例子中,如果有多个mapper ,则在spring 中要配置多次,很不方便。可以使用扫描的方式加载:

// 它来自mybatis-spring-1.2.2.jar -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  //由于是批量,就不用加id属性了
      <property name="basePackage" value="cat.dao" />
      <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
                         
//使用了这种方式以后,mybatis 主配置文件 SqlMapConfig 中的下面就可以不要了
<mappers>
      <package name="cat.mapper" />    
</mappers>

十一、mybatis + spring mvc

  1. 加入springmvc的配置文件


    <context:component-scan base-package="cat.controller" /> <mvc:annotation-driven />
    <mvc:resources location="/resource/" mapping="resources/**">

配置事物管理器

<aop:config>
     <aop:pointcut id="myTxPointCut"  expression="execution(* cat.service.impl.*.*(..))" /> 
     <aop:advisor advice-ref="txActive" pointcut-ref="myTxPointCut"/> 
</aop:config>
                      
<tx:advice id="txActive" transaction-manager="txManager">
           <tx:attributes>
           <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/>
           <tx:method name="update*" propagation="REQUIRED"  />
           <tx:method name="insert*" propagation="REQUIRED"  />
           <tx:method name="del*" propagation="REQUIRED"  />
           <tx:method name="add*" propagation="REQUIRED"  />
           </tx:attributes>
</tx:advice>
  1. 在web.xml中配置 (一是配置spring, 是配置核心控制器)

    //加载spring主配置文件

    contextConfigLocation classpath:spring/applicationContext.xml org.springframework.web.context.ContextLoaderListener

    //配置springmvc的核心控制器

    springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:spring/springmvc.xml 1 springmvc /
  2. Action的配置

    @Controller public class UserAction {

                         @Resource
                         private UserMapper mapper;
                         
                         @RequestMapping("/get_user")
                         public ModelAndView getUser(){
                             ModelAndView mv=new ModelAndView();
                             UserInfo user=mapper.getuser_byid(2);
                             System.out.println(user);
                             mv.addObject("user", user);
                             mv.setViewName("show_user");
                             return mv;
                         }
                     }
    
点赞
收藏
评论区
推荐文章
技术小男生 技术小男生
1个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi /etc/profile2:按字母键i进入编辑模式,在最底部添加内容: JAVAHOME/opt/jdk1.8.0152 CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jar PATH$JAVAHOME/bin:$PATH3:生效配置
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
Wesley13 Wesley13
1年前
Java爬虫之JSoup使用教程
title: Java爬虫之JSoup使用教程 date: 2018-12-24 8:00:00 +0800 update: 2018-12-24 8:00:00 +0800 author: me cover: [https://img-blog.csdnimg.cn/20181224144920712](https://www.oschin
Wesley13 Wesley13
1年前
030 SSM综合练习06
**1.权限操作涉及的三张表** (1)用户表信息描述users ![](https://oscimg.oschina.net/oscnet/a4a2b1f943cbc2db1c8ddd613e7ed00a9ae.png) sql语句: CREATE TABLE users ( id VARCHAR2 ( 32 ) DEFAU
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置 1、virsh edit centos7 找到“memory”和“vcpu”标签,将 <name>centos7</name> <uuid>2220a6d1-a36a-4fbb-8523-e078b3dfe795</uuid>
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
Stella981 Stella981
1年前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
helloworld_34035044 helloworld_34035044
4个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为