一个Spring+MyBatis整合实例
- jar包:包括Spring框架jar包,MyBatis框架jar包,中间jar
Spring | MyBatis | 中间jar | 数据源 | 日志 |
---|---|---|---|---|
aopalliance, aspectjweaver, spring-aop,spring-aspects, spring-beans,spring-context,spring-core,spring-expression,spring-jdbc,spring-tx | ant,ant-launcher,asm,cglib,commons-logging,javassist,mybatisognl,slf4j-api,slf4j-log4j12 | mybatis-spring | mysql-connector-java | log4j,log4j-api,log4j-core |
- 数据库配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
- Spring配置文件
<!--读取db.properties -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<!--数据库驱动 -->
<property name="driverClassName" value="${jdbc.driver}" />
<!--连接数据库的url -->
<property name="url" value="${jdbc.url}" />
<!--连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" />
<!--连接数据库的密码 -->
<property name="password" value="${jdbc.password}" />
<!--最大连接数 -->
<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"/>
<!--配置MyBatis工厂 -->
<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.itheima.dao.impl.CustomerDaoImpl">
<!-- 注入SqlSessionFactory对象实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- Mapper代理开发(基于MapperFactoryBean) -->
<!-- <bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean> -->
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
</bean>
<!-- 开启扫描 -->
<context:component-scan base-package="com.itheima.service" />
- MyBatis配置文件
<configuration>
<!--配置别名 -->
<typeAliases>
<package name="com.itheima.po" />
</typeAliases>
<!--配置Mapper的位置 -->
<mappers>
<mapper resource="com/itheima/po/CustomerMapper.xml" />
<!-- Mapper接口开发方式 -->
<mapper resource="com/itheima/mapper/CustomerMapper.xml" />
</mappers>
</configuration>
- 创建持久层
1)持久化类
package com.itheima.po;
/**
* 客户持久化类
*/
public class Customer {
private Integer id; // 主键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 + "]";
}
}
2)映射文件
<mapper namespace="com.itheima.po.CustomerMapper">
<!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer"
resultType="customer">
select * from t_customer where id = #{id}
</select>
</mapper>
3)在MyBatis配置文件中配置映射文件的位置:
<mappers>
<mapper resource="com/itheima/po/CustomerMapper.xml" />
</mappers>
- 传统DAO方式:编写DAO接口和实现类,且需要向DAO实现类注入SQLSessionFactory。
1)DAO接口
package com.itheima.dao;
import com.itheima.po.Customer;
public interface CustomerDao {
// 通过id查询客户
public Customer findCustomerById(Integer id);
}
2)DAO接口实现类
package com.itheima.dao.impl;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import com.itheima.dao.CustomerDao;
import com.itheima.po.Customer;
public class CustomerDaoImpl
extends SqlSessionDaoSupport implements CustomerDao {
// 通过id查询客户
public Customer findCustomerById(Integer id) {
return this.getSqlSession().selectOne("com.itheima.po"
+ ".CustomerMapper.findCustomerById", id);
}
}
3)实现类交给Spring管理,并注入SQLSessionFactory实例
<!--实例化Dao -->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl">
<!-- 注入SqlSessionFactory对象实例-->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
4)测试
@Test
public void findCustomerByIdDaoTest(){
ApplicationContext act =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 根据容器中Bean的id来获取指定的Bean
CustomerDao customerDao =
(CustomerDao) act.getBean("customerDao");
// CustomerDao customerDao = act.getBean(CustomerDao.class);
Customer customer = customerDao.findCustomerById(1);
System.out.println(customer);
}
- Mapper接口方式:传统DAO在实现类会出现大量重复代码
1)Mapper接口
package com.itheima.mapper;
import com.itheima.po.Customer;
public interface CustomerMapper {
// 通过id查询客户
public Customer findCustomerById(Integer id);
// 添加客户
public void addCustomer(Customer customer);
}
2)映射文件
<mapper namespace="com.itheima.mapper.CustomerMapper">
<!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer"
resultType="customer">
select * from t_customer where id = #{id}
</select>
<!--添加客户信息 -->
<insert id="addCustomer" parameterType="customer">
insert into t_customer(username,jobs,phone)
values(#{username},#{jobs},#{phone})
</insert>
</mapper>
3)在MyBatis配置文件中,配置新的映射文件的地址
<!--配置Mapper的位置 -->
<mappers>
<!-- Mapper接口开发方式 -->
<mapper resource="com/itheima/mapper/CustomerMapper.xml" />
</mappers>
4)创建Mapper代理
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
5)测试
@Test
public void findCustomerByIdMapperTest(){
ApplicationContext act =
new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerMapper customerMapper = act.getBean(CustomerMapper.class);
Customer customer = customerMapper.findCustomerById(2);
System.out.println(customer);
}
MapperScannerConfigurer:自动扫描MyBatis中的映射器,避免Spring中出现过于臃肿的配置文件。
属性 | 描述 |
---|---|
basePackage | 映射接口文件包路径 |
annotationClass | 要扫描的注解名称 |
sqlSessionFactoryBeanName | 指定SqlSessionFactory的Bean名称 |
sqlSessionTemplateBeanName | 指定SqlSessionTemplate的Bean名称 |
markerInterface | 创建映射器的接口 |
使用
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
</bean>
- 事务
1)在要添加事务的位置添加注解
package com.itheima.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itheima.mapper.CustomerMapper;
import com.itheima.po.Customer;
import com.itheima.service.CustomerService;
@Service
@Transactional
public class CustomerServiceImpl implements CustomerService {
//注解注入CustomerMapper
@Autowired
private CustomerMapper customerMapper;
//添加客户
public void addCustomer(Customer customer) {
this.customerMapper.addCustomer(customer);
int i=1/0; //模拟添加操作后系统突然出现的异常问题
}
}
2)添加事务管理器,开启注解扫描
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<!--数据库驱动 -->
<property name="driverClassName" value="${jdbc.driver}" />
<!--连接数据库的url -->
<property name="url" value="${jdbc.url}" />
<!--连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" />
<!--连接数据库的密码 -->
<property name="password" value="${jdbc.password}" />
<!--最大连接数 -->
<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"/>
<!-- 开启扫描 -->
<context:component-scan base-package="com.itheima.service" />
3)测试
public class TransactionTest {
public static void main(String[] args) {
ApplicationContext act =
new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService =
act.getBean(CustomerService.class);
Customer customer = new Customer();
customer.setUsername("zhangsan");
customer.setJobs("manager");
customer.setPhone("13233334444");
customerService.addCustomer(customer);
}
}