SpringMVC注解开发+JdbcTemplate 的demo

SpringMVC+JdbcTemplate注解开发demo

1、环境描述

本文目标:使用Spring框架的JdbcTemplate和阿里的druid数据库连接池整合SpringMVC。全称使用注解开发模式(零xml配置)。

  • maven 3.6版本
  • spring 5.x版本
  • servlet 3.1版本
  • mysql 8.x版本

1.1 项目结构

在这里插入图片描述

1.2 pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.feng</groupId>
  <artifactId>springmvc-publisher</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springmvc-publisher Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <spring.version>5.2.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.5</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>

    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.16</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.9</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>springmvc-publisher</finalName>
  </build>
</project>

1.3 jdbc.properties

jdbc.url=jdbc:mysql://localhost:3306/springmvc?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=root

1.4 log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=INFO, CONSOLE
#log4j.rootCategory=INFO, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=INFO
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

2、java代码

首先是配置类:用于替换之前在框架搭建时用的xml文件。

2.1 JDBC的配置类

package org.feng;

import com.alibaba.druid.pool.DruidDataSource;
import com.mysql.cj.jdbc.Driver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Created by Feng on 2019/12/19 17:35
 * CurrentProject's name is springmvc-publisher
 * JDBC配置类
 * @author Feng
 */
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(JdbcConfig.class);

    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


    /**
     * 装配{@link DataSource}到spring容器
     * @return DataSource对象
     */
    @Bean(name = "dataSource")
    public DataSource createDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        try {
            dataSource.setDriver(new Driver());
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
        } catch (SQLException e) {
            LOGGER.error("getting datasource error...", e);
        }
        return dataSource;
    }


    /**
     * 装配{@link JdbcTemplate}到spring容器
     * @param dataSource 数据源
     * @return JdbcTemplate对象
     */
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        LOGGER.info("creating JdbcTemplate...");
        return new JdbcTemplate(dataSource);
    }
}

2.2 Spring的配置类

package org.feng;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Controller;

/**
 * Created by Feng on 2019/12/19 17:34
 * CurrentProject's name is springmvc-publisher
 * Spring的配置类:不扫描{@link Controller}
 * @author Feng
 */
@Configuration
@ComponentScan(value = "org.feng", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
        Controller.class))
@Import(JdbcConfig.class)
public class SpringConfig {
}

2.3 SpringMVC的配置类

package org.feng;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * Created by Feng on 2019/12/19 19:28
 * CurrentProject's name is springmvc-publisher
 * Springmvc的配置类:用于替代springmvc.xml文件
 * @author Feng
 */
@Configuration
@ComponentScan(value = "org.feng.controller")
public class SpringMvcConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringConfig.class);
    /**
     * 创建视图解析器:设置前缀+后缀,存入IOC容器
     * @return 视图解析器
     */
    @Bean
    public ViewResolver createViewResolver(){
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        LOGGER.info("set viewResolver over");
        return viewResolver;
    }
}

2.4 配置类整合

package org.feng;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

/**
 * Created by Feng on 2019/12/19 19:40
 * CurrentProject's name is springmvc-publisher
 * 初始化spring和springmvc ioc容器的配置类:在spring框架前执行
 * @author Feng
 */
public class Config extends AbstractDispatcherServletInitializer {

    private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);
    /**
     * 重写方法:注册字符集过滤器
     * @param servletContext
     * @throws ServletException
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);

        // 创建字符集过滤器
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();

        // 设置使用的字符集
        characterEncodingFilter.setEncoding("UTF-8");

        // 添加到容器(不是IOC容器)
        servletContext.addFilter("characterEncodingFilter", characterEncodingFilter);
        LOGGER.info("set characterEncodingFilter to utf-8");
    }

    /**
     * 用于创建SpringMVC的ioc容器
     * @return 注册了springmvc配置的上下文类
     */
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext acw = new AnnotationConfigWebApplicationContext();

        // 注册SpringMVC的配置类
        acw.register(SpringMvcConfig.class);
        LOGGER.info("register org.feng.SpringMvcConfig.class");
        return acw;
    }


    /**
     * 用于指定DispatcherServlet的请求映射
     * @return 字符串数组;相当于在web.xml配置时的mapping路径
     */
    @Override
    protected String[] getServletMappings() {
        LOGGER.info("mapping to servlet[*.do][*.action]");
        return new String[]{"*.do", "*.action"};
    }

    /**
     * 用于创建Spring的ioc容器
     * @return 注册了Spring配置的上下文类
     */
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext acw = new AnnotationConfigWebApplicationContext();

        // 注册Spring的配置
        acw.register(SpringConfig.class);
        LOGGER.info("register org.feng.SpringConfig.class");
        return acw;
    }
}

