Top

JAVA Spring MyBatis DAY08

  1. Spring整合MyBatis案例-1
  2. Spring整合MyBatis案例-2
  3. Spring整合MyBatis案例-3
  4. 重构资费列表

1 Spring整合MyBatis案例-1

1.1 问题

使用MapperScannerConfigurer扫描所有Mapper映射器接口,实现Spring整合MyBatis,完成对员工表的查询。

1.2 方案

在applicationContext.xml中配置MapperScannerConfigurer,用它来自动扫描指定包下的所有Mapper映射器。

1.3 步骤

步骤一:创建项目,导入jar包

创建项目Spring08,导入jar包,如下图:

图-1

步骤二:配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下所有的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
	</bean>
	
</beans>

步骤三:创建实体类

创建员工实体类Emp,代码如下:

package com.tarena.entity;

import java.io.Serializable;
import java.sql.Date;

public class Emp implements Serializable{

	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Date hiredate;
	private Double sal;
	private Double comm;
	private Integer deptno;

	public Integer getEmpno() {
		return empno;
	}

	public void setEmpno(Integer empno) {
		this.empno = empno;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public Integer getMgr() {
		return mgr;
	}

	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}

	public Date getHiredate() {
		return hiredate;
	}

	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}

	public Double getSal() {
		return sal;
	}

	public void setSal(Double sal) {
		this.sal = sal;
	}

	public Double getComm() {
		return comm;
	}

	public void setComm(Double comm) {
		this.comm = comm;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

}

步骤四:创建Mapper映射器

创建Mapper映射器EmpMapper,代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.entity.Emp;

public interface EmpMapper {
	
	List<Emp> findAll();
	
}

步骤五:创建映射文件

创建映射文件EmpMapper.xml,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.EmpMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Emp">
		select * from t_emp
	</select>
	
</mapper>

步骤六:测试

创建测试类TestCase,代码如下:

package com.tarena.test;

import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptMapper;
import com.tarena.dao.EmpMapper;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;

public class TestCase {
	
	/**
	 * 查询所有员工
	 */
	@Test
	public void test1() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		EmpMapper mapper = 
			ctx.getBean("empMapper", EmpMapper.class);
		List<Emp> list = mapper.findAll();
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " + e.getEname());
		}
	}
	
}

执行该测试方法,结果如下图:

图-2

1.4 完整代码

applicationContext.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下所有的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
	</bean>
	
</beans>

Emp实体类完整代码如下:

package com.tarena.entity;

import java.io.Serializable;
import java.sql.Date;

public class Emp implements Serializable{

	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Date hiredate;
	private Double sal;
	private Double comm;
	private Integer deptno;

	public Integer getEmpno() {
		return empno;
	}

	public void setEmpno(Integer empno) {
		this.empno = empno;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public Integer getMgr() {
		return mgr;
	}

	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}

	public Date getHiredate() {
		return hiredate;
	}

	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}

	public Double getSal() {
		return sal;
	}

	public void setSal(Double sal) {
		this.sal = sal;
	}

	public Double getComm() {
		return comm;
	}

	public void setComm(Double comm) {
		this.comm = comm;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

}

EmpMapper完整代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.entity.Emp;

public interface EmpMapper {
	
	List<Emp> findAll();
	
}

EmpMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.EmpMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Emp">
		select * from t_emp
	</select>
	
</mapper>

TestCase完整代码如下:

package com.tarena.test;

import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptMapper;
import com.tarena.dao.EmpMapper;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;

public class TestCase {
	
	/**
	 * 查询所有员工
	 */
	@Test
	public void test1() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		EmpMapper mapper = 
			ctx.getBean("empMapper", EmpMapper.class);
		List<Emp> list = mapper.findAll();
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " + e.getEname());
		}
	}
	
}

2 Spring整合MyBatis案例-2

2.1 问题

使用MapperScannerConfigurer扫描带有注解的Mapper映射器接口,实现Spring整合MyBatis,完成对部门表的查询。

2.2 方案

创建一个自定义注解,然后在applicationContext.xml中配置MapperScannerConfigurer,用它来自动扫描指定包下的带有这个注解的Mapper映射器。

2.3 步骤

步骤一:创建自定义注解

创建自定义注解MyBatisRepository,代码如下:

package com.tarena.annotation;

