MyBatis3与Spring3的整合配置(初级篇)

1. 环境

mybatis-3.2版本,jdk1.6版本,Oracle数据库,spring3.2版本

2. 功能

MyBatis3入门三(增加、删除、修改、查询,自增长,允许空值,封装Mapper),目标是把上一篇实现的功能,结合spring实现。

3. spring环境准备

1). 首先需要下载mybatis-spring-1.1.1.jar

2). Spring的XML配置文件中加入:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:config/mybatis-module.xml" />
    </bean>

3). 假设已经有一个写好的数据映射器类(ProductMapper.java及ProductMapper.xml)

4). Spring的XML配置文件中加入:

    <bean id="productMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.clzhang.sample.struts2.mapper.ProductMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

5). 配置好后,在业务类中只需要:

    public class FooServiceImpl implements FooService {
    private ProductMapper productMapper;
    public void setProductMapper(ProductMapper productMapper) {
        this.productMapper = productMapper;
    }
    
    public void doBusinessStuff(int prodId) {
        ProductBean entity = productMapper.getProduct(prodId);
        ......
    }
    }

4. 环境准备

4.1 下载mybatis-3.2,需要引用其中的若干包;下载mybatis-spring-1.1.1.jar,略。

参考:MyBatis3入门级示范一(查询,插入)

4.2 项目的结构

4.3 假定数据库已经创建,表结构也已经创建,并且有测试数据

参考:MyBatis3入门三(增加、删除、修改、查询,自增长,允许空值,封装Mapper)

5. 具体步骤

5.1 创建entity类

package com.clzhang.sample.struts2.mapper.entity;

import java.sql.Timestamp;

/**
 * 数据库实体类,可以借助工具自动生成此类;
 * 也可以自己写一个程序从数据库读取数据,然后生成此类。
 * @author acer
 *
 */
public class ProductBean {
    
    private int prodId;
    private String prodSerial;
    private String prodName;
    private String categoryname;
    private String prodSpec;
    private double prodPrice;
    private String prodDesc;
    private String prodImage;
    private int isNew;
    private int isRecommend;
    private int isShow;
    private String username;
    private Timestamp handletime;
    private String prodThumbnail;

      public int getProdId() {
        return prodId;
    }


    public void setProdId(int prodId) {
        this.prodId = prodId;
    }


    public String getProdSerial() {
        return prodSerial;
    }


    public void setProdSerial(String prodSerial) {
        this.prodSerial = prodSerial;
    }


    public String getProdName() {
        return prodName;
    }


    public void setProdName(String prodName) {
        this.prodName = prodName;
    }


    public String getCategoryname() {
        return categoryname;
    }


    public void setCategoryname(String categoryname) {
        this.categoryname = categoryname;
    }


    public String getProdSpec() {
        return prodSpec;
    }


    public void setProdSpec(String prodSpec) {
        this.prodSpec = prodSpec;
    }


    public double getProdPrice() {
        return prodPrice;
    }


    public void setProdPrice(double prodPrice) {
        this.prodPrice = prodPrice;
    }


    public String getProdDesc() {
        return prodDesc;
    }


    public void setProdDesc(String prodDesc) {
        this.prodDesc = prodDesc;
    }


    public String getProdImage() {
        return prodImage;
    }


    public void setProdImage(String prodImage) {
        this.prodImage = prodImage;
    }


    public int getIsNew() {
        return isNew;
    }


    public void setIsNew(int isNew) {
        this.isNew = isNew;
    }


    public int getIsRecommend() {
        return isRecommend;
    }


    public void setIsRecommend(int isRecommend) {
        this.isRecommend = isRecommend;
    }


    public int getIsShow() {
        return isShow;
    }


    public void setIsShow(int isShow) {
        this.isShow = isShow;
    }


    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }


    public Timestamp getHandletime() {
        return handletime;
    }


    public void setHandletime(Timestamp handletime) {
        this.handletime = handletime;
    }


    public String getProdThumbnail() {
        return prodThumbnail;
    }


    public void setProdThumbnail(String prodThumbnail) {
        this.prodThumbnail = prodThumbnail;
    }

}

5.2 创建mapper接口类

package com.clzhang.sample.struts2.mapper;

import java.util.*;

import com.clzhang.sample.struts2.mapper.entity.ProductBean;

/**
 * 一个简单的CRUD操作示范类,接口
 * @author Administrator
 *
 */
public interface ProductMapper {
    public void insertProduct(ProductBean product);    
    public void updateProduct(ProductBean product);    
    public void deleteProduct(int prodId); 
    
