0 简介
MyBatis作为一个优秀的持久化框架,简化了开发者访问数据库的操作,节省了开发者的时间。Spring是一个以依赖注入IoC闻名,后来又有了事务管理器,Spring MVC等功能。
下面,我们以银行转账功能的例子,介绍如何使用MyBatis访问数据库,并使用Spring的IoC进行依赖注入,使用Spring的事务管理器。阅读之前,最好先学习一下mybatis和Spring的基础知识。代码已经上传到CSDN资源。
1 环境配置信息
我使用的是eclipse IDE.
- JDK1.8.0_101
- MyBatis3.4.2
- Spring4.3.5
- commons-dbcp2-2.1.1数据源
- JUnit4.12测试框架
2 步骤流程速览
- 建立数据库和数据表
- 创建Domain层的PO类
- 创建DAO接口及方法,以及对应的mapper配置文件
- 创建service层和对应的方法
- 创建applicationContext.xml配置文件
- 创建测试类
注意:这些文件目录的组织方式值得注意,如图。
3 建立数据库和数据表
我习惯于将名称都小写,这样更容易读,不是吗?虽然MySQL的字符都是大写的。
create database account;
use account;
create table account (
`id` int not null auto_increment,
`name` varchar(50) not null,
`money` double(16, 4) not null,
primary key (`id`)
);
insert into account (name, money) values ('Michael', 1000);
insert into account (name, money) values ('Jane', 1000);
insert into account (name, money) values ('Kate', 1000);
4 创建Domain层的PO类
创建以下的文件时,有的需要在对应的包中或者目录中,这是需要注意的。
package com.chris.domain;
public class Account {
private int id;
private String name;
private double money;
//Note that the default constructor is neccessary
//for mybatis.
public Account() {
super();
}
public Account(int id, String name, double money) {
super();
this.id = id;
this.name = name;
this.money = money;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account [" + "name=" + name + ", money=" + money + "]";
}
}
5 创建DAO接口及方法,mybatis配置文件以及对应的mapper配置文件
对于mybatis来说,创建DAO的接口,然后在mapper配置文件中写SQL语句。
DAO接口
package com.chris.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.chris.domain.Account;
@Mapper
public interface AccountDAO {
//因为要传入多个参数,可以采取这种方式。
public void inMoney(@Param("name") String name, @Param("money") double money);
public void outMoney(@Param("name") String name, @Param("money") double money);
public List<Account> getAllUser();
}
AccountDAO对应的mapper文件AccountDAOMapper.xml,里面书写了sql语句。
<?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属性将DAO接口和mapper文件绑定起来,就好像调用方法com.chris.dao.
AccountDAO.getAllUser()一样-->
<mapper namespace="com.chris.dao.AccountDAO">
<!--这里可以使用Acount,而不是使用com.chris.domain.Account,是因为
在mybatis的配置文件mybatis_config.xml进行了配置 -->
<resultMap id="accountRM" type="Account">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="money" property="money"/>
</resultMap>
<update id="inMoney">
update account set money = money + #{money} where name = #{name};
</update>
<update id="outMoney">
update account set money = money - #{money} where name = #{name};
</update>
<select id="getAllUser" resultMap="accountRM">
select * from account;
</select>
</mapper>
mybatis配置文件mybatis_config.xml。我们在这里只进行了简单地配置,给了com.chris.domain.Account类一个简短的名字,还有,定义了需要进行mapper的DAO配置文件。
<?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>
<typeAliases>
<typeAlias type="com.chris.domain.Account" alias="Account"/>
</typeAliases>
<mappers>
<mapper resource="AccountDAOMapper.xml"/>
</mappers>
</configuration>
6 创建service层和对应的方法
service层对应着业务逻辑,比如转账的方法,这个方法需要用到多个DAO方法。
package com.chris.service;
import java.util.List;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import com.chris.dao.AccountDAO;
import com.chris.domain.Account;
//使用注解式的事务管理器
@Transactional
public class AccountService {
private AccountDAO accountDAO;
public AccountDAO getAccountDAO() {
return accountDAO;
}
public void setAccountDAO(AccountDAO accountDAO) {
this.accountDAO = accountDAO;
}
//转账的方法
public void transfer(String from, String to, double money) {
accountDAO.outMoney(from, money);
accountDAO.inMoney(to, money);
}
//获取用户信息的方法
public void readAllUser() {
List<Account> accounts = accountDAO.getAllUser();
for(Account account : accounts) {
System.out.println(account);
}
}
}
7 创建applicationContext.xml配置文件
applicationContext.xml是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: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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 开启注解式的事务管理器-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--mybatis的配置文件 -->
<property name="configLocation"
value="classpath:mybatis_config.xml"/>
</bean>
<!-- The configurers in the configuration file will replace
${...} placeholders -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="initialSize" value="3"/>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Service layer依赖注入 -->
<bean id="accountService" class="com.chris.service.AccountService">
<property name="accountDAO" ref="accountDAO"/>
</bean>
<!-- DAO接口的配置信息-->
<bean id="accountDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
<property name="mapperInterface" value="com.chris.dao.AccountDAO"></property>
</bean>
</beans>
数据源配置文件db.properties的信息
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/account
# replace the xxxx with your own username and password
db.username=xxxx
db.password=xxxx
8 创建测试类
下面是一个简单地测试类,测试service层transfer
package com.chris.service;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.chris.service.AccountService;
//@RunWith注解使得Spring框架里可以使用JUnit4测试框架
@RunWith(SpringJUnit4ClassRunner.class)
//引入配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class TransferTest {
//根据名字注入实例
@Autowired
private AccountService accountService;
@Test
public void testTransfer() {
accountService.transfer("Jane", "Michael", 200d);
}
}
9 总结
在这里,我们只是简单地介绍了整合的大概流程,对于事务管理器、缓存等没有进行介绍。
源码上传到CSDN,包括lib里的jar文件。