Skip to content

Tutorial

springside edited this page Aug 27, 2012 · 16 revisions

CRUD页面教程

1. 数据库设计

在src/resouces/sql/h2/schema.sql 中手工编写创建表的sql。

 create table acct_user (
        id bigint generated by default as identity,
        email varchar(255),
        login_name varchar(255) not null unique,
        name varchar(255),
        password varchar(255),
        primary key (id)
    ) ;

Tips:
1.建议不要再显式的建立外键.
2.为h2和生产数据库各自建立sql.
3.为表名添加域前缀以便日后管理.

2. Entity

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

@Entity
@Table(name = "acct_user")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User extends IdEntity {
	private String loginName;
	private String password;
	private String name;
	private String email;
        //... getter and setter
}

2.2 执行JpaMapptingTest校验正确。

2.3 Spring能自动扫描@Entity类,无需配置。

3. DAO

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

public interface UserDao extends PagingAndSortingRepository<User, Long> {
	User findByLoginName(String loginName);
}

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

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

4.Service

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

@Component
@Transactional(readOnly = true)
public class AccountManager {
	private UserDao userDao;
	public User getUser(Long id) {
		return userDao.findOne(id);
	}

	@Transactional(readOnly = false)
	public void saveUser(User entity) {
		userDao.save(entity);
	}
}

4.2 Spring能自动扫描@Service或@Component, 无需配置。

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

Web Controller

4.1 写一个Controller负责List, Create, Delete。

@Controller
@RequestMapping(value = "/account/user")
public class UserController {

	private AccountManager accountManager;

	@RequestMapping(value = { "list", "" })
	public String list(Model model) {
		List<User> users = accountManager.getAllUser();
		model.addAttribute("users", users);
		return "account/userList";
	}

	@RequestMapping(value = "create")
	public String createForm(Model model) {
		model.addAttribute("user", new User());
		return "account/userForm";
        }

	@RequestMapping(value = "save")
	public String save(User user, RedirectAttributes redirectAttributes) {
		accountManager.saveUser(user);
		redirectAttributes.addFlashAttribute("message", "Create user " + user.getLoginName()
                + " success");
		return "redirect:/account/user/";
	}
}

4.2 一个DetailController负责Update页面。

@Controller
@RequestMapping(value = "/account/user/")
public class UserDetailController {

	private AccountManager accountManager;

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

	@RequestMapping(value = "save/{id}")
	public String save(@ModelAttribute("user") User user, RedirectAttributes redirectAttributes) {
		accountManager.saveUser(user);
		redirectAttributes.addFlashAttribute("message", "Modify user "  + user.getLoginName() 
                + " success");
		return "redirect:/account/user/";
	}

	@ModelAttribute("user")
	public User getAccount(@PathVariable("id") Long id) {
		return accountManager.getUser(id);
	}
}

4.3 Spring能自动扫描@Controller, 无需配置。

##5. JSP

5.1 写一个List页面,一个Form页面, 参见mini-web。

5.2 对关键页面流程应该编写Selenium功能测试用例。

Clone this wiki locally