spring与mybatis的整合
配置文件的更改
applicationContext.xml
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--读取db.properties-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<!--配置用户名-->
<property name="username" value="${jdbc.username}"/>
<!--配置密码-->
<property name="password" value="${jdbc.password}"/>
<!--连接数据库的URL-->
<property name="url" value="${jdbc.url}"/>
<!--数据库驱动-->
<property name="driverClassName" value="${jdbc.driver}"/>
<!--最大链接数-->
<property name="maxTotal" value="${jdbc.maxTotal}"/>
<!--最大空闲连接-->
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<!--初始化连接数-->
<property name="initialSize" value="${jdbc.initialSize}"/>
</bean>
<!--事务管理器,依赖于数据源-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--配置MyBatisG工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
</beans>
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
mybatis-config.xml
<?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>
<!--2.配置Mapper的位置 -->
<mappers>
<mapper resource="com/yzb/chapter09/IdCardMapper.xml" />
<mapper resource="com/yzb/chapter09/PersonMapper.xml"/>
<mapper resource="com/yzb/chapter09/example/UserMapper.xml"/>
<mapper resource="com/yzb/chapter09/example/ProductMapper.xml"/>
<mapper resource="com/yzb/chapter09/example/OrdersMapper.xml"/>
</mappers>
</configuration>
DAO的方式使用mybatis与Spring的整合
- 使用传统的DAO开发方式进行MyBatis与Spring框架的整合,可以使用mybatis-spring包中提供的SqlSessionTemplate类或SqlSessionDaoSupport类实现。
- SqlSessionTemplate:它负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,当调用SQL方法时,SqlSessionTemplate将保证使用的SqlSession和当前的Spring事务是相关的,他还管理SqlSession的生命周期,包括必要的关闭,提交,回滚操作
- SqlSessionDaoSupport:它继承了DaoSupport类,主要作为DAO的基类使用,可以通过SqlSessionDaoSupport类的getSqlSession()方法来获取所需的SqlSession.
代码
在上面的代码基础上添加
Customer
package com.yzb.chapter10;
import java.io.Serializable;
/*
* 客户持久化层
* */
public class Customer implements Serializable {
private Integer id;
private String username;
private String jobs;
private String phone;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", username='" + username + '\'' +
", jobs='" + jobs + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
Dao
package com.yzb.chapter10;
public interface Dao {
public Customer findCustomerById(Integer id);
}
DaoImpl
package com.yzb.chapter10;
import org.mybatis.spring.support.SqlSessionDaoSupport;
/*
* 继承SqlSessionDaoSupport
* */
public class DaoImpl extends SqlSessionDaoSupport implements Dao {
/*
* 通过ID查询客户
* */
@Override
public Customer findCustomerById(Integer id) {
return this.getSqlSession().selectOne("com.yzb.chapter10.CustomerMapper.findCustomerById", id);
}
}
CustomerMapper.xml
<?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">
<!-- namespace表示命名空间 -->
<mapper namespace="com.yzb.chapter10.CustomerMapper">
<select id="findCustomerById" parameterType="Integer" resultType="com.yzb.chapter10.Customer">
select * from t_customer where id = #{id}
</select>
</mapper>
Test
package com.yzb.chapter10;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// Dao customerDao = (Dao) applicationContext.getBean("customerDao");
Dao bean = applicationContext.getBean(Dao.class);
Customer customerById = bean.findCustomerById(1);
System.out.println(customerById);
}
}
applicationContext.xml
<!--实例化Dao-->
<bean id="customerDao" class="com.yzb.chapter10.DaoImpl">
<!--注入SqlSessionFactory的对象实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
mybatis-config.xml
<?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>
<!--2.配置Mapper的位置 -->
<mappers>
<mapper resource="com/yzb/chapter10/CustomerMapper.xml" />
</mappers>
</configuration>
mapper接口
使用Dao开发方式的缺点:会出现大量的重复代码,在方法中也需要指定映射文件中执行语句的id,并且不能保证编写id的正确性,所以这是可以使用Mapper接口编程。
MapperFactoryBean
它是MyBatis-Spring提供的一个根据Mapper接口生成Mapper对象的类,该类在Spring配置文件使用下面这些参数
- mapperInterface:用于指定接口;
- SqlSessionFactory:用于指定SqlSessionFactory
- SqlSessionTemplate:用于指定SqlSessionTemplate,如果SqlSessionFactory同时启用,则只会启用SqlSessionTemplate.
代码
CustomerMapper
package com.yzb.chapter10.example;
import com.yzb.chapter10.Customer;
public interface CustomerMapper {
public Customer findCustomerById(Integer id);
}
CustomerMapper.xml
<?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">
<!-- namespace表示命名空间 -->
<!--
Mapper代理开发规范
1:mapper接口的名称和对应的Mapper.xml映射文件的名称必须一致
2:Mapper.xml文件的namespace与Mapper接口的类路径相同(即接口文件和映射文件放在同一个包里面)
3:Mapper的接口中的方法名和Mapper.xml中定义的每个执行语句的id相同
4:Mapper接口中方法的输入参数类型和Mapper.xml中定义的每个SQL的parameterType类型相同
5:Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个sql的resultType的类型相同。
-->
<mapper namespace="com.yzb.chapter10.example.CustomerMapper">
<select id="findCustomerById" parameterType="Integer" resultType="com.yzb.chapter10.Customer">
select * from t_customer where id = #{id}
</select>
</mapper>
applicationContext.xml
<!--mapper代理开发,基于MapperFactoryBean-->
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.yzb.chapter10.example.CustomerMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
mybatis-config.xml
<!--2.配置Mapper的位置 -->
<mappers>
<mapper resource="com/yzb/chapter10/CustomerMapper.xml" />
<mapper resource="com/yzb/chapter10/example/CustomerMapper.xml"/>
</mappers>
MapperScannerConfigurer
- 对于接口的配置,在mybatis-config.xml中对于mapper.xml的文件的配置,和在appllicationContext.xml中基于Mapper(MapperFactoryBean的配置) ,如果接口过多很麻烦,所以可以用MapperScannerConfigure来代替他们两个的作用
-它是一种自动扫描的形式来配置MyBatis中的映射器。
applicationContex.xml
添加这个代码
<!--基于MapperScannerConfigurer的Mapper的代理开发-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yzb.chapter10.example"/>
</bean>
去掉这个代码
<!-- <!–mapper代理开发,基于MapperFactoryBean–>
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.yzb.chapter10.example.CustomerMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>-->
mybatis-config.xml
去掉相关的mapper.xml的配置文件
运行Test1的代码同样可以出来运行结果
事务
CustomerMapper
package com.yzb.chapter10.example;
import com.yzb.chapter10.Customer;
public interface CustomerMapper {
public Customer findCustomerById(Integer id);
public void addCustomer(Customer customer);
}
CustomerMapper.xml
<?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">
<!-- namespace表示命名空间 -->
<!--
Mapper代理开发规范
1:mapper接口的名称和对应的Mapper.xml映射文件的名称必须一致
2:Mapper.xml文件的namespace与Mapper接口的类路径相同(即接口文件和映射文件放在同一个包里面)
3:Mapper的接口中的方法名和Mapper.xml中定义的每个执行语句的id相同
4:Mapper接口中方法的输入参数类型和Mapper.xml中定义的每个SQL的parameterType类型相同
5:Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个sql的resultType的类型相同。
-->
<mapper namespace="com.yzb.chapter10.example.CustomerMapper">
<select id="findCustomerById" parameterType="Integer" resultType="com.yzb.chapter10.Customer">
select * from t_customer where id = #{id}
</select>
<insert id="addCustomer" parameterType="com.yzb.chapter10.Customer">
insert into t_customer (username,jobs,phone) values(#{username},#{jobs},#{phone})
</insert>
</mapper>
CustomerService
package com.yzb.chapter10.service;
import com.yzb.chapter10.Customer;
public interface CustomerService
{
public void addCustomer(Customer customer);
}
CustomerServiceImlp
package com.yzb.chapter10.service;
import com.yzb.chapter10.Customer;
import com.yzb.chapter10.example.CustomerMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerMapper customerMapper;
@Override
public void addCustomer(Customer customer) {
this.customerMapper.addCustomer(customer);
//模拟异常
//int i = 1/0;
}
}
applicationContext.xml
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="com.yzb.chapter10.service"/>
<!--读取db.properties-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<!--配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<!--配置用户名-->
<property name="username" value="${jdbc.username}"/>
<!--配置密码-->
<property name="password" value="${jdbc.password}"/>
<!--连接数据库的URL-->
<property name="url" value="${jdbc.url}"/>
<!--数据库驱动-->
<property name="driverClassName" value="${jdbc.driver}"/>
<!--最大链接数-->
<property name="maxTotal" value="${jdbc.maxTotal}"/>
<!--最大空闲连接-->
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<!--初始化连接数-->
<property name="initialSize" value="${jdbc.initialSize}"/>
</bean>
<!--事务管理器,依赖于数据源-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--配置MyBatisG工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--实例化Dao-->
<bean id="customerDao" class="com.yzb.chapter10.DaoImpl">
<!--注入SqlSessionFactory的对象实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!-- <!–mapper代理开发,基于MapperFactoryBean–>
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.yzb.chapter10.example.CustomerMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>-->
<!--基于MapperScannerConfigurer的Mapper的代理开发-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yzb.chapter10.example"/>
</bean>
</beans>
Test2
package com.yzb.chapter10.service;
import com.yzb.chapter10.Customer;
import com.yzb.chapter10.Dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// Dao customerDao = (Dao) applicationContext.getBean("customerDao");
CustomerService bean = applicationContext.getBean(CustomerService.class);
Customer customer = new Customer();
customer.setUsername("123");
customer.setJobs("456");
customer.setPhone("789");
bean.addCustomer(customer);
}
}