//用于标识接口,方便MapperScannerConfigurer精确扫描
public @interface MyBatisRepository {

}

步骤二: 配置applicationContext.xml

创建一个新的Spring配置文件applicationContext-annotation.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下带有注解@MyBatisRepository的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
		<property name="annotationClass" 
			value="com.tarena.annotation.MyBatisRepository"/>
	</bean>
	
</beans>

步骤三:创建部门实体类

创建部门实体类Dept,代码如下:

package com.tarena.entity;

import java.io.Serializable;

public class Dept implements Serializable {

	private Integer deptno;
	private String dname;
	private String loc;

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

步骤四:创建部门映射器

创建部门映射器DeptMapper,代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptMapper {
	
	List<Dept> findAll();

	Dept findById(int id);
	
	void save(Dept dept);
	
	void update(Dept dept);
	
	void delete(int id);
	
}

步骤五:创建部门映射文件

创建部门映射文件,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.DeptMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Dept">
		select * from t_dept
	</select>
	
	<select id="findById"
		parameterType="int"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{id}
	</select>
	
	<insert id="save"
		parameterType="com.tarena.entity.Dept">
		insert into t_dept values(
			dept_seq.nextval,
			#{dname},
			#{loc}
		)
	</insert>
	
	<update id="update"
		parameterType="com.tarena.entity.Dept">
		update t_dept set
			dname=#{dname},
			loc=#{lco}
		where deptno=#{deptno}
	</update>
	
	<delete id="delete"
		parameterType="int">
		delete from t_dept
		where deptno=#{id}
	</delete>
	
</mapper>

步骤六:测试

在TestCase中增加测试方法,追加代码如下:

	/**
	 * 查询所有部门
	 */
	@Test
	public void test2() {
		String cfg = "applicationContext-annotation.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		DeptMapper mapper = 
			ctx.getBean("deptMapper", DeptMapper.class);
		List<Dept> list = mapper.findAll();
		for(Dept d : list) {
			System.out.println(
				d.getDeptno() + " " + d.getDname());
		}
	}

执行该测试方法,结果如下图:

图-3

2.4 完整代码

MyBatisRepository完整代码如下:

package com.tarena.annotation;

//用于标识接口,方便MapperScannerConfigurer精确扫描
public @interface MyBatisRepository {

}

applicationContext-annotation.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下带有注解@MyBatisRepository的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
		<property name="annotationClass" 
			value="com.tarena.annotation.MyBatisRepository"/>
	</bean>
	
</beans>

Dept完整代码如下:

package com.tarena.entity;

import java.io.Serializable;

public class Dept implements Serializable {

	private Integer deptno;
	private String dname;
	private String loc;

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

DeptMapper完整代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptMapper {
	
	List<Dept> findAll();

	Dept findById(int id);
	
	void save(Dept dept);
	
	void update(Dept dept);
	
	void delete(int id);
	
}

DeptMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.DeptMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Dept">
		select * from t_dept
	</select>
	
	<select id="findById"
		parameterType="int"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{id}
	</select>
	
	<insert id="save"
		parameterType="com.tarena.entity.Dept">
		insert into t_dept values(
			dept_seq.nextval,
			#{dname},
			#{loc}
		)
	</insert>
	
	<update id="update"
		parameterType="com.tarena.entity.Dept">
		update t_dept set
			dname=#{dname},
			loc=#{lco}
		where deptno=#{deptno}
	</update>
	
	<delete id="delete"
		parameterType="int">
		delete from t_dept
		where deptno=#{id}
	</delete>
	
</mapper>

TestCase完整代码如下:

package com.tarena.test;

import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptMapper;
import com.tarena.dao.EmpMapper;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;

public class TestCase {
	
	/**
	 * 查询所有员工
	 */
	@Test
	public void test1() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		EmpMapper mapper = 
			ctx.getBean("empMapper", EmpMapper.class);
		List<Emp> list = mapper.findAll();
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " + e.getEname());
		}
	}
	
	/**
	 * 查询所有部门
	 */
	@Test
	public void test2() {
		String cfg = "applicationContext-annotation.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		DeptMapper mapper = 
			ctx.getBean("deptMapper", DeptMapper.class);
		List<Dept> list = mapper.findAll();
		for(Dept d : list) {
			System.out.println(
				d.getDeptno() + " " + d.getDname());
		}
	}
	
}

