spring+mybatis通用dao层、service层的一些个人理解与实现

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">	</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">首先声明,本文所述只是鉴于本人在开发一些应用时的心得,仅供参考。</span>


1、现在的绝大多数web应用,通常都以action、service、dao三层去组织代码,这样划分结构很清晰,分工明确

2、一般情况下,我们会把事务控制在service层。

3、action和dao层,会使用一些框架技术。比如action层可能选择有springmvc、struts等,dao层有hibernate、mybatis等选择,所以action的dao有可能遂根据情况变化,而service层关注业务逻辑,业务代码都是自己完成的,代码对自己是透明的。


基于1,我们的每个业务,可能都需要这三层代码,也就是因为一个很简单的业务,我们会写dao层及实现,service层及实现,action层,这样会造成很多的类。所以最好做到dao层必须通用,service层绝大部分通用,这样就会减少大量的类。


基于2,我们应把业务逻辑写在service层,这样才能控制住事务。例如我们的一个业务:删除A记录,插入B记录(需要在一个事务里进行),如果我们把这个业务逻辑写在了action层,我们再action层调用删除A的service,然后再调用插入B的service,如果说插入B失败了,那我们删除A这个操作将不能回滚,因为事务控制在了service层,这样写已不是一个事务。删除A操作的service已经完成,事务已经提交了,插入B的操作在另外的事务里运行。根据需要,业务逻辑尽量放在service层。通过配置spring事务控制的传播行为,在service层可以达到大部分的业务事务要求,而不需另加一层。


基于3,我们更应该把与业务相关的代码移至service层,如果service层的事务不容易控制了,可以增加额外的support层(个人理解,其实还是业务逻辑层)协助控制事务。这主要发生在我们把整个业务逻辑放在了service的一个方法,而这个方法以及调用的方法的事务配置为required(或其他),但业务的部分操作需要在不同的事务中进行,我们不想写另外的方法,也不想去更改事务配置,所以引入support层(或许你说可以把这种逻辑向action层移动,在action层处理,但记住我们的前提,action的框架是会变的,我们想尽量做到更改action层时,更简单。而且从分工来说,action层应该只关注视图逻辑,个人自扫门前雪,休管他人瓦上霜)。support层当然不是只为处理这种事务问题的,我把它定义为业务处理时需要的一些辅助层,可以协助处理业务,比如刚才说的事务问题,还有可以提供工具类支持等。 

对于dao层,应该只关注数据库连接执行结果封装这些事。


我们的通用,是基于以上的分析结论进行,下面贴上代码:

通用dao层:

package com.wls.websvn.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.wls.websvn.support.Page;

public interface CommonDao {
	/**
	 * 
	 * 增加一个实体
	 * @param pojo
	 * @return 影响的行数 0失败,1成功
	 */
	public <T extends Serializable> int save(T pojo);

	/**
	 * 
	 * 通过id删除实体
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T extends Serializable> int deleteById(Class<T> clazz,
			Serializable id);

	/**
	 * 
	 * 通过主键获取实体
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T extends Serializable> T getById(Class<T> clazz, Serializable id);

	/**
	 * 
	 * 查询所有实体
	 * 
	 * @param clazz
	 * @return
	 */
	public <T extends Serializable> List<T> listAll(Class<T> clazz);
	
	/**
	 * 
	 * 分页查询
	 * 
	 * @param clazz
	 * @param p
	 * @return
	 */
	public <T extends Serializable> Page<T> pageSelect(Class<T> clazz,Page<T> p,String[]attrs,Object[]values);
	
	
	/**
	 * 
	 * 分页查询时,用来统计总条数
	 * 
	 * @param clazz
	 * @param attrs
	 * @param values
	 * @return
	 */
	public <T extends Serializable> int pageCount(Class<T> clazz,String[]attrs,Object[]values);

	/**
	 * 
	 * 统计总条数
	 * 
	 * @param clazz
	 * @return
	 */
	public <T extends Serializable> int countAll(Class<T> clazz);

	/**
	 * 
	 * 指定查询使用的命名sql,查询结果封装成map
	 * 
	 * @param statment
	 * @param paraMap
	 * @return
	 */
	List<Map<String,Object>>  selectMap(String statment, Map<String, Object> paraMap);

}