    public ProductBean getProduct(int prodId); 
    public List<ProductBean> getProdByCategory(String categoryName); 
}

5.3 创建jdbc.properties文件,位置于resources/config目录

#main database settings
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
jdbc.username=mytest
jdbc.password=test001

5.4 创建mybatis-module.xml配置文件,位置于resources/config目录

<?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>
        <!--这些是极其重要的调整, 它们会修改 MyBatis 在运行时的行为方式。-->
        <setting name="cacheEnabled" value="false"/>
        <setting name="useGeneratedKeys" value="false"/>
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <setting name="jdbcTypeForNull" value="OTHER"/>
    </settings>
    <typeAliases> 
       <!--
        类型别名是为 Java 类型命名一个短的名字。它只和 XML 配置有关, 只用来减少类完全限定名的多余部分。
        You can also specify a package where MyBatis will search for beans. For example
        <typeAliases>
            <package name="domain.blog"/>
        </typeAliases>
        ......
       -->
       <typeAlias alias="Product" type="com.clzhang.sample.struts2.mapper.entity.ProductBean"/> 
    </typeAliases> 
    <mappers> 
        <mapper resource="com/clzhang/sample/struts2/mapper/ProductMapper.xml" />
        <!--其它装载方式
        <mapper url="file:///var/mappers/AuthorMapper.xml"/>
        <mapper class="org.mybatis.builder.BlogMapper"/>
        -->
    </mappers> 
</configuration>

5.5 创建ProductMapper.xml配置文件,位置于:resources\com\clzhang\sample\struts2\mapper\

<?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">