3 Spring整合MyBatis案例-3

3.1 问题

使用SqlSessionTemplate的方式整合MyBatis,实现对部门表的增删改查。

3.2 方案

声明SqlSessionTemplate,并注入数据访问组件,利用它所提供的API,实现对部门表的增删改查。

3.3 步骤

步骤一:创建项目,导入jar包

创建项目Spring08-2,导入jar包,如下图:

图-4

步骤二: 配置applicationContext.xml

配置Spring配置文件applicationContext.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!--定义SqlSessionTemplate -->
	<bean id="sqlSessionTemplate" 
		class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory"/>
	</bean>

	<!-- 注解扫描 -->
	<context:component-scan base-package="com.tarena"/>
	
</beans>

步骤三:创建部门实体类

创建部门实体类Dept,代码如下:

package com.tarena.entity;

import java.io.Serializable;

public class Dept implements Serializable {

	private Integer deptno;
	private String dname;
	private String loc;

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

步骤四:创建部门映射文件

创建部门映射文件DeptMapper.xml,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.DeptMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Dept">
		select * from t_dept
	</select>
	
	<select id="findById"
		parameterType="int"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{id}
	</select>
	
	<insert id="save"
		parameterType="com.tarena.entity.Dept">
		insert into t_dept values(
			dept_seq.nextval,
			#{dname},
			#{loc}
		)
	</insert>
	
	<update id="update"
		parameterType="com.tarena.entity.Dept">
		update t_dept set
			dname=#{dname},
			loc=#{loc}
		where deptno=#{deptno}
	</update>
	
	<delete id="delete"
		parameterType="int">
		delete from t_dept
		where deptno=#{id}
	</delete>
	
</mapper>

步骤五:创建部门数据访问组件

创建部门数据访问组件MyBatisDeptDao,代码如下:

package com.tarena.dao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

import com.tarena.entity.Dept;

@Repository
public class MyBatisDeptDao implements Serializable {
	
	@Resource
	private SqlSessionTemplate template;

	public List<Dept> findAll() {
		return template.selectList("com.tarena.dao.DeptMapper.findAll");
	}

	public Dept findById(int id) {
		return template.selectOne("com.tarena.dao.DeptMapper.findById", id);
	}

	public void save(Dept dept) {
		template.insert("com.tarena.dao.DeptMapper.save", dept);
	}

	public void update(Dept dept) {
		template.update("com.tarena.dao.DeptMapper.update", dept);
	}

	public void delete(int id) {
		template.delete("com.tarena.dao.DeptMapper.delete", id);
	}

}

步骤六:测试

创建测试类TestCase,代码如下:

package com.tarena.test;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tarena.dao.MyBatisDeptDao;
import com.tarena.entity.Dept;

public class TestCase {
	
	
	/**
	 * DeptMapper.findAll()
	 */
	@Test
	public void test1() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		List<Dept> list = dao.findAll();
		for(Dept d : list) {
			System.out.println(
				d.getDeptno() + " " + d.getDname());
		}
	}
	
	/**
	 * DeptMapper.findById()
	 */
	@Test
	public void test2() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept dept = dao.findById(1);
		System.out.println(
			dept.getDeptno() + " " + dept.getDname());
	}
	
	/**
	 * DeptMapper.save()
	 */
	@Test
	public void test3() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept d = new Dept();
		d.setDname("财务部");
		d.setLoc("深圳");
		dao.save(d);
	}
	
	/**
	 * DeptMapper.update()
	 */
	@Test
	public void test4() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept d = dao.findById(41);
		d.setDname("市场部");
		dao.update(d);
	}
	
	/**
	 * DeptMapper.delete()
	 */
	@Test
	public void test5() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		dao.delete(41);
	}

}

依次执行测试方法,效果如下图:

图-5

3.4 完整代码

applicationContext.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<!-- 数据源 -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
		<property name="username" value="lhh"/>
		<property name="password" value="123456"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!--定义SqlSessionTemplate -->
	<bean id="sqlSessionTemplate" 
		class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory"/>
	</bean>

	<!-- 注解扫描 -->
	<context:component-scan base-package="com.tarena"/>
	
</beans>

Dept完整代码如下:

package com.tarena.entity;

import java.io.Serializable;