2.5 实体类

package org.feng.entity;

import java.io.Serializable;
import java.util.Date;
/**
 * Created by Feng on 2019/12/19 17:50
 * CurrentProject's name is springmvc-publisher
 * @author Feng
 */
public class Publisher implements Serializable {
    private static final long serialVersionUID = -2069618414619440779L;

    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    private Integer pub_id;
    private String pub_name;
    private String pub_address;
    private String pub_phone;
    private String pub_contact;
    private Date pub_date;

    public Integer getPub_id() {
        return pub_id;
    }

    public void setPub_id(Integer pub_id) {
        this.pub_id = pub_id;
    }

    public String getPub_name() {
        return pub_name;
    }

    public void setPub_name(String pub_name) {
        this.pub_name = pub_name;
    }

    public String getPub_address() {
        return pub_address;
    }

    public void setPub_address(String pub_address) {
        this.pub_address = pub_address;
    }

    public String getPub_phone() {
        return pub_phone;
    }

    public void setPub_phone(String pub_phone) {
        this.pub_phone = pub_phone;
    }

    public String getPub_contact() {
        return pub_contact;
    }

    public void setPub_contact(String pub_contact) {
        this.pub_contact = pub_contact;
    }

    public Date getPub_date() {
        return pub_date;
    }

    public void setPub_date(Date pub_date) {
        this.pub_date = pub_date;
    }

    @Override
    public String toString() {
        return "Publisher{" +
                "pub_id=" + pub_id +
                ", pub_name='" + pub_name + '\'' +
                ", pub_address='" + pub_address + '\'' +
                ", pub_phone='" + pub_phone + '\'' +
                ", pub_contact='" + pub_contact + '\'' +
                ", pub_date=" + pub_date +
                '}';
    }
}

2.6 数据访问层接口和类

package org.feng.dao;

import org.feng.entity.Publisher;

import java.util.List;

/**
 * Created by Feng on 2019/12/19 17:55
 * CurrentProject's name is springmvc-publisher
 * @author Feng
 */
public interface PublisherDao {
    /**
     * 查询所有的publisher
     * @return publisher集合
     */
    List<Publisher> listPublisher();


    /**
     * 修改 publisher
     * @param publisher 实体
     * @return 修改结果;影响行数
     */
    int updatePublisher(Publisher publisher);


    /**
     * 增加 publisher
     * @param publisher 实体
     * @return 结果;影响行数
     */
    int insertPublisher(Publisher publisher);


    /**
     * 删除 publisher
     * @param publisher 实体
     * @return 结果;影响行数
     */
    int deletePublisher(Publisher publisher);
}
package org.feng.dao.impl;

import org.feng.dao.PublisherDao;
import org.feng.entity.Publisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by Feng on 2019/12/19 17:57
 * CurrentProject's name is springmvc-publisher
 * 数据访问实现:对表publisher进行操作
 * @author Feng
 */
@Component("publisherDao")
public class PublisherDaoImpl implements PublisherDao {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public PublisherDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public List<Publisher> listPublisher() {
        String sql = "select pub_id, pub_name, pub_address, pub_phone, pub_contact, pub_date from publisher";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Publisher.class));
    }

    @Override
    public int updatePublisher(Publisher publisher) {
        String sql = "update publisher set pub_name = ?, pub_address = ?, pub_phone = ?, pub_contact = ?, pub_date = " +
                "? where pub_id = ?";

        return jdbcTemplate.update(sql, publisher.getPub_name(), publisher.getPub_address(),
                publisher.getPub_phone(), publisher.getPub_contact(), publisher.getPub_date(), publisher.getPub_id());
    }

    @Override
    public int insertPublisher(Publisher publisher) {
        String sql = "insert into publisher(pub_name, pub_address, pub_phone, pub_contact, pub_date) values (?,?,?,?," +
                "?)";
        return jdbcTemplate.update(sql, publisher.getPub_name(), publisher.getPub_address(), publisher.getPub_phone()
                , publisher.getPub_contact(), publisher.getPub_date());
    }

    @Override
    public int deletePublisher(Publisher publisher) {
        String sql = "delete from publisher where pub_id = ?";
        return jdbcTemplate.update(sql, publisher.getPub_id());
    }
}

2.7 业务层接口和类