<!--
1.namespace的值可以设置得非常短比如:ProductMapper,如果项目不大的情况下,可以考虑这样使用。
好处是在Java代码如下调用即可:session.insert("ProductMapper.insertProduct", product);
2.如果项目非常大的话(或者是与Spring整合),那么还是建议使用长文件名做标识。
-->
<mapper namespace="com.clzhang.sample.struts2.mapper.ProductMapper">
    <!--
    默认情况下是没有开启缓存的,下条代码是开启二级缓存的,作用如下:
    1.•映射语句文件中的所有 select 语句将会被缓存。
    2.•映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
    3.•缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
    ......
    -->
    <cache />
    
    <!-- 用来定义可重用的SQL代码段 -->
    <sql id="selectProdSQL">
       PRODID,PRODSERIAL,PRODNAME,CATEGORYNAME,PRODSPEC,PRODPRICE,PRODDESC,PRODIMAGE,ISNEW,ISRECOMMEND,ISSHOW,USERNAME,HANDLETIME,PRODTHUMBNAIL
    </sql>

    <!--以单个对象方式返回-->
    <select id="getProduct" resultType="Product" parameterType="int">
    select <include refid="selectProdSQL"/>
      FROM PRODUCT
    WHERE PRODID = #{prodId}
    </select>

    <resultMap type="Product" id="prodByCategoryMap">  
        <id property="prodId" column="prodId"/>  
        <!--有需要做数据库到实体类名称转换的,可以写在这里-->
        <!--
        <result property="objname" column="dbname"/>
        -->
    </resultMap>  

    <!--以List方式返回多个结果-->
    <select id="getProdByCategory" resultMap="prodByCategoryMap" parameterType="string">
    select <include refid="selectProdSQL"/>
      FROM PRODUCT
    WHERE CATEGORYNAME = #{categoryName}
    </select>
    
    <!--Oracle的实现自增长主键的方式-->
    <!--对于数据库中允许为空的字段,需要在这里指定字段类型,因为MyBatis不知道你传入的 null 参数对应的 jdbc 类型是什么;如何没有指定,则需要在插入数据时全部字段都要设置值,哪怕是空值!-->
    <insert id="insertProduct" parameterType="Product">
    <selectKey keyProperty="prodId" resultType="int" order="BEFORE">
      select SEQ_PRODUCT.nextval from DUAL
    </selectKey>
      INSERT INTO PRODUCT (PRODID,PRODSERIAL,PRODNAME,CATEGORYNAME,PRODSPEC,PRODPRICE,PRODDESC,PRODIMAGE,ISNEW,ISRECOMMEND,ISSHOW,USERNAME,HANDLETIME,PRODTHUMBNAIL)
      VALUES(#{prodId}, #{prodSerial,jdbcType=VARCHAR}, #{prodName}, #{categoryname,jdbcType=VARCHAR}, #{prodSpec,jdbcType=VARCHAR}, #{prodPrice,jdbcType=DOUBLE}, 
      #{prodDesc,jdbcType=VARCHAR}, #{prodImage,jdbcType=VARCHAR}, #{isNew}, #{isRecommend}, #{isShow}, #{username}, #{handletime,jdbcType=DATE}, #{prodThumbnail,jdbcType=VARCHAR})
    </insert>

    <update id="updateProduct" parameterType="Product">
      update PRODUCT set
        PRODSERIAL = #{prodSerial,jdbcType=VARCHAR},
        PRODNAME = #{prodName},
        CATEGORYNAME = #{categoryname,jdbcType=VARCHAR},
        PRODSPEC = #{prodSpec,jdbcType=VARCHAR},
        PRODPRICE = #{prodPrice,jdbcType=DOUBLE},
        PRODDESC = #{prodDesc,jdbcType=VARCHAR},
        PRODIMAGE = #{prodImage,jdbcType=VARCHAR},
        ISNEW = #{isNew},
        ISRECOMMEND = #{isRecommend},
        ISSHOW = #{isShow},
        USERNAME = #{username},
        HANDLETIME = #{handletime,jdbcType=DATE},
        PRODTHUMBNAIL = #{prodThumbnail,jdbcType=VARCHAR}
      where PRODID = #{prodId}
    </update>

    <delete id="deleteProduct" parameterType="int">
      delete from PRODUCT where PRODID = #{prodId}
    </delete>
</mapper>

5.6 创建applicationContext-common.xml配置文件,位置于resources/config目录

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd 
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"
    default-autowire="byName" default-lazy-init="true">

    <!-- 属性文件读入 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/jdbc.properties</value>
            </list>
        </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>

    <!-- 配置sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:config/mybatis-module.xml" />
    </bean>

    <!-- 配置sqlSession,待用;注:SqlSessionTemplate实现了SqlSession,且是线程安全的。第二个参数含义是允许你做批量。 -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
        <!--
        <constructor-arg index="1" value="BATCH" />
        -->
    </bean>

    <!-- 开启Spring事务管理的标准配置 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 基于注解的事务,待用 -->
    <tx:annotation-driven transaction-manager="txManager" />
    

</beans>

5.7 创建applicationContext-service.xml配置文件,位置于resources/config目录

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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-3.0.xsd">
           
    <bean id="productMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.clzhang.sample.struts2.mapper.ProductMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

</beans>

5.8 创建测试类到了这里,代码就变得非常简单了

package com.clzhang.sample.struts2.test;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.clzhang.sample.struts2.mapper.entity.ProductBean;
import com.clzhang.sample.struts2.mapper.ProductMapper;

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration("classpath:config/applicationContext-*.xml")
public class MyBatisTest3 {
    @Autowired
    private ProductMapper productMapper;
    

    @Test
    public void testInsert() {
        ProductBean entity = new ProductBean();
        
        // 注意:因数的ProductMapper.xml中已经设置了字段空值时如果处理,所以此处不一定要设置实体的所有属性。
        entity.setProdName("相册");
        entity.setIsNew(0);
        entity.setIsRecommend(0);
        entity.setIsShow(0);
        entity.setUsername("admin");
        productMapper.insertProduct(entity);
        
        System.out.println("新加的实体主键:" + entity.getProdId());
    }

    @Test
    public void testUpdate() {
        int prodId = 63;
        
        ProductBean entity = productMapper.getProduct(prodId);
        entity.setProdName("新产品");
        
        productMapper.updateProduct(entity);
    }

    @Test
    public void testDelete() {
        int prodId = 64;

        productMapper.deleteProduct(prodId);
    }

    @Test
    public void getProduct() {
        int prodId = 65;
        
        ProductBean entity = productMapper.getProduct(prodId);
        if(entity != null){
            System.out.println(entity.getProdName());
        }
        else{
            System.out.println("prodId不存在!" + prodId);
        }
        System.out.println("-------------------------------");
    }

    @Test
    public void getProdByCategoryName() {
        List<ProductBean> list = productMapper.getProdByCategory("套件");
        for(ProductBean entity: list) {
            System.out.println(entity.getProdName());
        }
        System.out.println("-------------------------------");
    }
}

输出结果:

新加的实体主键:68
相册
-------------------------------
图门
美好心情
123
大雅风尚
-------------------------------

posted @ 2013-03-13 21:47  那些年的事儿  阅读(965)  评论(0编辑  收藏  举报