基于MyBatis和Spring泛型DAO的三层架构

1 介绍

项目整合了Spring和SpringMVC,MyBatis,在这里已经整合过了:http://my.oschina.net/ChiLin/blog/689022

这里是在已经整合的基础上改进DAO和Service。。。

这里只补充一下Spring和MyBatis的配置文件:applicationContext-mybatis:

<?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.xsd 
                     http://www.springframework.org/schema/tx 
                     http://www.springframework.org/schema/tx/spring-tx.xsd 
                     http://www.springframework.org/schema/aop 
                     http://www.springframework.org/schema/aop/spring-aop.xsd
                     http://www.springframework.org/schema/context 
  					 http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean name="baseServiceImpl" class="com.lin.ssm.service.impl.BaseServiceImpl"/>
	
	<bean name="newsServiceImpl" class="com.lin.ssm.service.impl.NewsServiceImpl" parent="baseServiceImpl">
		<constructor-arg index="0" ref="newsDaoImpl" />
		<property name="commentDao" ref="commentDaoImpl"/>
	</bean>

</beans>

2 实体类和映射

写了一个News类,一个Comment类,News和Comment是一对多的关系。

2.1 实体类

News类:

package com.lin.ssm.domain;

import java.util.ArrayList;
import java.util.List;

public class News {
	
	private int id;
	
	private String title;
	
	private String content;
	
	private List<Comment> comments = new ArrayList<Comment>();

	public News() {
	}

	public News(int id, String title, String content) {
		this.id = id;
		this.title = title;
		this.content = content;
	}

	public int getId() {
		return id;
	}

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

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public List<Comment> getComments() {
		return comments;
	}

	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}

	@Override
	public String toString() {
		return "News [id=" + id + ", title=" + title + ", content=" + content
				+ ", comments=" + comments + "]";
	}

}

Comment类:

package com.lin.ssm.domain;

public class Comment {
	
	private int id;
	
	private String content;
	
	private News news;//many to one

	public int getId() {
		return id;
	}

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

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public News getNews() {
		return news;
	}

	public void setNews(News news) {
		this.news = news;
	}

	@Override
	public String toString() {
		return "Comment [id=" + id + ", content=" + content + ", news=" + news
				+ "]";
	}

}

2.2 ORM映射

News类的映射:

<?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.lin.ssm.mapper.NewsMapper">

	<resultMap type="com.lin.ssm.domain.News" id="newsMap">
		<id property="id" column="NEWS_ID"/>
		<result property="title" column="TITLE"/>
		<result property="content" column="CONTENT"/>
		<collection property="comments" ofType="com.lin.ssm.domain.Comment">
			<id property="id" column="COMMENT_ID"/>
			<result property="content" column="CONTENT"/>
		</collection>
	</resultMap>
	
	<insert id="create" parameterType="com.lin.ssm.domain.News">
		insert into TB_NEWS (TITLE,CONTENT) values (#{title},#{content})
	</insert>
	
	<select id="read" parameterType="int" resultMap="newsMap">
		SELECT n.*,c.* FROM TB_NEWS n left outer join TB_COMMENT c on n.NEWS_ID=c.NEWS_ID WHERE n.NEWS_ID=#{id}
	</select>
	
	<select id="readAll" resultMap="newsMap">
		SELECT n.*,c.* FROM TB_NEWS n left outer join TB_COMMENT c on n.NEWS_ID=c.NEWS_ID
	</select>
	
	<update id="update" parameterType="com.lin.ssm.domain.News">
		update TB_NEWS set TITLE=#{title},CONTENT=#{content} where NEWS_ID=#{id}
	</update>
	
	<delete id="delete" parameterType="int">
		delete from TB_NEWS where NEWS_ID=#{id}
	</delete>
	
	<select id="countOfNews" resultType="int">
		select count(*) from TB_NEWS
	</select>

</mapper>

Comment类的映射:

<?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.lin.ssm.mapper.CommentMapper">

	<resultMap type="com.lin.ssm.domain.Comment" id="commentMap">
		<id property="id" column="COMMENT_ID"/>
		<result property="content" column="CONTENT"/>
		
		<association property="news" javaType="com.lin.ssm.domain.News">
			<id property="id" column="NEWS_ID"/>
			<result property="title" column="TITLE"/>
			<result property="content" column="CONTENT"/>
		</association>
	</resultMap>
	
	<insert id="create" parameterType="com.lin.ssm.domain.Comment">
		insert into TB_COMMENT (CONTENT,NEWS_ID) values (#{content},#{news.id})
	</insert>
	
	<select id="read" parameterType="int" resultMap="commentMap">
		select TB_COMMENT.*,TB_NEWS.* from
		 TB_COMMENT left outer join TB_NEWS on TB_COMMENT.NEWS_ID=TB_NEWS.NEWS_ID where
		  TB_COMMENT.COMMENT_ID=#{id}
	</select>
	
	<select id="readAll" resultMap="commentMap">
		select TB_COMMENT.*,TB_NEWS.* from
		 TB_COMMENT left outer join TB_NEWS on TB_COMMENT.NEWS_ID=TB_NEWS.NEWS_ID
	</select>
	
	<update id="update" parameterType="com.lin.ssm.domain.Comment">
		update TB_COMMENT set CONTENT=#{content} where COMMENT_ID=#{id}
	</update>
	
	<delete id="delete" parameterType="int">
		delete from TB_COMMENT where COMMENT_ID=#{id}
	</delete>
	
	<select id="countOfComments" resultType="int">
		select count(*) from TB_COMMENT
	</select>

</mapper>

2.3 映射接口

接口名称要和映射配置文件的namespace一致

下面是一个泛型映射接口,它把CRUD方法抽象出来。

package com.lin.ssm.mapper;

import java.util.List;

/**
 * 注意方法名称要和配置文件中的<select>/<insert>/<update>/<delete>的 id 一致
 * @author lin
 *
 * @param <T>
 */
public interface Mapper<T> {
	
	public void create(T t);
	
	public T read(int id);
	
	public void update(T t);
	
	public void delete(int id);
	
	public List<T> readAll();

}

下面是具体的映射接口:

package com.lin.ssm.mapper;

import com.lin.ssm.domain.News;

public interface NewsMapper extends Mapper<News> {
	
	public int countOfNews();

}
package com.lin.ssm.mapper;

import com.lin.ssm.domain.Comment;

public interface CommentMapper extends Mapper<Comment> {
	
	public int countOfComments();

}

这些接口只需要抽象自己特有的方法。

2.4 配置mapper接口

applicationContext-mapper.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.xsd 
                     http://www.springframework.org/schema/tx 
                     http://www.springframework.org/schema/tx/spring-tx.xsd 
                     http://www.springframework.org/schema/aop 
                     http://www.springframework.org/schema/aop/spring-aop.xsd
                     http://www.springframework.org/schema/context 
  					 http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean name="newsMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
		<property name="mapperInterface" value="com.lin.ssm.mapper.NewsMapper" />
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>
	
	<bean name="commentMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
		<property name="mapperInterface" value="com.lin.ssm.mapper.CommentMapper"/>
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>

</beans>

3 DAO层

3.1 通用DAO接口

package com.lin.ssm.dao;

import java.util.List;

public interface IBaseDao<T> {
	
	public void create(T t);
	
	public T read(int key);
	
	public void update(T t);
	
	public void delete(int key);
	
	public List<T> readAll();

}

3.2 通用DAO实现

package com.lin.ssm.dao.impl;

import java.util.List;

import com.lin.ssm.dao.IBaseDao;
import com.lin.ssm.mapper.Mapper;

public abstract class BaseDaoImpl<T> implements IBaseDao<T> {
	
	private Mapper<T> mapper;

	public BaseDaoImpl(Mapper<T> mapper) {
		super();
		this.mapper = mapper;
	}

	public Mapper<T> getMapper() {
		return mapper;
	}

	public void setMapper(Mapper<T> mapper) {
		this.mapper = mapper;
	}

	@Override
	public void create(T t) {
		
		if(t != null)
		{
			mapper.create(t);
		}
	}

	@Override
	public T read(int key) {
		
		return mapper.read(key);
	}

	@Override
	public void update(T t) {
		
		if(t != null)
		{
			mapper.update(t);
		}
	}

	@Override
	public void delete(int key) {
		
		mapper.delete(key);
	}

	@Override
	public List<T> readAll() {
		
		return mapper.readAll();
	}

}

3.3 具体DAO接口

同样,这些接口只需抽象自己特有的方法

News的DAO接口

package com.lin.ssm.dao;

import com.lin.ssm.domain.News;

public interface INewsDao extends IBaseDao<News> {
	
	public int countOfNews();

}

Comment的DAO接口

package com.lin.ssm.dao;

import com.lin.ssm.domain.Comment;

public interface ICommentDao extends IBaseDao<Comment> {
	
	public int countOfComments();

}

3.4 具体DAO实现

package com.lin.ssm.dao.impl;

import com.lin.ssm.dao.INewsDao;
import com.lin.ssm.domain.News;
import com.lin.ssm.mapper.Mapper;
import com.lin.ssm.mapper.NewsMapper;

public class NewsDaoImpl extends BaseDaoImpl<News> implements INewsDao {
	
	private NewsMapper newsMapper;

	public NewsDaoImpl(Mapper<News> mapper) {
		super(mapper);
		this.newsMapper = (NewsMapper)mapper;
	}

	public NewsMapper getNewsMapper() {
		return newsMapper;
	}

	public void setNewsMapper(NewsMapper newsMapper) {
		this.newsMapper = newsMapper;
	}

	@Override
	public int countOfNews() {
		
		return newsMapper.countOfNews();
	}

}
package com.lin.ssm.dao.impl;

import com.lin.ssm.dao.ICommentDao;
import com.lin.ssm.domain.Comment;
import com.lin.ssm.mapper.CommentMapper;
import com.lin.ssm.mapper.Mapper;

public class CommentDaoImpl extends BaseDaoImpl<Comment> implements ICommentDao {
	
	private CommentMapper commentMapper;

	public CommentMapper getCommentMapper() {
		return commentMapper;
	}

	public void setCommentMapper(CommentMapper commentMapper) {
		this.commentMapper = commentMapper;
	}

	public CommentDaoImpl(Mapper<Comment> mapper) {
		super(mapper);
		
		this.commentMapper = (CommentMapper)mapper;
	}

	@Override
	public int countOfComments() {
		
		return commentMapper.countOfComments();
	}

}

3.5 配置DAO组件

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: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.xsd 
                     http://www.springframework.org/schema/tx 
                     http://www.springframework.org/schema/tx/spring-tx.xsd 
                     http://www.springframework.org/schema/aop 
                     http://www.springframework.org/schema/aop/spring-aop.xsd
                     http://www.springframework.org/schema/context 
  					 http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean name="baseDaoImpl" class="com.lin.ssm.dao.impl.BaseDaoImpl"
		abstract="true"></bean>

	<bean name="newsDaoImpl" class="com.lin.ssm.dao.impl.NewsDaoImpl"
		parent="baseDaoImpl">
		<constructor-arg index="0" ref="newsMapper" />
	</bean>
	
	<bean name="commentDaoImpl" class="com.lin.ssm.dao.impl.CommentDaoImpl"
		parent="baseDaoImpl">
		<constructor-arg index="0" ref="commentMapper" />
	</bean>

</beans>

4 Service层

4.1 通用Service接口

package com.lin.ssm.service;

import java.util.List;

public interface IBaseService<T> {
	
	public void add(T t);
	
	public void deleteById(int id);
	
	public void update(T t);
	
	public T queryById(int id);
	
	public List<T> queryForAll();

}

4.2 通用Service实现

package com.lin.ssm.service.impl;

import java.util.List;

import com.lin.ssm.dao.IBaseDao;
import com.lin.ssm.service.IBaseService;

public class BaseServiceImpl<T> implements IBaseService<T> {
	
	private IBaseDao<T> baseDao;

	public BaseServiceImpl() {
	}

	public BaseServiceImpl(IBaseDao<T> baseDao) {
		this.baseDao = baseDao;
	}

	public IBaseDao<T> getBaseDao() {
		return baseDao;
	}

	public void setBaseDao(IBaseDao<T> baseDao) {
		this.baseDao = baseDao;
	}

	@Override
	public void add(T t) {
		
		if(t != null)
		{
			baseDao.create(t);
		}
	}

	@Override
	public void deleteById(int id) {
		
		baseDao.delete(id);
	}

	@Override
	public void update(T t) {
		
		if(t != null)
		{
			baseDao.update(t);
		}
	}

	@Override
	public T queryById(int id) {
		
		return baseDao.read(id);
	}

	@Override
	public List<T> queryForAll() {
		
		return baseDao.readAll();
	}

}

4.3 具体Service接口

package com.lin.ssm.service;

import com.lin.ssm.domain.Comment;
import com.lin.ssm.domain.News;

public interface INewsService extends IBaseService<News> {
	
	public void addComment(Comment comment);

}

4.4 具体Service实现

package com.lin.ssm.service.impl;

import com.lin.ssm.dao.IBaseDao;
import com.lin.ssm.dao.ICommentDao;
import com.lin.ssm.dao.INewsDao;
import com.lin.ssm.domain.Comment;
import com.lin.ssm.domain.News;
import com.lin.ssm.service.INewsService;

public class NewsServiceImpl extends BaseServiceImpl<News> implements INewsService {

	private INewsDao newsDao;
	
	private ICommentDao commentDao;
	
	public NewsServiceImpl(IBaseDao<News> baseDao) {
		super(baseDao);
		this.newsDao = (INewsDao)baseDao;
	}

	public INewsDao getNewsDao() {
		return newsDao;
	}

	public void setNewsDao(INewsDao newsDao) {
		this.newsDao = newsDao;
	}

	public ICommentDao getCommentDao() {
		return commentDao;
	}

	public void setCommentDao(ICommentDao commentDao) {
		this.commentDao = commentDao;
	}

	@Override
	public void addComment(Comment comment) {
		
		if(comment != null)
		{
			commentDao.create(comment);
		}
	}

}

4.5 配置Service组件

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: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.xsd 
                     http://www.springframework.org/schema/tx 
                     http://www.springframework.org/schema/tx/spring-tx.xsd 
                     http://www.springframework.org/schema/aop 
                     http://www.springframework.org/schema/aop/spring-aop.xsd
                     http://www.springframework.org/schema/context 
  					 http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean name="baseServiceImpl" class="com.lin.ssm.service.impl.BaseServiceImpl"/>
	
	<bean name="newsServiceImpl" class="com.lin.ssm.service.impl.NewsServiceImpl" parent="baseServiceImpl">
		<constructor-arg index="0" ref="newsDaoImpl" />
		<property name="commentDao" ref="commentDaoImpl"/>
	</bean>

</beans>

5 测试

package com.lin.ssm.test;

import javax.annotation.Resource;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.lin.ssm.domain.Comment;
import com.lin.ssm.domain.News;
import com.lin.ssm.service.INewsService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring-mybatis.xml","classpath*:applicationContext-*.xml"})
public class Test {
	
	@Resource(name="newsServiceImpl")
	private INewsService newsService;

	public INewsService getNewsService() {
		return newsService;
	}

	public void setNewsService(INewsService newsService) {
		this.newsService = newsService;
	}

	@org.junit.Test
	public void test()
	{
		News news = newsService.queryById(2);
		System.out.println(news);
		
		Comment comment = new Comment();
		comment.setContent("Comment to news2");
		comment.setNews(news);
		
		newsService.addComment(comment);
	}
}

6 项目目录结构

 

 

转载于:https://my.oschina.net/ChiLin/blog/689618

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值