springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例

一:准备工作

1.下载安装MySql,确保安装成功。

2.下载mave、springside并配置,参考:https://github.com/springside/springside4/wiki/QuickStart

3.Eclipse配置m2eclipse.参考上篇博客:http://my.oschina.net/robinjiang/blog/83735

4.成功运行quickstart,运行界面如下:

 

springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第1张图片        springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第2张图片

 

二: 配置Mysql

    1.官方参考资料:https://github.com/springside/springside4/wiki/DataBase

    2.修改pom.xml,注释掉h2相关配置

    

 


 


 


 

<!-- 项目属性,修改为mysql -->
		<!--  
		<jdbc.driver.groupId>com.h2database</jdbc.driver.groupId>
		<jdbc.driver.artifactId>h2</jdbc.driver.artifactId>
		<jdbc.driver.version>${h2.version}</jdbc.driver.version>
		-->
		
			<jdbc.driver.groupId>mysql</jdbc.driver.groupId>
			<jdbc.driver.artifactId>mysql-connector-java</jdbc.driver.artifactId>
			<jdbc.driver.version>5.0.8</jdbc.driver.version>
<!--  注释掉
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>${h2.version}</version>
			<scope>test</scope>
		</dependency>
         -->
            <!-- 修改刷新开发环境数据库,将sql脚本定义至mysql的脚本 -->
		<sql driver="${jdbc.driver}" url="${jdbc.url}" userid="${jdbc.username}" password="${jdbc.password}" onerror="continue">
									<classpath refid="maven.test.classpath" />
									<transaction src="src/main/resources/sql/mysql/schema.sql"/>
									<transaction src="src/test/resources/data/import-data.sql"/>
								</sql>


 


 


 

 

3.修改application.properties

 


 


 


 

#mysql database setting
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234

#dbcp settings
dbcp.maxIdle=5
dbcp.maxActive=40


 


 


 

 

4.修改applicationContext.xml相应部分

如果在functional测试期间也需要使用mysql,更改application.functional.properties中的配置,并且修改applicatonContext.xml的functional profile中的sql脚本目录。

 

5.在mysql下新建数据库(例如:springdb),然后运行springside下的mysql脚本

 

springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第3张图片

 

6.运行springside项目bin下的refresh-db.bat,刷新数据。会看到表中多了数据

springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第4张图片

 

三:CRUD示例

    官方资料:https://github.com/springside/springside4/wiki/Tutorial。但是我按照官方资料运行有点错误,所以自己总结下。

    1.数据库设计:

    在src/resouces/sql/mysql/schema.sql 中手工编写创建表的sql。 建好之后最好运行springside项目bin下的refresh-db.bat,刷新数据。

 


 


 


 

create table acct_user (
        id bigint auto_increment,
        email varchar(255),
        login_name varchar(255) not null unique,
        name varchar(255),
        password varchar(255),
        primary key (id)
) engine=InnoDB;


 


 


 

 

    2.Entity

        2.1 手工编写Entity,利用默认大于配置原理,写尽量少的注释, 一般只有带前缀的表名,Cache和关联属性需要注释。

 


 


 


 

package org.springside.examples.quickstart.entity;

import javax.persistence.Entity;
import javax.persistence.Table;

import org.hibernate.validator.constraints.NotBlank;

//JPA标识
@Entity
@Table(name="ACCT_USER")
public class UserDemo extends IdEntity {
	private String loginName;
	private String password;
	private String name;
	private String email;

	@NotBlank
	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}


 


 


 

 

     2.2 执行test中的JpaMapptingTest.java校验ORM配置正确。

     2.3 Spring的LocalContainerEntityManagerFactoryBean能自动扫描packagesToScan中的@Entity类,无需逐一配置。    

    3.DAO

     3.1写一个简单的DAO接口,日后再根据需要添加方法定义。


 

 


 


 


 

package org.springside.examples.quickstart.repository;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springside.examples.quickstart.entity.UserDemo;

public interface UserDemoDao extends PagingAndSortingRepository<UserDemo, Long> {

	
}
    


   3.2 Spring Data JPA能根据<jpa:repositories>自动扫描继承于Repostory及其子接口的接口,无需配置。

     3.3 如果有复杂的操作或ORM关系可添加单元测试,否则可忽略。

    4.Service

     4.1 按业务划分新建或使用已有Service(与DAO不应是一一对应关系),根据需求添加方法定义。 注意事务定义。

