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 项目目录结构