首页 > 代码库 > Spring MVC + Hibernate + Maven: Crud操作示例
Spring MVC + Hibernate + Maven: Crud操作示例
Alexey是一个在使用Java,TestNG 和Selenium的自动化WEB应用程序中有丰富经验的测试开发者。他如此的喜欢QA以至于在下班后他为初级QA工程师提供培训课程。
在这篇文章中我想介绍一个Spring MVC + Hibernate + Maven例子。这组技术主要涉及一些基础知识,我想在每一个必要的地方详细解释它。本篇话题范围以外的更多资源,我会提供链接方便你阅读。在文章的最后,我将发布一个GitHub的链接。
目标
示例web应用程序是基于Spring MVC, Hibernate, Maven的,界面是基于HTML的。这个应用程序将提供所有的CRUD操作:增删改查。和往常一样,我将使用Mysql作为我的数据库。这个应用程序将 把足球俱乐部相关的实体来作为示例,所以这个教程将会涉及运动领域。
准备
我需要在数据库中创建一个表,下面就是创建它的代码:
1 2 3 4 5 6 | CREATE TABLE `teams` ( `id` int (6) NOT NULL AUTO_INCREMENT, ` name ` varchar (40) NOT NULL , `rating` int (6) NOT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; |
这个表将在应用程序中用下面的类来表示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | @Entity @Table (name= "teams" ) public class Team { @Id @GeneratedValue private Integer id; private String name; private Integer rating; public Integer getId() { return id; } public void setId(Integer id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public Integer getRating() { return rating; } public void setRating(Integer rating) { this .rating = rating; } } |
然后我需要在IDE(我使用Eclipse)里面创建一个Maven项目。我将略过创建的详细过程,你可以查看它在我的关于Maven项目的创建的文章里,这是pom.xml文件的链接。首先最重要的一点就是WebAppConfig.java 文件,所以我开始吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | @Configuration @ComponentScan ( "com.sprhib" ) @EnableWebMvc @EnableTransactionManagement @PropertySource ( "classpath:application.properties" ) public class WebAppConfig { private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver" ; private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password" ; private static final String PROPERTY_NAME_DATABASE_URL = "db.url" ; private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username" ; private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect" ; private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql" ; private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan" ; @Resource private Environment env; @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)); dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)); dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)); dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)); return dataSource; } @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource()); sessionFactoryBean.setPackagesToScan(env.getRequiredProperty( PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN)); sessionFactoryBean.setHibernateProperties(hibProperties()); return sessionFactoryBean; } private Properties hibProperties() { Properties properties = new Properties(); properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)); properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL)); return properties; } @Bean public HibernateTransactionManager transactionManager() { HibernateTransactionManager transactionManager = new HibernateTransactionManager(); transactionManager.setSessionFactory(sessionFactory().getObject()); return transactionManager; } @Bean public UrlBasedViewResolver setupViewResolver() { UrlBasedViewResolver resolver = new UrlBasedViewResolver(); resolver.setPrefix( "/WEB-INF/pages/" ); resolver.setSuffix( ".jsp" ); resolver.setViewClass(JstlView. class ); return resolver; } } |
在这个文件开头,你看见了注解@EnableTransactionManagement,它可以使Spring的注解驱动事务管理器生效工作。注 解@PropertySource(“classpath:application.properties”)定位属性文件所在的资源文件夹。注意着三个 beans:transactionManager, sessionFactory, dataSource,这些beans提供了事务管理。更多信息可以阅读我的关于Hibernate功能的文章。
1 2 3 4 5 6 7 8 9 10 | #DB properties: db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql: //localhost:3306/hibnatedb db.username=hibuser db.password=root #Hibernate Configuration: hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect hibernate.show_sql= true entitymanager.packages.to.scan=com.sprhib.model |
以上是我和项目有关的所有准备,接下来我将向你展示DAO层和Service层。
DAO层和Service层
下面是DAOs和Services接口和实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public interface TeamDAO { public void addTeam(Team team); public void updateTeam(Team team); public Team getTeam( int id); public void deleteTeam( int id); public List getTeams(); } @Repository public class TeamDAOImpl implements TeamDAO { @Autowired private SessionFactory sessionFactory; private Session getCurrentSession() { return sessionFactory.getCurrentSession(); } public void addTeam(Team team) { getCurrentSession().save(team); } public void updateTeam(Team team) { Team teamToUpdate = getTeam(team.getId()); teamToUpdate.setName(team.getName()); teamToUpdate.setRating(team.getRating()); getCurrentSession().update(teamToUpdate); } public Team getTeam( int id) { Team team = (Team) getCurrentSession().get(Team. class , id); return team; } public void deleteTeam( int id) { Team team = getTeam(id); if (team != null ) getCurrentSession().delete(team); } @SuppressWarnings ( "unchecked" ) public List getTeams() { return getCurrentSession().createQuery( "from Team" ).list(); } } |
注解 @Repository 表明被注解的类是一个DAO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public interface TeamService { public void addTeam(Team team); public void updateTeam(Team team); public Team getTeam( int id); public void deleteTeam( int id); public List getTeams(); } @Service @Transactional public class TeamServiceImpl implements TeamService { @Autowired private TeamDAO teamDAO; public void addTeam(Team team) { teamDAO.addTeam(team); } public void updateTeam(Team team) { teamDAO.updateTeam(team); } public Team getTeam( int id) { return teamDAO.getTeam(id); } public void deleteTeam( int id) { teamDAO.deleteTeam(id); } public List getTeams() { return teamDAO.getTeams(); } } |
注解@Service表明备注解的类是一个“Service”。注解@Transactional在一个方法或者是类上声明一个事务。
控制器和JSPs
现在我就要涵盖所有的 CRUD操作,这一章会有点长。我将从最基础的控制器开始,它负责主页:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Controller public class LinkController { @RequestMapping (value=http://www.mamicode.com/ "/" ) public ModelAndView mainPage() { return new ModelAndView( "home" ); } @RequestMapping (value=http://www.mamicode.com/ "/index" ) public ModelAndView indexPage() { return new ModelAndView( "home" ); } } |
它挺简单的,这是JSP文件:
1 2 3 4 5 6 7 8 | ... <h1>Home page</h1> <p> ${message} <a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/team/add.html" >Add new team</a> <a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/team/list.html" >Team list</a> </p> ... |
下面是这里是核心控制器,主要应用程序的控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | @Controller public class TeamController { @Autowired private TeamService teamService; @RequestMapping (value=http://www.mamicode.com/ "/team/add" ) public ModelAndView addTeamPage() { ModelAndView modelAndView = new ModelAndView( "add-team-form" ); modelAndView.addObject( "team" , new Team()); return modelAndView; } @RequestMapping (value=http://www.mamicode.com/ "/team/add/process" ) public ModelAndView addingTeam( @ModelAttribute Team team) { ModelAndView modelAndView = new ModelAndView( "home" ); teamService.addTeam(team); String message = "Team was successfully added." ; modelAndView.addObject( "message" , message); return modelAndView; } @RequestMapping (value=http://www.mamicode.com/ "/team/list" ) public ModelAndView listOfTeams() { ModelAndView modelAndView = new ModelAndView( "list-of-teams" ); List teams = teamService.getTeams(); modelAndView.addObject( "teams" , teams); return modelAndView; } @RequestMapping (value=http://www.mamicode.com/ "/team/edit/{id}" , method=RequestMethod.GET) public ModelAndView editTeamPage( @PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView( "edit-team-form" ); Team team = teamService.getTeam(id); modelAndView.addObject( "team" ,team); return modelAndView; } @RequestMapping (value=http://www.mamicode.com/ "/team/edit/{id}" , method=RequestMethod.POST) public ModelAndView edditingTeam( @ModelAttribute Team team, @PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView( "home" ); teamService.updateTeam(team); String message = "Team was successfully edited." ; modelAndView.addObject( "message" , message); return modelAndView; } @RequestMapping (value=http://www.mamicode.com/ "/team/delete/{id}" , method=RequestMethod.GET) public ModelAndView deleteTeam( @PathVariable Integer id) { ModelAndView modelAndView = new ModelAndView( "home" ); teamService.deleteTeam(id); String message = "Team was successfully deleted." ; modelAndView.addObject( "message" , message); return modelAndView; } } |
基本上所有的方法和请求映射都是很清晰的。请注意editTeamPage() 和edditingTeam() 方法的@RequestMapping,对于不同的method属性包含不同的值。
现在我们来看看JSP页面:
“Add new team” 页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ... <h1>Add team page</h1> <p>Here you can add a new team.</p> <form:form method= "POST" commandname= "team" action= "${pageContext.request.contextPath}/team/add/process.html" > <table> <tbody> <tr> <td>Name:</td> <td><form:input path= "name" ></form:input></td> </tr> <tr> <td>Rating:</td> <td><form:input path= "rating" ></form:input></td> </tr> <tr> <td><input value=http://www.mamicode.com/ "Add" type= "submit" ></td> <td></td> </tr> </tbody> </table> </form:form> <p><a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/index.html" >Home page</a></p> ... |
“List of teams” 页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ... <h1>List of teams</h1> <p>Here you can see the list of the teams, edit them, remove or update.</p> <c:foreach var= "team" items= "${teams}" > </c:foreach><table border= "1px" cellpadding= "0" cellspacing= "0" > <thead> <tr> <th width= "10%" >id</th><th width= "15%" >name</th><th width= "10%" >rating</th><th width= "10%" >actions</th> </tr> </thead> <tbody> <tr> <td>${team.id}</td> <td>${team.name}</td> <td>${team.rating}</td> <td> <a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/team/edit/${team.id}.html" >Edit</a> <a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/team/delete/${team.id}.html" >Delete</a> </td> </tr> </tbody> </table> <p><a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/index.html" >Home page</a></p> ... |
“Edit team” 页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ... <h1>Edit team page</h1> <p>Here you can edit the existing team.</p> <p>${message}</p> <form:form method= "POST" commandname= "team" action= "${pageContext.request.contextPath}/team/edit/${team.id}.html" > <table> <tbody> <tr> <td>Name:</td> <td><form:input path= "name" ></form:input></td> </tr> <tr> <td>Rating:</td> <td><form:input path= "rating" ></form:input></td> </tr> <tr> <td><input value=http://www.mamicode.com/ "Edit" type= "submit" ></td> <td></td> </tr> </tbody> </table> </form:form> <p><a href=http://www.mamicode.com/ "${pageContext.request.contextPath}/index.html" >Home page</a></p> ... |
“List of teams” 页面的效果:
总结
几个技术的整合通常不是一件简单的事情,所有如果要想成功就需要有耐心。在这篇文章中没有囊括所有的资源,你可以访问GitHub去查看哪些你感兴趣的类。
Spring MVC + Hibernate + Maven: Crud操作示例