package org.springside.examples.quickstart.service.userdemo;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.examples.quickstart.entity.UserDemo;
import org.springside.examples.quickstart.repository.UserDemoDao;

@Component
@Transactional(readOnly = true)
public class UserDemoService {

	private UserDemoDao userDemoDao;

	@Autowired
	public void setUserDemoDao(UserDemoDao userDemoDao) {
		this.userDemoDao = userDemoDao;
	}

	public UserDemo findUserDemobyName(Long id) {
		return userDemoDao.findOne(id);
	}

	@Transactional(readOnly = false)
	public void deleteUserDemo(Long id) {
		userDemoDao.delete(id);
	}

	@Transactional(readOnly = false)
	public void saveUserDemo(UserDemo userDemo) {
		userDemoDao.save(userDemo);
	}

	public List<UserDemo> findAllUserDemo() {
		return (List<UserDemo>) userDemoDao.findAll(((new Sort(Direction.ASC,
				"id"))));

	}

}

  

    4.2 Spring能根据applicationContext.xml中的<context:component-scan...>自动扫描@Service或@Component, 无需配置。

     4.3 对有业务逻辑的方法要编写单元测试,并用Mock框架模拟dao层。

    5.Web Controller

     5.1 我这里写了两个controller 一个负责增、查、删

 

package org.springside.examples.quickstart.web.userdemo;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.examples.quickstart.entity.UserDemo;
import org.springside.examples.quickstart.service.userdemo.UserDemoService;

/**
 * List page:
 * @author Robin
 *
 */
@Controller
@RequestMapping(value = "/userDemo")
public class UserDemoController {

	@Autowired
	private UserDemoService userDemoService;

	@RequestMapping(value ={"list",""})
	public String list(Model model) {

		List<UserDemo> userDemos = userDemoService.findAllUserDemo();
		model.addAttribute("userDemos", userDemos);
		return "userDemo/userDemoList";
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String createForm(Model model) {
		model.addAttribute("userDemo", new UserDemo());
		//设置跳转的action 但是未成功。采用写死的方法
		//model.addAttribute("action", "create");
		return "userDemo/userDemoForm";
	}

	@RequestMapping(value = "save", method = RequestMethod.POST)
	public String create(UserDemo newUserDemo,
			RedirectAttributes redirectAttributes) {

		userDemoService.saveUserDemo(newUserDemo);
		redirectAttributes.addFlashAttribute("message", "创建"+newUserDemo.getLoginName()+"成功");
		return "redirect:/userDemo/";
	}

	@RequestMapping(value = "delete/{id}")
	public String delete(@PathVariable("id") Long id,
			RedirectAttributes redirectAttributes) {
		userDemoService.deleteUserDemo(id);
		redirectAttributes.addFlashAttribute("message", "删除任务成功");
		return "redirect:/userDemo/";
	}
	
	
}


5.2 另外一个负责修改

 

package org.springside.examples.quickstart.web.userdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.examples.quickstart.entity.UserDemo;
import org.springside.examples.quickstart.service.userdemo.UserDemoService;

@Controller
@RequestMapping(value = "/userDemo")
public class UserDemoUpdateController {

	private UserDemoService userDemoService;

	@Autowired
	public void setUserDemoService(UserDemoService userDemoService) {
		this.userDemoService = userDemoService;
	}

	@RequestMapping(value = "update/{id}")
	public String updateForm(Model model) {

		return "userDemo/userDemoForm";
	}

	@RequestMapping(value = "save/{id}")
	public String update(@ModelAttribute("userDemo") UserDemo userDemo,
			RedirectAttributes redirectAttributes) {
		userDemoService.saveUserDemo(userDemo);
		redirectAttributes.addFlashAttribute("message",
				"更新" + userDemo.getLoginName() + "成功");
		return "redirect:/userDemo/";
	}

	/**
	 * 使用@ModelAttribute, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性,因此本方法在该方法中执行.
	 */
	@ModelAttribute("userDemo")
	public UserDemo getUserDemoId(@PathVariable("id") Long id) {
		return userDemoService.findUserDemobyName(id);
	}
}
    5.3 Spring能根据spring-mvc.xml中的<context:component-scan> 自动扫描@Controller, 无需配置。


    5.4 如果有participation update的情况,即Form表单中的变量没有包含Entity中的所有属性,一个方法是另外编写一个DTO,一个方法是参照quickstart中基于@ModelAttribute的二次绑定的做法。

     6.JSP

