zoukankan      html  css  js  c++  java
  • 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="/")
        public ModelAndView mainPage() {
            return new ModelAndView("home");
        }
     
        @RequestMapping(value="/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="${pageContext.request.contextPath}/team/add.html">Add new team</a>
    <a href="${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="/team/add")
        public ModelAndView addTeamPage() {
            ModelAndView modelAndView = new ModelAndView("add-team-form");
            modelAndView.addObject("team", new Team());
            return modelAndView;
        }
     
        @RequestMapping(value="/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="/team/list")
        public ModelAndView listOfTeams() {
            ModelAndView modelAndView = new ModelAndView("list-of-teams");
     
            List
     
              teams = teamService.getTeams();
            modelAndView.addObject("teams", teams);
     
            return modelAndView;
        }
     
        @RequestMapping(value="/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="/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="/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="Add" type="submit"></td>
            <td></td>
        </tr>
    </tbody>
    </table>
    </form:form>
     
    <p><a href="${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="${pageContext.request.contextPath}/team/edit/${team.id}.html">Edit</a>
        <a href="${pageContext.request.contextPath}/team/delete/${team.id}.html">Delete</a>
        </td>
    </tr>
     
    </tbody>
    </table>
     
    <p><a href="${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="Edit" type="submit"></td>
            <td></td>
        </tr>
    </tbody>
    </table>
    </form:form>
     
    <p><a href="${pageContext.request.contextPath}/index.html">Home page</a></p>
    ...

    “List of teams” 页面的效果:

    总结

    几个技术的整合通常不是一件简单的事情,所有如果要想成功就需要有耐心。在这篇文章中没有囊括所有的资源,你可以访问GitHub去查看哪些你感兴趣的类。

  • 相关阅读:
    Vim快捷键键位图大全
    Docker快速入门
    针对base64编码和URIEncode的一点研究
    JavaEE初学笔记之Servlet与Tomcat
    【编码】彻底弄懂ASCII、Unicode、UTF-8之间的关系
    React的世界观及与Vue之比较
    彻底搞懂CSS文本、空白换行问题
    Vue实现懒加载的基本思路
    CSS中的px与物理像素、逻辑像素、1px边框问题
    Vue插值文本换行问题
  • 原文地址:https://www.cnblogs.com/Lightning-Kid/p/3933771.html
Copyright © 2011-2022 走看看