Spring集成mybatis
(1)方式一
step1. 导包。
spring-webmvc,mybatis,mybatis-spring, ojdbc,dbcp,spring-jdbc,junit。
step2. 添加spring的配置文件。
注:集成之后,不再需要mybatis的配置文件了,之前的配置信息 用一个bean(SqlSessionFactoryBean)来代替。
step3.实体类。
step4.映射文件。
step5.Mapper映射器。
step6.配置MapperScannerConfigurer。
注入要扫描的包名,多个包之间使用逗号或分号进行分隔
注:该bean负责调用SqlSession的getMapper方法,获得 符合Mapper映射器要求的对象。并且会将这些对象放到spring 容器里面(默认的id是首字母小写之后的接口名,比如Mapper 映射器名为EmpDAO,则默认的id是empDAO,也可以使用@Repository 来修改默认的id)。
注:如果只扫描特定的映射器,可以做如下两步。
step1.开发一个注解,比如@MyBatisRepository,并且,将 该注解添加到需要扫描的映射器上面。
step2.给MapperScannerConfigurer注入annotationClass属性值。
(2)方式二
step1. 导包。
spring-webmvc,mybatis,mybatis-spring, ojdbc,dbcp,spring-jdbc,junit。
step2. 添加spring的配置文件。
注:集成之后,不再需要mybatis的配置文件了,之前的配置信息 用一个bean(SqlSessionFactoryBean)来代替。
step3.实体类。
step4.映射文件。
step5.Mapper映射器。
step6.写映射器的实现类。
注:可以将SqlSessionTemplate注入到实现类中,然后调用 SqlSessionTemplate的方法即可。
step7.配置SqlSessionTemplate。
方法一的代码如下:
实体类:
package entity;
/*
* 属性名必须跟表的字段名一样(大小写不区分)
*/
public class Emp {
private Long id;
private String name;
private Double age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getAge() {
return age;
}
public void setAge(Double age) {
this.age = age;
}
@Override
public String toString() {
return "Emp [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
spring配置文件:
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-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/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<util:properties id="config" location="classpath:db.properties"/>
<!-- 配置连接池 spring关闭之前关闭连接池-->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="#{config.driver}"/>
<property name="url" value="#{config.url}"/>
<property name="username" value="#{config.username}"/>
<property name="password" value="#{config.password}"/>
</bean>
<!--
spring集成mybatis,不再需要mybatis的配置文件
配置SqlSessionFactoryBean来代替mybatis的配置文件
-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 连接池 不再使用mybatis自带的连接池,使用spring管理的连接池 -->
<property name="dataSource" ref="ds"/>
<!-- 映射文件位置 -->
<property name="mapperLocations" value="classpath:entity/*.xml"/>
</bean>
<!--
配置MapperScannerConfigurer
负责扫描指定包下面的所有Mapper映射器
然后生成符合这些映射器要求的对象(其实就是调用SqlSession的getMapper方法)
另外,还会将这些对象添加到spring容器里面,默认的id是首字母小写之后的接口名
比如Mapper映射器名为EmpDAO,则默认的id是empDAO,也可以使用@Repository来修改默认的id
也可以使用@Repository("eDAO")重新设置id,此处不用配置组件扫描,因为MapperScannerConfigurer
里面会自动调用组件扫描
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入要扫描的包名,多个包之间使用逗号或分号进行分隔 -->
<property name="basePackage" value="dao"/>
<!-- 只扫描dao包下面带有该注解的映射器 -->
<property name="annotationClass" value="annotations.MyBatisRepository"/>
</bean>
</beans>
映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- 命名空间为一个字符串,加以区分xml中各个元素 -->
<mapper namespace="dao.EmpDAO"><!-- 映射文件的namespace必须等于该接口的完整的名称(全限定名) -->
<!--
id:要求唯一
resultType:返回的数据类型(完整类名)
parameterType:参数类型 #{name}表示读取Emp类中的name属性(此处的两个变量名必须一致)
注意:此处的name和age是对象里面的属性,所以要求一致
-->
<!-- 插入一条数据 -->
<insert id="save" parameterType="entity.Emp">
INSERT INTO emp(name,age) VALUES(#{name},#{age})
</insert>
<!-- 查询所有记录 有返回结果-->
<select id="findAll" resultType="entity.Emp">
SELECT * FROM emp ORDER BY id
</select>
<!--
根据id查询 参数类型为java.lang.Integer 可以简写为int
此处#{id}中的参数名称不做要求,id1也可以
-->
<select id="findById" parameterType="long" resultType="entity.Emp">
SELECT * FROM emp WHERE id = #{id}
</select>
<!-- 修改某条记录 属性来自于实体类,故要一致-->
<update id="modify" parameterType="entity.Emp">
UPDATE emp SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
<!-- 删除某条记录 -->
<delete id="delete" parameterType="long">
DELETE FROM emp WHERE id = #{id}
</delete>
<!-- 返回Map类型的结果 map是java.util.Map的简写-->
<select id="findById2" parameterType="long" resultType="map">
SELECT * FROM emp WHERE id = #{id}
</select>
<!--
根据id查询
使用ResultMap解决表的字段名与实体属性不一致的情况
-->
<select id="findById3" parameterType="long" resultType="entity.Emp2" resultMap="emp2Map">
SELECT * FROM emp WHERE id = #{id}
</select>
<resultMap type="entity.Emp2" id="emp2Map">
<result property="empNo" column="id"/>
<result property="ename" column="name"/>
</resultMap>
</mapper>
自定义的注解:
package annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
*
* @MyBatisRepository 用于映射器的特定注解
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MyBatisRepository {
}
映射器:
package dao;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Repository;
import annotations.MyBatisRepository;
import entity.Emp;
import entity.Emp2;
/**
* Mapper映射器
* a. 方法的名称必须与sql的id一样。
* b. 方法的返回值类型必须与sql的resultType一样。
* c. 方法的参数类型必须怀sql的parameterType一样。
* d. 映射文件的namespace必须等于该接口的完整的名称。
*/
//@Repository("eDAO")
@MyBatisRepository//自定义注解 用于扫描映射器
public interface EmpDAO {
public void save(Emp emp);//插入一条数据
public List<Emp> findAll();//查询所有
public Emp findById(long id);//根据id查询
public void modify(Emp emp);//修改某条数据
public void delete(long id);//删除某条数据
public Map findById2(long id);//返回map
public Emp2 findById3(long id);//使用ResultMap解决表的字段名与实体属性不一致的情况
}
测试代码:
package test;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.EmpDAO;
import entity.Emp;
import entity.Emp2;
public class TestCase {
private EmpDAO dao;
@Before
public void init(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
dao = ac.getBean("empDAO",EmpDAO.class);
}
@Test
//插入一条数据
public void test1(){
Emp emp = new Emp();
emp.setName("Sally");
emp.setAge(new Double(22));
dao.save(emp);
}
@Test
//查询所有
public void test2(){
List<Emp> list = dao.findAll();
for(Emp emp : list){
System.out.println(emp);
}
}
@Test
//通过id查询
public void test3(){
long id = 7;
Emp emp = dao.findById(id);
System.out.println(emp);
}
@Test
//修改某条数据
public void test4(){
long id = 7;
Emp emp = dao.findById(id);
emp.setAge(emp.getAge() + 10);
dao.modify(emp);
}
@Test
//删除某条数据
public void test5(){
long id = 2;
dao.delete(id);
}
@Test
//返回map
public void test6(){
long id = 7;
Map map = dao.findById2(id);
System.out.println(map);
System.out.println(map.get("name") + " " + map.get("age"));
}
@Test
//使用ResultMap解决表的字段名与实体属性不一致的情况
public void test7(){
long id = 7;
Emp2 emp = dao.findById3(id);
System.out.println(emp);
}
}