package org.feng.service;

import org.feng.entity.Publisher;

import java.util.List;

/**
 * Created by Feng on 2019/12/19 18:06
 * CurrentProject's name is springmvc-publisher
 * @author Feng
 */
public interface PublisherService {
    /**
     * 查询所有的publisher
     * @return publisher集合
     */
    List<Publisher> listPublisher();

    /**
     * 修改 publisher
     * @param publisher 实体
     * @return 修改结果;影响行数
     */
    int updatePublisher(Publisher publisher);


    /**
     * 增加 publisher
     * @param publisher 实体
     * @return 结果;影响行数
     */
    int insertPublisher(Publisher publisher);


    /**
     * 删除 publisher
     * @param publisher 实体
     * @return 结果;影响行数
     */
    int deletePublisher(Publisher publisher);
}
package org.feng.service.impl;

import org.feng.dao.PublisherDao;
import org.feng.entity.Publisher;
import org.feng.service.PublisherService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by Feng on 2019/12/19 18:08
 * CurrentProject's name is springmvc-publisher
 * @author Feng
 */
@Service
public class PublisherServiceImpl implements PublisherService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PublisherServiceImpl.class);
    private final PublisherDao publisherDao;

    @Autowired
    public PublisherServiceImpl(PublisherDao publisherDao) {
        LOGGER.info(PublisherServiceImpl.class + " get " + PublisherDao.class);
        this.publisherDao = publisherDao;
    }

    @Override
    public List<Publisher> listPublisher() {
        return publisherDao.listPublisher();
    }

    @Override
    public int updatePublisher(Publisher publisher) {
        return publisherDao.updatePublisher(publisher);
    }

    @Override
    public int insertPublisher(Publisher publisher) {
        return publisherDao.insertPublisher(publisher);
    }

    @Override
    public int deletePublisher(Publisher publisher) {
        return publisherDao.deletePublisher(publisher);
    }
}

2.8 控制器类

package org.feng.controller;

import org.feng.service.PublisherService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by Feng on 2019/12/19 20:21
 * CurrentProject's name is springmvc-publisher
 * @author Feng
 */
@Controller
@RequestMapping("/publisher")
public class PublisherController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PublisherController.class);
    private final PublisherService publisherService;

    @Autowired
    public PublisherController(PublisherService publisherService) {
        LOGGER.info(PublisherController.class + " get " + PublisherService.class);
        this.publisherService = publisherService;
    }

    @RequestMapping("/list.do")
    public ModelAndView listPublishers(){
        ModelAndView modelAndView = new ModelAndView();

        modelAndView.addObject("publisherList", publisherService.listPublisher());
        modelAndView.setViewName("/success");
        return modelAndView;
    }
}

3、页面

success.jsp

<%@page isELIgnored="false" pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<h2>出版社列表</h2>
<div>
    <table>
        <tr>
            <th>编号</th>
            <th>出版社名</th>
            <th>地址</th>
            <th>电话</th>
            <th>联系人</th>
            <th>成立日期</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${publisherList}" var="publisher" varStatus="status">
            <tr>
                <td>${status.count}</td>
                <td>${publisher.pub_name}</td>
                <td>${publisher.pub_address}</td>
                <td>${publisher.pub_phone}</td>
                <td>${publisher.pub_contact}</td>
                <td>${publisher.pub_date}</td>
                <td><a href="#">删除</a>&nbsp;&nbsp;<a href="#">修改</a></td>
            </tr>
        </c:forEach>
    </table>
</div>
</body>
</html>

4、Tomcat配置和结果

测试类(注意放在test/java中)

package org.feng.service;

import org.feng.SpringConfig;
import org.feng.entity.Publisher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Date;

/**
 * Created by Feng on 2019/12/19 18:14
 * CurrentProject's name is springmvc-publisher
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class ServiceTest {
    @Autowired
    private PublisherService publisherService;

    @Test
    public void testQueryAll(){
        publisherService.listPublisher().forEach(System.out::println);
    }


    @Test
    public void testInsert(){
        Publisher publisher = new Publisher();
        publisher.setPub_name("xiao风出版社");
        publisher.setPub_address("西安");
        publisher.setPub_contact("小冯");
        publisher.setPub_date(new Date());
        publisher.setPub_phone("18142395136");

        System.out.println(publisherService.insertPublisher(publisher));
    }
}

在这里插入图片描述

在这里插入图片描述

发布了108 篇原创文章 · 获赞 117 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/FBB360JAVA/article/details/103627542