public class Dept implements Serializable {

	private Integer deptno;
	private String dname;
	private String loc;

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

DeptMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.DeptMapper">

	<select id="findAll" 
		resultType="com.tarena.entity.Dept">
		select * from t_dept
	</select>
	
	<select id="findById"
		parameterType="int"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{id}
	</select>
	
	<insert id="save"
		parameterType="com.tarena.entity.Dept">
		insert into t_dept values(
			dept_seq.nextval,
			#{dname},
			#{loc}
		)
	</insert>
	
	<update id="update"
		parameterType="com.tarena.entity.Dept">
		update t_dept set
			dname=#{dname},
			loc=#{loc}
		where deptno=#{deptno}
	</update>
	
	<delete id="delete"
		parameterType="int">
		delete from t_dept
		where deptno=#{id}
	</delete>
	
</mapper>

MyBatisDeptDao完整代码如下:

package com.tarena.dao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

import com.tarena.entity.Dept;

@Repository
public class MyBatisDeptDao implements Serializable {
	
	@Resource
	private SqlSessionTemplate template;

	public List<Dept> findAll() {
		return template.selectList("com.tarena.dao.DeptMapper.findAll");
	}

	public Dept findById(int id) {
		return template.selectOne("com.tarena.dao.DeptMapper.findById", id);
	}

	public void save(Dept dept) {
		template.insert("com.tarena.dao.DeptMapper.save", dept);
	}

	public void update(Dept dept) {
		template.update("com.tarena.dao.DeptMapper.update", dept);
	}

	public void delete(int id) {
		template.delete("com.tarena.dao.DeptMapper.delete", id);
	}

}

TestCase完整代码如下:

package com.tarena.test;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tarena.dao.MyBatisDeptDao;
import com.tarena.entity.Dept;

public class TestCase {
	
	
	/**
	 * DeptMapper.findAll()
	 */
	@Test
	public void test1() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		List<Dept> list = dao.findAll();
		for(Dept d : list) {
			System.out.println(
				d.getDeptno() + " " + d.getDname());
		}
	}
	
	/**
	 * DeptMapper.findById()
	 */
	@Test
	public void test2() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept dept = dao.findById(1);
		System.out.println(
			dept.getDeptno() + " " + dept.getDname());
	}
	
	/**
	 * DeptMapper.save()
	 */
	@Test
	public void test3() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept d = new Dept();
		d.setDname("财务部");
		d.setLoc("深圳");
		dao.save(d);
	}
	
	/**
	 * DeptMapper.update()
	 */
	@Test
	public void test4() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		Dept d = dao.findById(41);
		d.setDname("市场部");
		dao.update(d);
	}
	
	/**
	 * DeptMapper.delete()
	 */
	@Test
	public void test5() {
		String cfg = "applicationContext.xml";
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(cfg);
		MyBatisDeptDao dao = 
			ctx.getBean("myBatisDeptDao", MyBatisDeptDao.class);
		dao.delete(41);
	}

}

4 重构资费列表

4.1 问题

使用Spring整合MyBatis,重构资费列表。

4.2 方案

使用MapperScannerConfigurer扫描带有注解的接口,实现整合MyBatis,重新实现NETCTOSS项目中的资费数据访问组件。

4.3 步骤

步骤一:导包

为NETCTOSS项目补充导入开发包,如下图:

图-6

步骤二: 创建自定义注解

创建注解@MyBatisRepository,代码如下:

package com.tarena.annotation;

public @interface MyBatisRepository {

}

步骤三:配置applicationContext.xml

配置applicationContext.xml,增加MapperScannerConfigurer,追加代码如下:

	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下带有注解@MyBatisRepository的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
		<property name="annotationClass" 
			value="com.tarena.annotation.MyBatisRepository"/>
	</bean>

步骤四:创建资费映射文件

创建资费映射文件CostMapper.xml,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.CostDao">

	<select id="findAll" 
		resultType="com.tarena.entity.Cost">
		select 
			cost_id as costId,
			name,
			base_duration as baseDuration,
			base_cost as baseCost,
			unit_cost as unitCost,
			status,
			descr,
			creatime,
			startime,
			cost_type as costType
		from cost order by cost_id
	</select>
	
</mapper>

步骤五:重构业务组件

修改CostService,将注入的CostDao组件ID改为costDao,代码如下:

package com.tarena.service;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.tarena.dao.CostDao;
import com.tarena.entity.Cost;

@Service
public class CostService implements Serializable {
	
#cold_bold	@Resource(name="costDao")
	private CostDao costDao;
	
	public List<Cost> findAll() {
		return costDao.findAll();
	}
}

步骤六:测试

重新部署项目并启动Tomcat,登录后访问资费列表功能,效果如下图:

图-7

4.4 完整代码

MyBatisRepository完整代码如下:

package com.tarena.annotation;

public @interface MyBatisRepository {

}

applicationContext.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/www.springframework.org/schema/beans" 
	xmlns:xsi="/www.w3.org/2001/XMLSchema-instance"
	xmlns:context="/www.springframework.org/schema/context" 
	xmlns:jdbc="/www.springframework.org/schema/jdbc"  
	xmlns:jee="/www.springframework.org/schema/jee" 
	xmlns:tx="/www.springframework.org/schema/tx"
	xmlns:aop="/www.springframework.org/schema/aop" 
	xmlns:mvc="/www.springframework.org/schema/mvc"
	xmlns:util="/www.springframework.org/schema/util"
	xmlns:jpa="/www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		/www.springframework.org/schema/beans /www.springframework.org/schema/beans/spring-beans-3.2.xsd
		/www.springframework.org/schema/context /www.springframework.org/schema/context/spring-context-3.2.xsd
		/www.springframework.org/schema/jdbc /www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		/www.springframework.org/schema/jee /www.springframework.org/schema/jee/spring-jee-3.2.xsd
		/www.springframework.org/schema/tx /www.springframework.org/schema/tx/spring-tx-3.2.xsd
		/www.springframework.org/schema/data/jpa /www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		/www.springframework.org/schema/aop /www.springframework.org/schema/aop/spring-aop-3.2.xsd
		/www.springframework.org/schema/mvc /www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		/www.springframework.org/schema/util /www.springframework.org/schema/util/spring-util-3.2.xsd">
	
	<util:properties id="jdbc" location="classpath:jdbc.properties"/>
	
	<!-- 定义数据源 -->
	<bean id="ds" 
		class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="url" value="#{jdbc.url}"/>
		<property name="driverClassName" value="#{jdbc.driver}"/>
		<property name="username" value="#{jdbc.user}"/>
		<property name="password" value="#{jdbc.password}"/>
	</bean>	
	
	<!-- 开启注解扫描 -->
	<context:component-scan base-package="com.tarena"/>
	
	<!-- 开启MVC注解扫描 -->
	<mvc:annotation-driven/>
	
	<!-- 定义视图解析器ViewResolver -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- 处理系统异常 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
	        <props>		
	             <prop key="java.lang.Exception">main/error</prop>
	        </props>
	    </property>
	</bean>	
	
	<!-- 拦截器 -->
	<mvc:interceptors>
		<!-- 登录检查拦截器 -->
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<mvc:exclude-mapping path="/login/toLogin.do"/>
			<mvc:exclude-mapping path="/login/checkLogin.do"/>
			<bean class="com.tarena.web.LoginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>
	
	<!-- 整合JDBC -->
	<bean class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="ds"/>
	</bean>
	
	<!-- session工厂 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="ds" />
		<property name="mapperLocations"
			value="classpath:com/tarena/dao/*.xml" />
	</bean>
	
	<!-- 扫描指定包下带有注解@MyBatisRepository的接口 -->	
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.tarena.dao" />
		<property name="annotationClass" 
			value="com.tarena.annotation.MyBatisRepository"/>
	</bean>
	
</beans>

CostMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.CostDao">

	<select id="findAll" 
		resultType="com.tarena.entity.Cost">
		select 
			cost_id as costId,
			name,
			base_duration as baseDuration,
			base_cost as baseCost,
			unit_cost as unitCost,
			status,
			descr,
			creatime,
			startime,
			cost_type as costType
		from cost order by cost_id
	</select>
	
</mapper>

CostService完整代码如下:

package com.tarena.service;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.tarena.dao.CostDao;
import com.tarena.entity.Cost;

@Service
public class CostService implements Serializable {
	
	@Resource(name="costDao")
	private CostDao costDao;
	
	public List<Cost> findAll() {
		return costDao.findAll();
	}
}