论坛系统(Spring+SpringMVC+Mybatis)

论坛系统(Spring+SpringMVC+Mybatis)

接着上一篇文章介绍的论坛系统—— 基于Spring+Struts1+Hibernate实现,本文章要介绍的是基于Spring+SpringMVC+Mybatis实现的论坛系统。之所以心血来潮把框架换了,是因为刚学完SpringMVC和Mybatis,只有几个SSM的例程,得不到做一个系统的实践经验,所以就尝试换了框架,经过几天的努力,最后把功能都还原了,整个小项目从创建到完成,还是挺有点成就感的,毕竟是自己把代码一个个敲出来,把功能一步步完成。目前,很多公司都使用SSM组合框架,而SSM也得到了越来越多web开发者的追捧,所以很有必要学习。

个人觉得SpringMVC比Struts好得多,在以后的开发中,我更倾向于SpringMVC,毕竟是同一家公司的产品,SpringMVC比Struts更容易契合Spring技术;而Hibernate和Mybatis各有其优点,可以根据系统的需求而选择Hibernate还是Mybatis。对两者做一些小总结:

Hibernate对数据库结构提供了较为完整的封装,只需定义好POJO 到数据库表的映射关系,即可通过Hibernate 提供的方法完成持久层操作;而Mybatis侧重于POJO 与SQL之间的映射关系,然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO。
Mybatis优势:
  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段
  • MyBatis容易掌握,而Hibernate门槛较高
Hibernate优势:
  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。(我最大的感悟是Mybatis只提供级联查询,而不能级联插入、更新
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳,更新操作不能指定刷新指定记录,会清空整个表,但是也可以使用第三方缓存。
当然,Hibernate的缺点也很明显,如果涉及到多张关联表的调用时:
  • 多表关联等比较复杂,使用的成本并不低
  • 效率比较低,在大型项目中很少使用,因为sql都是自动生成,不太好人工优化。

说点闲话,开始有点喜欢写一下博客,记录一下自己所学的知识还是挺好的,嗯,得坚持!!!!

回到正事!该基于SSM的系统直接用的是上一篇文章的数据库,懒得创建了。 整个工程目录以及数据表如下:
论坛系统(Spring+SpringMVC+Mybatis)_第1张图片   论坛系统(Spring+SpringMVC+Mybatis)_第2张图片   论坛系统(Spring+SpringMVC+Mybatis)_第3张图片   论坛系统(Spring+SpringMVC+Mybatis)_第4张图片
论坛系统(Spring+SpringMVC+Mybatis)_第5张图片
就贴一张效果图,界面跟上一篇贴出来的都一样,我只是把框架给换了,在JSP中把所有Struts的标签都换成spring提供的form标签!
论坛系统(Spring+SpringMVC+Mybatis)_第6张图片

1、使用Mybatis-Generator自动生成DAO、Model、Mapping相关文件

Mybatis属于半自动ORM,在使用这个框架中,工作量最大的就是书写Mapping的映射文件,由于手动书写很容易出错,我们可以利用Mybatis-Generator来帮我们自动生成文件。(说到底是自己懒,哈哈)尽管是这样,确实是会减少一点额外的工作。但我通常都会把生成的xxExample.java文件删掉,并对xxMapper.java、xxMapper.xml文件进行适当的删减,留下几个有用的,在此基础上再添加自己的操作语句。
generatorConfig.xml:



	
		
	
		
		
			
			
		
		
		
		 
		
		
		
		 
		
		
		

2、相关配置文件

2.1、web.xml

这里主要配置了Spring的DispatcherServlet,让它拦截所有以.do结尾的请求,还配置了一个字符过滤器,防止乱码问题(个人习惯了,不管有没有用,加上去再说)


	Forum_SSM
	
	
		org.springframework.web.context.ContextLoaderListener
	
	
		contextConfigLocation
		classpath:applicationContext.xml
	
	
	
		spring
		org.springframework.web.servlet.DispatcherServlet
		
			contextConfigLocation
			classpath:mvc-config.xml
		
		1
	
	
		spring
		*.do
	
	
	
		CharacterEncodingFilter
		filter.CharacterEncodingFilter
		
			characterEncoding
			UTF-8
		
		
			enabled
			true
		
	
	
		CharacterEncodingFilter
		/*
	

2.2、applicationContext.xml

component-scan标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Component、@Repository、@Service、@Controller标签的类自动注册到spring容器。对标记了@Required、@Autowired等注解的类进行对应的操作使注解生效。





	

	
	

		
		
		
		
		
	

	
	
		
		
		
		
	

	
	
		
	

	
	
		
		
			
			
			
			
		
	
	
	
		
		
	

	
	
		
	

2.3、SpringMVC配置文件——mvc-config.xml

该配置文件主要服务于SpringMVC流程。 在mvc-config.xml中,最重要的工作是控制转发,这个配置文件中做了最简单的转发操作,只能转发页面,如果想要通过ajax实现转发数据,那么需要重写ViewResolver来实现这个功能。把jsp文件放在WEB-INF下,这样就只能通过Controller进行访问。



	
    
    
    
    

	
	
		
			/WEB-INF/jsp/
		
		
			.jsp
		
	
	
	
    
    
        
            
            
        
    
	
	
    
    

2.4、mybatis-config.xml

在mybatis-config.xml中不需要额外的配置,它只是个空文件。

3、用户模块

3.1、Person.java

mybatis的实体类和hibernate实体类的不同是mybatis的实体类不需要加载到spring的beanFactory中,而是通过操作数据库的mapper来持久化数据。
package model;

public class Person {
    private Integer id;
    private Date datecreated;
    private Boolean deleted;
    private Integer version;
    private String account;
    private String birthday;
    private Date datelastactived;
    private String email;
    private String ipcreated;
    private String iplastactived;
    private String name;
    private String password;
    private String sex;
	//省略setter和getter方法
}

3.2、PersonMapper映射接口

对Mybatis-Generator生成的personMapper.java进行删减,只留下在该系统中可能用到的,并添加需要用到的操作方法。
package mapper;

public interface PersonMapper {
	Person getPerson(Person person);
	Person selectByAccount(String account);
	List selectBoardByPersonId(int id);
	List selectAll();
	int deleteByBoardId(Integer id);
	int insertBoardAdministrator(@Param("boardId") int boardId, @Param("personId") int personId);
	/*以上为自己实现的方法,保留了下面可能用到的方法*/
	int deleteByPrimaryKey(Integer id);
	int insert(Person record);
	int insertSelective(Person record);
	Person selectByPrimaryKey(Integer id);
	int updateByPrimaryKeySelective(Person record);
	int updateByPrimaryKey(Person record);
}