dao层实现:

package com.wls.websvn.dao.mybatis;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Repository;

import com.wls.websvn.dao.CommonDao;
import com.wls.websvn.support.Page;

@Repository("commonDao")
public class CommonDaoImpl implements CommonDao {

	@Resource(name = "sqlSessionFactory")
	protected SqlSessionFactory sqlSessionFactory;

	protected <T> String getStatement(Class<T> clazz, String prefix) {
		String entityName = clazz.getSimpleName();
		if (entityName.endsWith("Model")) {
			entityName = entityName.substring(0, entityName.length() - 5);
		}
		entityName = prefix + entityName;
		return entityName;
	}

	@Override
	public <T extends Serializable> int save(T pojo) {
		String statement = getStatement(pojo.getClass(), "insert");
		return sqlSessionFactory.openSession().insert(statement, pojo);
	}

	@Override
	public <T extends Serializable> int deleteById(Class<T> clazz,
			Serializable id) {
		String statement = getStatement(clazz, "idDelete");
		return sqlSessionFactory.openSession().update(statement, id);
	}

	@Override
	public <T extends Serializable> T getById(Class<T> clazz, Serializable id) {
		String statement = getStatement(clazz, "idGet");
		return sqlSessionFactory.openSession().selectOne(statement, id);
	}

	@Override
	public <T extends Serializable> List<T> listAll(Class<T> clazz) {
		String statement = getStatement(clazz, "list");
		return sqlSessionFactory.openSession().selectList(statement);
	}

	/**
	 * 
	 * 组装排序串
	 * 
	 * @param sort
	 * @param order  最好将order定义成枚举类型,传递一个枚举数组
	 * @return
	 */
	private String genOrderStr(String sort, String order) {
		String orderBy = "";
		if (StringUtils.isNotBlank(sort)) {
			if (StringUtils.isNotBlank(order)) {
				StringBuilder sb = new StringBuilder(" ");
				String[] aSort = sort.split(",");
				String[] aOrder = order.split(",");
				for (int i = 0; i < aSort.length; i++) {
					sb.append(aSort[i]).append(" ");
					if (i < aOrder.length) {
						sb.append(aOrder[i]).append(",");
					} else {
						sb.append("ASC").append(",");
					}
				}
				// 删除最后一个,
				sb.deleteCharAt(sb.length() - 1);
				orderBy = sb.toString();

			} else {
				orderBy = " order by " + sort;
			}
		}

		return orderBy;
	}

	@Override
	public <T extends Serializable> int pageCount(Class<T> clazz,
			String[] attrs, Object[] values) {
		Map<String, Object> paraMap = new HashMap<String, Object>();

		if (values != null && attrs != null) {
			for (int i = 0; i < values.length; i++) {
				if (i < attrs.length) {
					paraMap.put(attrs[i], values[i]);
				}
			}
		}
		String statement = getStatement(clazz, "pageCount");
		Object o = sqlSessionFactory.openSession().selectOne(statement,paraMap);
		return Integer.parseInt(o.toString());
	}

	@Override
	public <T extends Serializable> Page<T> pageSelect(Class<T> clazz,
			Page<T> p, String[] attrs, Object[] values) {
		int startNum = p.getStartIndex();
		int pageSize = p.getPageSize();
		String orderBy = genOrderStr(p.getSort(), p.getOrder());
		Map<String, Object> paraMap = new HashMap<String, Object>();

		if (values != null && attrs != null) {
			for (int i = 0; i < values.length; i++) {
				if (i < attrs.length) {
					paraMap.put(attrs[i], values[i]);
				}

			}
		}
		String statement = getStatement(clazz, "page");
		p.setTotal(pageCount(clazz, attrs, values));

		paraMap.put("startNum", startNum);
		paraMap.put("pageSize", pageSize);
		paraMap.put("endNum", startNum + pageSize);
		paraMap.put("orderBy", orderBy);
		List<T> list = sqlSessionFactory.openSession().selectList(statement,
				paraMap);
		p.setData(list);
		return p;
	}

