Ibatis3.0之后作者迁移了代码管理的位置,之前放在apache,现在放在了google code,改名成为mybatis,mybatis是持久层的类框架,有了它,就不用自己动手一行行的写jdbc的代码了,一句话使用它是为了提高我们工作效率,相对ibatis来说mybatis需要编写的代码量是越来越少了,越来越像傻瓜式编程,为了满足人类自古以来偷懒的习惯,工具是编写的越来越好了。本文参考mybatis的example:jpetstore来学习,ibatis的增删改查、存储过程、事务等等操作。初步研究,若有不对之处,请高手多多指教,谢谢!
Mybatis、Jpetstore下载地址:http://code.google.com/p/mybatis/
Mybatis用户指南:http://mybatis.github.com/mybatis-3/zh/index.html
好了,本文实现效果和之前ibatis一样,实现的是对一张用户表tb_users的增删改查、存储过程的调用、事务的处理等等操作。
项目搭建的环境是:eclipse
数据库:oracle10g
框架:spring+mybatis+velocity
项目编译和依赖管理:maven
开始我们的步步为营实验:
第一步:新建数据表、存储过程和序列
-- Create table
createtable TB_USERS
(
USERID NUMBER(12)notnull,
NAME VARCHAR2(20),
PASSWORD VARCHAR2(50),
ADDRESS VARCHAR2(200),
POSTCODE VARCHAR2(20),
TELEPHONE VARCHAR2(20),
MOBILE VARCHAR2(20),
EMAIL VARCHAR2(50),
COMPANY VARCHAR2(50),
GRADUATE_SCHOOLVARCHAR2(50),
REGISTER_TIME TIMESTAMP(6)
)
tablespace USERS
pctfree10
initrans1
maxtrans255
storage
(
initial64K
minextents1
maxextentsunlimited
);
-- Create/Recreate primary, unique and foreign key constraints
altertable TB_USERS
addconstraint KEY_USERIDprimarykey (USERID)
usingindex
tablespace USERS
pctfree10
initrans2
maxtrans255
storage
(
initial64K
minextents1
maxextentsunlimited
);
-- Create procedure
createorreplaceprocedure p_insertUser( nameinvarchar2,passwordin varchar2,addressin varchar2, postcodeinvarchar2, telephoneinvarchar2, mobileinvarchar2, emailinvarchar2, companyinvarchar2, graduateSchoolinvarchar2, useridoutnumber)as
userid1 number;
begin
select SEQ_TB_USERS.nextvalinto userid1from dual;
userid:=userid1;
insertinto tb_users(userid,name,password,address,postcode,telephone,mobile,email,company,graduate_school,register_time)values(userid,name,password,address,postcode,telephone,mobile,email,company,graduateSchool,systimestamp);
end p_insertUser;
-- Create sequence
createsequence SEQ_TB_USERS
minvalue1
maxvalue9999999999999
startwith1
incrementby1
cache20
cycle;
第二步、maven配置文件
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>onlinemarket-parent</artifactId>
<groupId>com.figo.onlinemarket</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.figo.onlinemarket</groupId>
<artifactId>onlinemarket-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>velocity-tools</groupId>
<artifactId>velocity-tools</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
</project>
第三步、持久层编写
Mybatis很神奇的地方是,只需要编写接口,不需要写实现类,但前提是mybatis sqlmap文件增删改查的id要和接口里面的方法名一致,否则是会报错,这个理算当然的了,之前ibatis是在实现类里面指定的,现在人家不需要你写实现类了,那当然需要保持一致,才能实现ORMapping功能。
package com.figo.onlinemarket.test.persistence;
import java.util.HashMap;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.figo.onlinemarket.test.domain.User;
public interface UserMapper {
/**
* 增加用户
* @param user
* @return
*/
public int insertUser(User user);
/**
* 通过存储过程增加用户
* @param user
* @return
*/
public int insertUserByProcedure(HashMap user);
/**
* 删除用户
* @param userId
* @return
*/
public int deleteUser(String name);
/**
* 修改用户
* @param user
* @return
*/
public int updateUser(User user);
/**
* 查询所有用户
* @param
* @return
*/
public List<User> selectUsers();
/**
* 查询用户
* @param userId
* @return
*/
public User selectUser(User user);
}
第四步、业务层编写
package com.figo.onlinemarket.test.service;
import java.util.HashMap;
import java.util.List;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.figo.onlinemarket.test.domain.User;
import com.figo.onlinemarket.test.persistence.UserMapper;
/**
* @author zhuzhifei
*
*/
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 增加用户
*
* @param user
* @return
*/
public int insertUser(User user) {
try {
return userMapper.insertUser(user);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return -1;
}
}
/**
* 通过存储过程增加用户
*
* @param user
* @return
*/
public int insertUserByProcedure(User user) {
try {
HashMap<String, Object> map = new HashMap<String, Object>();
// map.put("userid", 0);
map.put("name", user.getName());
map.put("password", user.getPassword());
map.put("address", user.getAddress());
map.put("postcode", user.getPostcode());
map.put("telephone", user.getTelephone());
map.put("mobile", user.getMobile());
map.put("email", user.getEmail());
map.put("company", user.getCompany());
map.put("graduateSchool", user.getGraduateSchool());
userMapper.insertUserByProcedure(map);
return Integer.parseInt(map.get("userid").toString());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return -1;
}
}
/**
* 删除用户
*
* @param userId
* @return
*/
public int deleteUser(String name) {
return userMapper.deleteUser(name);
}
/**
* 更新用户
*
* @param user
* @return
*/
public int updateUser(User user) {
return userMapper.updateUser(user);
}
/**
* 查询某个用户
*
* @param user
* @return
*/
public User selectUser(User user) {
return userMapper.selectUser(user);
}
/**
* 查询所有用户
*
* @return
*/
public List<User> selectUsers() {
return userMapper.selectUsers();
}
/**
* 先更新,再插入
* 在一个事务里面实现,注解的方式实现事务
* @param user
*/
@Transactional(isolation = Isolation.READ_COMMITTED, timeout = 30, propagation = Propagation.REQUIRED)
public void transactionUser(User user) {
userMapper.updateUser(user);
userMapper.insertUser(user);
}
}
第五步、Action编写
package com.figo.onlinemarket.test.action;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import com.figo.onlinemarket.test.domain.User;
import com.figo.onlinemarket.test.service.UserService;
/**
* @author zhuzhifei
*
*/
@Controller
public class UserAction {
@Autowired
private UserService userService;
@RequestMapping(value = "/action/addUser.htm")
public String andUser(User user, ModelMap model) {
if (user.getName()!=null&&!user.getName().equals("null")) {
//sql插入
int rowId = userService.insertUser(user);
if (rowId > 0) {
model.put("result", "新增成功");
} else {
model.put("result", "新增失败");
}
}
return "users/addUserForm";
}
@RequestMapping(value = "/action/addUserByProcedure.htm")
public String andUserByProcedure(User user, ModelMap model) {
if (user.getName()!=null&&!user.getName().equals("null")) {
//存储过程插入
int rowId = userService.insertUserByProcedure(user);
if (rowId > 0) {
model.put("result", "新增成功");
} else {
model.put("result", "新增失败");
}
}
return "users/addUserForm";
}
@RequestMapping(value = "/action/deleteUser.htm")
public String deleteUser(String name, ModelMap model) {
if (name!=null&&!name.equals("")) {
int rowId = userService.deleteUser(name);
if (rowId > 0) {
model.put("result", "删除成功");
} else {
model.put("result", "删除失败");
}
}
return "users/addUserForm";
}
@RequestMapping(value = "/action/updateUser.htm")
public String updateUser(User user, ModelMap model) {
if (user.getName()!=null&&!user.getName().equals("null")) {
int rowId = userService.updateUser(user);
if (rowId > 0) {
model.put("result", "修改成功");
} else {
model.put("result", "修改失败");
}
}
return "users/addUserForm";
}
@RequestMapping(value = "/action/selectUser.htm")
public String selectUser(User user, ModelMap model) {
if (user.getName()!=null&&!user.getName().equals("null")) {
User userResult = userService.selectUser(user);
model.put("userResult", userResult);
}
return "users/addUserForm";
}
@RequestMapping(value = "/action/selectUsers.htm")
public String selectUsers(ModelMap model) {
List<User> users = userService.selectUsers();
model.put("users", users);
return "users/addUserForm";
}
/**
* 事务测试
* @param model
* @return
*/
@RequestMapping(value = "/action/transactionUser.htm")
public String transactionUser(User user,ModelMap model) {
try {
userService.transactionUser(user);
} catch (Exception e) {
// TODO: handle exception
}
return "users/addUserForm";
}
}
第六步、ORMapping文件编写UserMapper.xml
Mybatis神奇的地方是只要UserMapper.xml和UserMapper.java在同一个包名下,就不需要在spring配置文件中另外配置UserMapper.xml的路径了
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="com.figo.onlinemarket.test.persistence.UserMapper">
<!-- cache /-->
<insert
id="insertUser"
keyProperty="userId"
parameterType="com.figo.onlinemarket.test.domain.User">
insert into TB_USERS(USERID,NAME, PASSWORD,ADDRESS,POSTCODE,TELEPHONE,MOBILE,EMAIL,COMPANY,GRADUATE_SCHOOL,REGISTER_TIME) values (#{userId,jdbcType=NUMERIC},#{name,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}, #{postcode,jdbcType=VARCHAR},#{telephone,jdbcType=VARCHAR},#{mobile,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{company,jdbcType=VARCHAR}, #{graduateSchool,jdbcType=VARCHAR},systimestamp)
</insert>
<parameterMaptype="java.util.HashMap"
id="user">
<parameter property="name" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="password" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="address" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="postcode" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="telephone" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="mobile"jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="email" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="company" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="graduateSchool" jdbcType="VARCHAR"javaType="java.lang.String"
mode="IN"/>
<parameterproperty="userid"jdbcType="DECIMAL"javaType="java.lang.Long"
mode="OUT"/>
</parameterMap>
<insertid="insertUserByProcedure"parameterMap="user"statementType="CALLABLE">
{call p_insertUser(?,?,?,?,?,?,?,?,?,?)}
</insert>
<deleteid="deleteUser">
delete from TB_USERS where (name=#{name})
</delete>
<updateid="updateUser" parameterType="com.figo.onlinemarket.test.domain.User">
update TB_USERS set password=#{password,jdbcType=VARCHAR} where name=#{name}
</update>
<selectid="selectUser"parameterType="User"resultType="User">
select
userId,name,password,address,postcode,telephone,mobile,email,
company,graduate_School as graduateSchool,register_Time as registerTime
from TB_USERS where name=#{name,jdbcType=VARCHAR} and password=#{password,jdbc=VARCHAR}
</select>
<selectid="selectUsers"resultType="User">
select
userId,name,password,address,postcode,telephone,mobile,email,
company,graduate_School as graduateSchool,register_Time as registerTime
from TB_USERS
</select>
</mapper>
第七步、applicationContext.xml配置
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- data source -->
<beanid="onlineMarketDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<propertyname="jndiName">
<value>java:comp/env/mposDataSource</value>
</property>
</bean>
<!-- transaction manager, use JtaTransactionManager for global tx -->
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="onlineMarketDataSource"/>
</bean>
<!-- enable component scanning (beware that this does not enable mapper scanning!) -->
<context:component-scanbase-package="com.figo.onlinemarket.test.service"/>
<!-- enable autowire -->
<context:annotation-config/>
<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven/>
<!-- define the SqlSessionFactory -->
<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
<propertyname="dataSource"ref="onlineMarketDataSource"/>
<propertyname="typeAliasesPackage"value="com.figo.onlinemarket.test.domain"/>
</bean>
<!-- scan for mappers and let them be autowired -->
<beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">
<propertyname="basePackage"value="com.figo.onlinemarket.test.persistence"/>
</bean>
</beans>
总结:代码量比较多,我这里给出我的demo下载地址,大家动手实验一下就清楚了。
http://pan.baidu.com/share/link?shareid=299697&uk=4245640613