3.3、PersonMapper.xml映射文件




  
    
    
    
    
    
    
    
    
    
    
    
    
    
  
  
  
  
  
    id, dateCreated, deleted, version, account, birthday, dateLastActived, email, ipCreated, 
    ipLastActived, name, password, sex
  
  
    id, dateCreated, deleted, version, description, name, replyCount, threadCount, category_id, 
    last_reply_id, last_thread_id
  
  
  
  
  
  
  
  
  
  
  
  
  
	delete from board_administrator
	where board_id = #{boardId,jdbcType=INTEGER}
  
  
  
  	insert into board_administrator
  	values (#{boardId}, #{personId})
  
  
  
  
    delete from person
    where id = #{id,jdbcType=INTEGER}
  

  
    insert into person (id, dateCreated, deleted, 
      version, account, birthday, 
      dateLastActived, email, ipCreated, 
      ipLastActived, name, password, 
      sex)
    values (#{id,jdbcType=INTEGER}, #{datecreated,jdbcType=TIMESTAMP}, #{deleted,jdbcType=BIT}, 
      #{version,jdbcType=INTEGER}, #{account,jdbcType=VARCHAR}, #{birthday,jdbcType=VARCHAR}, 
      #{datelastactived,jdbcType=TIMESTAMP}, #{email,jdbcType=VARCHAR}, #{ipcreated,jdbcType=VARCHAR}, 
      #{iplastactived,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{sex,jdbcType=VARCHAR})
  
  
    insert into person
    
      
        id,
      
      
        dateCreated,
      
      
        deleted,
      
      
        version,
      
      
        account,
      
      
        birthday,
      
      
        dateLastActived,
      
      
        email,
      
      
        ipCreated,
      
      
        ipLastActived,
      
      
        name,
      
      
        password,
      
      
        sex,
      
    
    
      
        #{id,jdbcType=INTEGER},
      
      
        #{datecreated,jdbcType=TIMESTAMP},
      
      
        #{deleted,jdbcType=BIT},
      
      
        #{version,jdbcType=INTEGER},
      
      
        #{account,jdbcType=VARCHAR},
      
      
        #{birthday,jdbcType=VARCHAR},
      
      
        #{datelastactived,jdbcType=TIMESTAMP},
      
      
        #{email,jdbcType=VARCHAR},
      
      
        #{ipcreated,jdbcType=VARCHAR},
      
      
        #{iplastactived,jdbcType=VARCHAR},
      
      
        #{name,jdbcType=VARCHAR},
      
      
        #{password,jdbcType=VARCHAR},
      
      
        #{sex,jdbcType=VARCHAR},
      
    
  

  
    update person
    
      
        dateCreated = #{datecreated,jdbcType=TIMESTAMP},
      
      
        deleted = #{deleted,jdbcType=BIT},
      
      
        version = #{version,jdbcType=INTEGER},
      
      
        account = #{account,jdbcType=VARCHAR},
      
      
        birthday = #{birthday,jdbcType=VARCHAR},
      
      
        dateLastActived = #{datelastactived,jdbcType=TIMESTAMP},
      
      
        email = #{email,jdbcType=VARCHAR},
      
      
        ipCreated = #{ipcreated,jdbcType=VARCHAR},
      
      
        ipLastActived = #{iplastactived,jdbcType=VARCHAR},
      
      
        name = #{name,jdbcType=VARCHAR},
      
      
        password = #{password,jdbcType=VARCHAR},
      
      
        sex = #{sex,jdbcType=VARCHAR},
      
    
    where id = #{id,jdbcType=INTEGER}
  
  
    update person
    set dateCreated = #{datecreated,jdbcType=TIMESTAMP},
      deleted = #{deleted,jdbcType=BIT},
      version = #{version,jdbcType=INTEGER},
      account = #{account,jdbcType=VARCHAR},
      birthday = #{birthday,jdbcType=VARCHAR},
      dateLastActived = #{datelastactived,jdbcType=TIMESTAMP},
      email = #{email,jdbcType=VARCHAR},
      ipCreated = #{ipcreated,jdbcType=VARCHAR},
      ipLastActived = #{iplastactived,jdbcType=VARCHAR},
      name = #{name,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      sex = #{sex,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  

3.4、PersonDAO层及其实现

本系统继续沿用了DAO层和Service层的编程习惯。
package DAO;

public interface PersonDAO {
	public void save(Person person);
	public int insert(Person person);
	public Person selectById(int id);
	public List selectBoardByPersonId(int id);
	public List selectAll();
	public Person findPersonByAccount(String account);
	public Person getPerson(Person person);
	public int deleteByBoardId(int id);
	public int insertBoardAdministrator(int boardId, int personId);
}

package DAOImpl;

@Repository
public class PersonDAOImpl implements PersonDAO{

	@Autowired
	private PersonMapper personMapper;

	@Override
	public Person findPersonByAccount(String account) {
		return personMapper.selectByAccount(account);
	}
	@Override
	public Person getPerson(Person person) {
		return personMapper.getPerson(person);
	}
	@Override
	public void save(Person person) {
		personMapper.updateByPrimaryKeySelective(person);
	}
	@Override
	public int insert(Person person) {
		return personMapper.insertSelective(person);
	}
	@Override
	public Person selectById(int id) {
		return personMapper.selectByPrimaryKey(id);
	}
	@Override
	public List selectBoardByPersonId(int id) {
		return personMapper.selectBoardByPersonId(id);
	}
	@Override
	public List selectAll() {
		return personMapper.selectAll();
	}
	@Override
	public int deleteByBoardId(int id) {
		return personMapper.deleteByBoardId(id);
	}
	@Override
	public int insertBoardAdministrator(int boardId, int personId) {
		return personMapper.insertBoardAdministrator(boardId, personId);
	}
}

3.5、PersonService层及其实现

package Service;

public interface PersonService {
	
	public void save(Person person);
	public int insert(Person person);
	public Person selectById(int id);
	public List selectAll();
	public List selectBoardByPersonId(int id);
	public Person findPersonByAccount(String account);
	public Person getPerson(Person person);
	public int deleteByBoardId(int id);
	public int insertBoardAdministrator(int boardId, int personId);
}

package ServiceImpl;

@Service
public class PersonServiceImpl implements PersonService{

	@Autowired
	private PersonDAO personDAO;

	@Override
	public Person findPersonByAccount(String account) {
		return personDAO.findPersonByAccount(account);
	}

	@Override
	public Person getPerson(Person person) {
		Person newper=new Person();
		newper.setAccount(person.getAccount());
		newper.setPassword(MD5Util.calc(person.getPassword()));
		return personDAO.getPerson(newper);
	}

	@Override
	public void save(Person person) {
		personDAO.save(person);
	}

	@Override
	public int insert(Person person) {
		if(findPersonByAccount(person.getAccount())!=null)
			throw new RuntimeException("帐号 " + person.getAccount() + " 已经存在。");
		person.setPassword(MD5Util.calc(person.getPassword()));
		return personDAO.insert(person);
	}

	@Override
	public Person selectById(int id) {
		return personDAO.selectById(id);
	}

	@Override
	public List selectBoardByPersonId(int id) {
		return personDAO.selectBoardByPersonId(id);
	}

	@Override
	public List selectAll() {
		return personDAO.selectAll();
	}

	@Override
	public int deleteByBoardId(int id) {
		return personDAO.deleteByBoardId(id);
	}

	@Override
	public int insertBoardAdministrator(int boardId, int personId) {
		return personDAO.insertBoardAdministrator(boardId, personId);
	} 

}

3.6、Person控制器

package Controller;

@Controller
public class PersonController {

	@Autowired
	private PersonService personService;
	
	@RequestMapping("person_initAdd.do")
	public ModelAndView initAdd(HttpServletRequest request){
		request.setAttribute("title", "用户注册");
		request.setAttribute("person", new Person());
		return new ModelAndView("person/addPerson");
	}
	
	
	@RequestMapping("person_add.do")
	public ModelAndView add(@ModelAttribute Person person, HttpServletRequest request, HttpServletResponse response){
		request.setAttribute("title", "用户注册");
		person.setIpcreated(request.getRemoteAddr());
		person.setIplastactived(request.getRemoteAddr());
		person.setDatecreated(new Date());
		person.setDatelastactived(new Date());
		person.setDeleted(false);
		if (person.getAccount() == null|| person.getAccount().trim().length() == 0) {
			request.setAttribute("message", "请输入帐号");
			return initAdd(request);
		}
		if (person.getPassword() == null|| person.getPassword().trim().length() == 0|| !person.getPassword().equals(request.getParameter("password1"))) {
			request.setAttribute("message", "密码不一致");
			return initAdd(request);
		}
		try {
			personService.insert(person);//保存到数据库,此时没有id
			PersonUtil.setPersonInf(request, response, personService.findPersonByAccount(person.getAccount()));
			request.setAttribute("message", "注册成功");
			return new ModelAndView("person/success");
		} catch (Exception e) {
			request.setAttribute("message", "注册失败,原因:" + e.getMessage());
			return initAdd(request);
		}
	}
	
	@RequestMapping("person_initLogin.do")
	public ModelAndView initLogin(HttpServletRequest request){
		request.setAttribute("person", new Person());
		request.setAttribute("title", "用户登录");
		return new ModelAndView("person/login");
	}
	
	@RequestMapping("person_login.do")
	public ModelAndView login(@ModelAttribute Person person,HttpServletRequest request, HttpServletResponse response) throws Exception{
		request.setAttribute("title", "用户登录");
		Person person1=personService.getPerson(person);
		if (person1 == null)
			throw new AccountException("用户名密码错误");
		PersonUtil.setPersonInf(request, response, person1);
		person1.setIplastactived(request.getRemoteAddr());
		person1.setDatelastactived(new Date());
		personService.save(person1);
		request.setAttribute("message", "欢迎回来");
		return new ModelAndView("person/success");
	}
	
	@RequestMapping("person_logout.do")
	public ModelAndView logout(HttpServletRequest request){
		request.setAttribute("title", "用户注销");
		request.getSession(true).setAttribute(PersonUtil.PERSON_INFO, null);
		request.setAttribute("person", new Person());
		return new ModelAndView("person/login");
	}
	
	@RequestMapping("person_view.do")
	public ModelAndView view(HttpServletRequest request){
		request.setAttribute("title", "查看用户资料");
		int id=Integer.parseInt(request.getParameter("id"));
		Person person=personService.selectById(id);
		request.setAttribute("person", person);
		List boardList=personService.selectBoardByPersonId(id);
		request.setAttribute("boardList", boardList);
		return new ModelAndView("person/viewPerson");
	}
}

4、版面类型模块

4.1、Category.java

boardList需要自己手动,因为它并不属于表中的字段,级联查询时需要用到
package model;

public class Category {
	private Integer id;

	private Date datecreated;

	private Boolean deleted;

	private Integer version;

	private String name;

	private List boardList; //省略setter、getter方法
}

4.2、CategoryMapper映射接口

package mapper;

public interface CategoryMapper {

	List getList();

	Category selectByName(String name);

	List getAll();

	/*以上为自己实现的方法,保留了下面可能用到的方法*/

	int deleteByPrimaryKey(Integer id);

	int insert(Category record);

	int insertSelective(Category record);

	Category selectByPrimaryKey(Integer id);

	int updateByPrimaryKeySelective(Category record);

	int updateByPrimaryKey(Category record);
}

4.3、CategoryMapper.xml映射文件




  
    
    
    
    
    
  
  
    
  
  
  
    id, dateCreated, deleted, version, name
  
  
  
  
  
  
  
  
  
    delete from category
    where id = #{id,jdbcType=INTEGER}
  
  
    insert into category (id, dateCreated, deleted, 
      version, name)
    values (#{id,jdbcType=INTEGER}, #{datecreated,jdbcType=TIMESTAMP}, #{deleted,jdbcType=BIT}, 
      #{version,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
  
  
    insert into category
    
      
        id,
      
      
        dateCreated,
      
      
        deleted,
      
      
        version,
      
      
        name,
      
    
    
      
        #{id,jdbcType=INTEGER},
      
      
        #{datecreated,jdbcType=TIMESTAMP},
      
      
        #{deleted,jdbcType=BIT},
      
      
        #{version,jdbcType=INTEGER},
      
      
        #{name,jdbcType=VARCHAR},
      
    
  

  
    update category
    
      
        dateCreated = #{datecreated,jdbcType=TIMESTAMP},
      
      
        deleted = #{deleted,jdbcType=BIT},
      
      
        version = #{version,jdbcType=INTEGER},
      
      
        name = #{name,jdbcType=VARCHAR},
      
    
    where id = #{id,jdbcType=INTEGER}
  
  
    update category
    set dateCreated = #{datecreated,jdbcType=TIMESTAMP},
      deleted = #{deleted,jdbcType=BIT},
      version = #{version,jdbcType=INTEGER},
      name = #{name,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  

4.4、CategoryDAO层及其实现

package DAO;

public interface CategoryDAO {

	public List getList();

	public int create(Category category);
	
	public Category selectByName(String name);
	
	public List getAll();
}

package DAOImpl;

@Repository
public class CategoryDAOImpl implements CategoryDAO{

	@Autowired
	private CategoryMapper categoryMapper;

	@Override
	public List getList() {
		return categoryMapper.getList();
	}

	@Override
	public int create(Category category) {
		return categoryMapper.insertSelective(category);
	}

	@Override
	public Category selectByName(String name) {
		return categoryMapper.selectByName(name);
	}

	@Override
	public List getAll() {
		return categoryMapper.getAll();
	}
}

4.5、CategoryService层及其实现

package Service;

public interface CategoryService {

	public List getList();
	
	public int create(Category category);
	
	public List getAll();
}

package ServiceImpl;

@Service
public class CategoryServiceImpl implements CategoryService{

	@Autowired
	private CategoryDAO categoryDAO;

	@Override
	public List getList() {
		return categoryDAO.getList();
	}

	@Override
	public int create(Category category) {
		if(categoryDAO.selectByName(category.getName())!=null)
			throw new RuntimeException("类别 " + category.getName() + " 已经存在。");
		return categoryDAO.create(category);
	}

	@Override
	public List getAll() {
		return categoryDAO.getAll();
	}
}

4.6、Category控制层

package Controller;

@Controller
public class CategoryController {
	
	@Autowired
	private CategoryService categoryService;
	
	@RequestMapping("category_list.do")
	public ModelAndView list(HttpServletRequest request){
		request.setAttribute("title", "轻量级 Java EE 论坛程序");
		List categoryList = categoryService.getList();
		request.setAttribute("categoryList", categoryList);
		return new ModelAndView("category/listCategory");
	}
	
	@RequestMapping("category_initAdd.do")
	public ModelAndView initAdd(HttpServletRequest request){
		request.setAttribute("title", "添加类别");
		request.setAttribute("category", new Category());
		return new ModelAndView("category/addCategory");
	}
	
	@RequestMapping("category_add.do")
	public ModelAndView add(@ModelAttribute Category category, HttpServletRequest request){
		request.setAttribute("title", "添加类别");
		category.setDatecreated(new Date());
		category.setDeleted(false);
		categoryService.create(category);
		return new ModelAndView("category/success");
	}

}

好吧!我承认老是贴代码,毫无营养!版面模块、帖子模块和回帖模块的代码就不贴出来了。如果是我也没耐心看完,直接下载源码学来得更实际一些。

下载源码

数据库脚本:
create database forum character set utf8 ;

use forum;

CREATE TABLE if not exists person (
  id int(11) NOT NULL AUTO_INCREMENT,
  dateCreated datetime DEFAULT NULL,
  deleted bit(1) NOT NULL,
  version int(11) DEFAULT NULL,
  account varchar(255) DEFAULT NULL,
  birthday varchar(255) DEFAULT NULL,
  dateLastActived datetime DEFAULT NULL,
  email varchar(255) DEFAULT NULL,
  ipCreated varchar(255) DEFAULT NULL,
  ipLastActived varchar(255) DEFAULT NULL,
  name varchar(255) DEFAULT NULL,
  password varchar(255) DEFAULT NULL,
  sex varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE category (
  id int(11) NOT NULL AUTO_INCREMENT,
  dateCreated datetime DEFAULT NULL,
  deleted bit(1) NOT NULL,
  version int(11) DEFAULT NULL,
  name varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
);


CREATE TABLE thread (
  id int(11) NOT NULL AUTO_INCREMENT,
  dateCreated datetime DEFAULT NULL,
  deleted bit(1) NOT NULL,
  version int(11) DEFAULT NULL,
  content longtext,
  dateLastReplied datetime DEFAULT NULL,
  hit int(11) NOT NULL,
  ipCreated varchar(255) DEFAULT NULL,
  readonly bit(1) NOT NULL,
  replyCount int(11) NOT NULL,
  title varchar(255) DEFAULT NULL,
  topped bit(1) NOT NULL,
  author_id int(11) DEFAULT NULL,
  author_last_replied_id int(11) DEFAULT NULL,
  board_id int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (author_last_replied_id) REFERENCES person (id),
  FOREIGN KEY (author_id) REFERENCES person (id)
);
alter table thread add FOREIGN KEY (board_id) REFERENCES board (id);

CREATE TABLE reply (
  id int(11) NOT NULL AUTO_INCREMENT,
  dateCreated datetime DEFAULT NULL,
  deleted bit(1) NOT NULL,
  version int(11) DEFAULT NULL,
  content varchar(255) DEFAULT NULL,
  floor int(11) NOT NULL,
  ipCreated varchar(255) DEFAULT NULL,
  title varchar(255) DEFAULT NULL,
  author_id int(11) DEFAULT NULL,
  thread_id int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (author_id) REFERENCES person (id),
  FOREIGN KEY (thread_id) REFERENCES thread (id)
);

CREATE TABLE board(
  id int(11) NOT NULL AUTO_INCREMENT,
  dateCreated datetime DEFAULT NULL,
  deleted bit(1) NOT NULL,
  version int(11) DEFAULT NULL,
  description varchar(255) DEFAULT NULL,
  name varchar(255) DEFAULT NULL,
  replyCount int(11) NOT NULL,
  threadCount int(11) NOT NULL,
  category_id int(11) DEFAULT NULL,
  last_reply_id int(11) DEFAULT NULL,
  last_thread_id int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (last_thread_id) REFERENCES thread (id),
  FOREIGN KEY (last_reply_id) REFERENCES reply (id),
  FOREIGN KEY (category_id) REFERENCES category (id)
);


CREATE TABLE board_administrator (
  board_id int(11) NOT NULL,
  person_id int(11) NOT NULL,
  PRIMARY KEY (board_id,person_id),
  FOREIGN KEY (person_id) REFERENCES person (id),
  FOREIGN KEY (board_id) REFERENCES board (id)
);



你可能感兴趣的:(Web开发,Forum,web开发系统例程,论坛系统,SSM)