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,略。
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
大雅风尚
-------------------------------