     总共两个jsp页面,在WEB-INF的views文件夹下新建userDemo,在其中创建两个jsp文件:userDemoForm.jsp,userDemoList.jsp

      6.1 userDemoForm.jsp

 

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

<html>
<head>
	<title>UserDemo管理</title>
	
	<script>
		$(document).ready(function() {
			//聚焦第一个输入框
			$("#userDemo_loginName").focus();
			//为inputForm注册validate函数
			$("#inputForm").validate();
		});
	</script>
</head>

<body>
	<form id="inputForm" action="${ctx}/userDemo/save/${userDemo.id}"  method="POST" class="form-horizontal">
		<input type="hidden" name="id" value="${userDemo.id}"/>
		<fieldset>
			<legend><small>管理UserDemo任务</small></legend>
			<div class="control-group">
				<label for="userDemo_loginName" class="control-label">LoginName:</label>
				<div class="controls">
					<input type="text" id="userDemo_loginName" name="loginName"  value="${userDemo.loginName}" class="input-large required" minlength="3"/>
				</div>
			</div>	
			<div class="control-group">
				<label for="userDemo_password" class="control-label">Password:</label>
				<div class="controls">
					<textarea id="userDemo_password" name="password" class="input-large">${userDemo.password}</textarea>
				</div>
			</div>	
			<div class="control-group">
				<label for="userDemo_name" class="control-label">Name:</label>
				<div class="controls">
					<textarea id="userDemo_name" name="name" class="input-large">${userDemo.name}</textarea>
				</div>
			</div>	
			<div class="control-group">
				<label for="userDemo_email" class="control-label">Email:</label>
				<div class="controls">
					<textarea id="userDemo_email" name="email" class="input-large">${userDemo.email}</textarea>
				</div>
			</div>	
			<div class="form-actions">
				<input id="submit_btn" class="btn btn-primary" type="submit" value="提交"/>&nbsp;	
				<input id="cancel_btn" class="btn" type="button" value="返回" onclick="history.back()"/>
			</div>
		</fieldset>
	</form>
</body>
</html>


 

6.2 userDemoList.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

<html>
<head>
	<title>UserDemo管理</title>
</head>

<body>
	<c:if test="${not empty message}">
		<div id="message" class="alert alert-success"><button data-dismiss="alert" class="close">×</button>${message}</div>
	</c:if>
	<!--  
	<div class="row">
		<div class="span4 offset7">
			<form class="form-search" action="#">
			 	<label>查询条件(id):</label> <input type="text" name="search_LIKE_id" class="input-medium" value="${param.search_LIKE_id}"> 
			    <button type="submit" class="btn">Search</button>
		    </form>
	    </div>
	    <tags:sort/>
	</div>
	-->
	<table id="contentTable" class="table table-striped table-bordered table-condensed">
		<thead><tr><th>登录名</th><th>密码</th><th>姓名</th><th>邮箱</th><th>操作</th></tr></thead>
		<tbody>
		<c:forEach items="${userDemos}" var="userDemo">
			<tr>
				<td><a href="${ctx}/userDemo/update/${userDemo.id}">${userDemo.loginName}</a></td>
				<td>${userDemo.password}</td>
				<td>${userDemo.name}</td>
				<td>${userDemo.email}</td>
				<td><a href="${ctx}/userDemo/delete/${userDemo.id}">删除</a></td>
			</tr>
		</c:forEach>
		</tbody>
	</table>

	<div><a class="btn" href="${ctx}/userDemo/create">创建用户</a></div>
</body>
</html>

 

6.3 为方便查看userdemo修改header.jsp ,添加一行代码:<li><a href="${ctx}/userDemo">userDemo</a></li>

7.最好重启下eclipse。运行结果如下:

 springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第5张图片

     springside4配置Mysql并在Eclipse上创建quickstart的CRUD示例_第6张图片

 


 

四:遇到的问题

    1.修改配置文件后,必须要重启eclipse,否则不能正确读取,不知道是什么原因。

     2.Invocation of init method failed错误。

       解决办法:@RequestMapping(value = "save")  多个requestmapping 的value值相同,设置为不同的值。

      3.开发过程中可能会遇到运行refresh-db.bat出错的问题,可能是由于没有mysql-connector   jar包引起的,此外还要注意mysql-connector 的版本问题,在配置文件中要注意。

说明:我也是刚开始研究接触springside,有困难大家一起讨论~~~



 

 


 

你可能感兴趣的:(eclipse,mysql,maven3,springside4)