	@Override
	public <T extends Serializable> int countAll(Class<T> clazz) {
		String statement = getStatement(clazz, "count");
		Object o = sqlSessionFactory.openSession().selectOne(statement);
		return Integer.parseInt(o.toString());
	}

	@Override
	public List<Map<String, Object>> selectMap(String statement,
			Map<String, Object> paraMap) {
		return sqlSessionFactory.openSession().selectList(statement, paraMap);
	}

}


support:

package com.wls.websvn.support;

import java.util.List;

public class Page<T> {

	/**
	 * 页码
	 */
	private int page = 1;

	/**
	 * 每页条数
	 */
	private int pageSize = 10;

	/**
	 * 总记录数
	 */
	private long total;

	/**
	 * 排序列
	 */
	private String sort;

	/**
	 * 升降序
	 */
	private String order;

	/**
	 * 单页数据
	 */
	private List<T> data;

	public Page() {
		this.page = 1;
		this.pageSize = 10;
	}

	
	public Page(int page, int pageSize) {
		this.page = page;
		this.pageSize = pageSize;
	}

	/**
	 * 获取page值
	 * @return int page.
	 */
	public int getPage() {
		return page;
	}

	/**
	 * 设置page值
	 * @param page The page to set.
	 */
	public void setPage(int page) {
		this.page = page;
	}

	/**
	 * 获取pageSize值
	 * @return int pageSize.
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * 设置pageSize值
	 * @param pageSize The pageSize to set.
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * 获取data值
	 * @return List<T> data.
	 */
	public List<T> getData() {
		return data;
	}

	/**
	 * 设置data值
	 * @param data The data to set.
	 */
	public void setData(List<T> data) {
		this.data = data;
	}

	/**
	 * 获取total值
	 * @return long total.
	 */
	public long getTotal() {
		return total;
	}

	/**
	 * 设置total值
	 * @param total The total to set.
	 */
	public void setTotal(long total) {
		this.total = total;
	}

	public String getSort() {
		return sort;
	}

	public void setSort(String sort) {
		this.sort = sort;
	}

	/**
	 * @return the order
	 */
	public String getOrder() {
		return order;
	}

	/**
	 * @param order the order to set
	 */
	public void setOrder(String order) {
		this.order = order;
	}

	/**
	 * 
	 * 获取分页开始的位置
	 * 
	 * @return
	 */
	public int getStartIndex() {
		if(page<1){
			return 0;
		}
		return (page - 1) * pageSize;
	}
}


service层:

package com.wls.websvn.service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.wls.websvn.support.Page;

public interface CommonService {

	/**
	 * 
	 * 增加一个实体
	 * @param pojo
	 * @return 影响的行数 0失败,1成功
	 */
	public <T extends Serializable> int save(T pojo);

	/**
	 * 
	 * 通过id删除实体
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T extends Serializable> int deleteById(Class<T> clazz,
			Serializable id);

	/**
	 * 
	 * 通过主键获取实体
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public <T extends Serializable> T getById(Class<T> clazz, Serializable id);

	/**
	 * 
	 * 查询所有实体
	 * 
	 * @param clazz
	 * @return
	 */
	public <T extends Serializable> List<T> listAll(Class<T> clazz);
	
	/**
	 * 
	 * 分页查询
	 * 
	 * @param clazz
	 * @param p
	 * @return
	 */
	public <T extends Serializable> Page<T> pageSelect(Class<T> clazz,Page<T> p,String[]attrs,Object[]values);
	
	
	/**
	 * 
	 * 分页查询时,用来统计总条数
	 * 
	 * @param clazz
	 * @param attrs
	 * @param values
	 * @return
	 */
	public <T extends Serializable> int pageCount(Class<T> clazz,String[]attrs,Object[]values);

	/**
	 * 
	 * 统计总条数
	 * 
	 * @param clazz
	 * @return
	 */
	public <T extends Serializable> int countAll(Class<T> clazz);

	/**
	 * 
	 * 指定查询使用的命名sql,查询结果封装成map
	 * 
	 * @param statment
	 * @param paraMap
	 * @return
	 */
	List<Map<String,Object>>  selectMap(String statment, Map<String, Object> paraMap);

}

service层实现:

package com.wls.websvn.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.wls.websvn.dao.CommonDao;
import com.wls.websvn.service.CommonService;
import com.wls.websvn.support.Page;

/**
 * 
 * @author weilisky
 * 考虑将来可能切换到hibernate或其他框架的情况,尽量的将切换时不用变的代码移到service层。
 * 将切换时可能会变更的代码放在了dao层
 *
 */
@Service("commonService")
public class CommonServiceImpl implements CommonService {

	@Resource(name = "commonDao")
	protected CommonDao commonDao;


	@Override
	public <T extends Serializable> int save(T pojo) {
		return commonDao.save(pojo);
	}

	@Override
	public <T extends Serializable> int deleteById(Class<T> clazz,
			Serializable id) {
		return commonDao.deleteById(clazz, id);
	}

	@Override
	public <T extends Serializable> T getById(Class<T> clazz, Serializable id) {
		return commonDao.getById(clazz, id);
	}

	@Override
	public <T extends Serializable> List<T> listAll(Class<T> clazz) {
		return commonDao.listAll(clazz);
	}


	@Override
	public <T extends Serializable> int pageCount(Class<T> clazz,
			String[] attrs, Object[] values) {
		return commonDao.pageCount(clazz, attrs, values);
	}

	@Override
	public <T extends Serializable> Page<T> pageSelect(Class<T> clazz,
			Page<T> p, String[] attrs, Object[] values) {
		return commonDao.pageSelect(clazz, p, attrs, values);
	}

	@Override
	public <T extends Serializable> int countAll(Class<T> clazz) {
		return commonDao.countAll(clazz);
	}

	@Override
	public List<Map<String, Object>> selectMap(String statement,
			Map<String, Object> paraMap) {
		return commonDao.selectMap(statement, paraMap);
	}

}

通过泛型,这里做到了service层可以查询各种实体。如果实体的操作简单,完全没有必要再写service层,commonService应该就够用,当然你还可以增加CommonService增加方法(当然可能需要同步增加CommonDao),使其更通用。

如果CommonService不够用了,你的接口应该继承CommonService接口,你的实现应该继承CommonServiceImpl实现,然后根据需要override其中的一些方法。


需要说明一下,我们把protected <T> String getStatement(Class<T> clazz, String prefix)放置在dao层,因为它并不是业务逻辑的一部分,而且对于mybaits框架,你需要这个方法,而对应hibenate你可能根本不需要(或则可以把这个方法重构到另外的一个接口)。


最后附上例子model和mapping:

package com.wls.websvn.model;

import java.io.Serializable;
import java.util.Date;

public class BaseModel implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -459530011111182045L;
	
	protected Long id;
	
	protected Date createDate;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}
	
}

package com.wls.websvn.model;

public class UserModel extends BaseModel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5715947400419117755L;
	//登录名
	private String userName;
	//真实姓名
	private String realName;
	//密码
	private String userPwd;
	
	private String phoneNum;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}


	public String getRealName() {
		return realName;
	}

	public void setRealName(String realName) {
		this.realName = realName;
	}

	public String getUserPwd() {
		return userPwd;
	}

	public void setUserPwd(String userPwd) {
		this.userPwd = userPwd;
	}

	public String getPhoneNum() {
		return phoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		this.phoneNum = phoneNum;
	}

}


<?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">

<mapper namespace="com.wls.websvn.model.UserModel">

	<!-- PROCESSDEFINITION INSERT -->


	<insert id="insertUser" parameterType="com.wls.websvn.model.UserModel">
		insert into
		SVN_USER(ID_,
		NAME_, REALNAME_, PASSWORD_, MOBILEPHONE_,CREATE_TIME_)
		values
		(#{id,
		jdbcType=BIGINT},
		#{userName, jdbcType=VARCHAR},
		#{realName,
		jdbcType=VARCHAR},
		#{userPwd, jdbcType=VARCHAR},
		#{phoneNum,
		jdbcType=VARCHAR},
		#{createDate,
		jdbcType=TIMESTAMP})
	</insert>

	<update id="idDeleteUser" parameterType="long">
		DELETE FROM
		SVN_USER WHERE ID_=#{id,jdbcType=BIGINT}
	</update>


	<resultMap id="userResultMap" type="com.wls.websvn.model.UserModel">
		<id property="id" column="ID_" jdbcType="BIGINT" />
		<result property="userName" column="NAME_" jdbcType="VARCHAR" />
		<result property="realName" column="REALNAME_" jdbcType="VARCHAR" />
		<result property="userPwd" column="PASSWORD_" jdbcType="VARCHAR" />
		<result property="phoneNum" column="MOBILEPHONE_" jdbcType="VARCHAR" />
		<result property="createDate" column="CREATE_TIME_" jdbcType="VARCHAR" />
	</resultMap>

	<select id="idGetUser" parameterType="string" resultMap="userResultMap">
		SELECT *
		FROM SVN_USER WHERE ID_=#{id,jdbcType=BIGINT}
	</select>

	<select id="countUser" resultType="int">
		SELECT COUNT(1) FROM
		SVN_USER
	</select>

	<select id="listUser" resultMap="userResultMap">
		SELECT * FROM SVN_USER
	</select>

	<select id="pageCountUser" resultType="int" parameterType="map">
		select count(1) from SVN_USER ST
		<where>
			<if test="id!=null and id!='' ">
				ST.ID_ = #{id}
			</if>
			<if test="name!= null and name!= '' ">
				AND ST.NAME_ LIKE CONCAT(CONCAT('%', #{name}),'%')
			</if>
			<if test="codePrefix !=null and codePrefix!='' ">
				AND ST.CODEPREFIX_ = #{codePrefix}
			</if>
			<if test="active !=null ">
				AND ST.ACTIVE_ = #{active}
			</if>
			<if test="description !=null and description!='' ">
				AND ST.DESCRIPTION_ = #{description}
			</if>
		</where>
	</select>


	<select id="pageUser" resultMap="userResultMap"
		parameterType="map">
		select * from SVN_USER ST
		<where>
			<if test="id!=null and id!='' ">
				ST.ID_ = #{id}
			</if>
			<if test="name!= null and name!= '' ">
				AND ST.NAME_ LIKE CONCAT(CONCAT('%', #{name}),'%')
			</if>
			<if test="codePrefix !=null and codePrefix!='' ">
				AND ST.CODEPREFIX_ = #{codePrefix}
			</if>
			<if test="active !=null ">
				AND ST.ACTIVE_ = #{active}
			</if>
			<if test="description !=null and description!='' ">
				AND ST.DESCRIPTION_ = #{description}
			</if>
		</where>
		<if test="startNum!=null">
			LIMIT ${startNum} , ${pageSize}
		</if>

		<if test="orderBy!=null and orderBy!='' ">
			${orderBy}
		</if>

	</select>


	<select id="selectMap" resultType="map" parameterType="map">
		SELECT *
		FROM SVN_USER
	</select>

</mapper>

部分spring配置:

applicationContext-dao.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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="${initialSize}"></property>
		<!-- 连接池最大数量 -->
		<property name="maxActive" value="${maxActive}"></property>
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="${maxIdle}"></property>
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="${minIdle}"></property>
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="${maxWait}"></property>
	</bean>

	<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- 自动扫描mapping.xml文件 -->
		<property name="mapperLocations" value="classpath:com/wls/websvn/mapping/*.xml"></property>
	</bean>

	<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<!-- 	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.wls.websvn.dao" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>
 -->
	<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>


</beans>
applicationContext-service.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"
	default-lazy-init="true">
	<aop:config>
		<aop:advisor id="managerTx" advice-ref="txAdvice"
			pointcut="execution(* *..service.*Manager.*(..))" order="0" />

		<aop:advisor id="managerTxService" advice-ref="txAdvice"
			pointcut="execution(* *..service.*Service.*(..))" order="1" />

	</aop:config>

	<!-- Enable @Transactional support -->
	<tx:annotation-driven transaction-manager="transactionManager" />

	<!-- Enable @AspectJ support -->
	<aop:aspectj-autoproxy proxy-target-class="true" />

	<!-- Activates scanning of @Autowired -->
	<context:annotation-config />

	<!-- Activates scanning of @Service -->
	<context:component-scan base-package="com.dcfs.qed" />


	<tx:advice id="txAdvice">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="set*" read-only="true" />
			<tx:method name="exist*" read-only="true" />
			<tx:method name="find*" read-only="true" />
			<tx:method name="load*" read-only="true" />
			<tx:method name="query*" read-only="true" />
			<tx:method name="list*" read-only="true" />
			<tx:method name="paging*" read-only="true" />

			<tx:method name="update*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" />
			<tx:method name="remove*" propagation="REQUIRED"
				rollback-for="Exception" />
			<tx:method name="save*" propagation="REQUIRED"
				rollback-for="Exception" />

			<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />

			<tx:method name="create*" propagation="REQUIRED"
				rollback-for="Exception" />
		</tx:attributes>
	</tx:advice>
</beans>

hibernate的通用下次再整理





  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: Spring MVC是基于Spring框架的一种Web框架,用于开发Java Web应用程序。而Spring是一个轻量级的IoC(Inverse of Control)和AOP(Aspect-Oriented Programming)容器,通过IOC容器,可以管理各种Java Bean的生命周期和依赖关系,而通过AOP可以实现一些跨越多个模块或对象的通用功能。 MyBatis是一个持久框架,它可以将数据库操作抽象为Java接口的方法,通过配置文件将这些方法映射到相应的SQL语句,实现轻量级的数据库访问。 SpringMVC、SpringMyBatis可以结合使用来开发一个完整的Java Web项目。 在一个典型的SpringMVC、SpringMyBatis项目中,通常会有以下几个主要组件: 1. 控制器(Controller):负责接收用户的请求,处理业务逻辑,并返回相应的结果。SpringMVC提供了很多注解和接口,可以很方便地定义和处理请求。 2. 服务(Service):负责处理具体的业务逻辑。通常一个服务类会对应一个或多个DAO(Data Access Object),通过DAO对象访问数据库,获取或修改数据。 3. DAO(Data Access Object):负责封装与数据库交互的细节。通过使用MyBatis的映射文件,将Java接口的方法映射到相应的SQL语句。 4. 数据库:使用关系型数据库(如MySQL、Oracle等)存储持久化数据。 在项目中,通过配置文件和注解,将这些组件关联起来。Spring框架负责管理各个组件的生命周期和依赖关系,MyBatis提供数据访问功能,SpringMVC负责接收用户请求并将结果返回给用户。 通过SpringMVC、SpringMyBatis的结合,可以实现一个完整的Java Web项目,使开发者能够更加方便、高效地进行开发,并且能够更好地实现各个组件之间的解耦和复用。 ### 回答2: springmvc spring mybatis是一种常见的Java Web开发框架组合,被广泛应用于企业级的Web应用程序开发中。下面以一个简单的项目实例来介绍其基本用法。 假设我们要开发一个简单的学生信息管理系统,使用springmvc来搭建前端控制器,spring来进行依赖注入和事务管理,mybatis作为持久框架与数据库交互。 首先,我们需要进行项目的初始化配置。在Spring配置文件中,配置相关的bean以及包扫描路径,使得框架能够自动扫描并管理相应的组件。 接下来,我们创建相应的实体类,例如学生类,可以定义属性如姓名、年龄等,并使用注解进行实体类与数据库表的映射。同时,我们可以创建DAO接口和Mapper映射文件,用于扩展mybatis的CURD操作。 然后,我们在Controller中编写处理请求的方法,通过注解标识URL映射关系、请求类型,使用Service的方法进行业务处理,并将结果传递给视图解析器进行渲染。 在Service,我们可以编写相应的逻辑代码,例如添加、删除、修改学生信息等。同时,我们可以利用@Autowired注解将DAO的方法注入到Service中,从而将数据库操作与业务逻辑进行分离。 最后,我们可以在视图创建相应的页面,例如添加、删除、修改学生信息的页面。利用EL表达式和JSTL标签库等,实现数据的展示和交互。 总的来说,springmvc spring mybatis的项目实例中,我们通过配置框架的相关组件,编写实体类、映射文件以及相应的控制器、服务和视图代码,从而实现了一个简单的学生信息管理系统。通过这个实例,我们可以更好地理解和掌握springmvc spring mybatis的基本用法和项目架构。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值