1. 程式人生 > >spring、springmvc和mybatis整合(java config方式)

spring、springmvc和mybatis整合(java config方式)

ada vat req style face sat roo art 實體

  之前項目中使用ssm框架大多是基於xml的方式,spring3.0以後就提供java config的模式來構建項目,並且也推薦使用這種方式,自從接觸過springboot後,深深感受到這種純java配置的便利,但是springboot默認為我們引入好多jar和配置,使得項目變得很重,因此決定自己動手搭建一個無xml的ssm項目。

  開發環境

  我的開發環境如下:

  web服務器:tomcat8

  開發工具:STS

  JDK版本:1.8

  項目構建工具:maven

  搭建過程

  1、首先引入相關依賴

  pom文件如下:

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>io.powerx</groupId> <artifactId>springmvcconfig</artifactId> <packaging
>war</packaging> <version>0.0.1-SNAPSHOT</version> <properties> </properties> <dependencies> <!-- spring相關 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</
artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- springmvc相關 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.9.RELEASE</version> </dependency> <!-- servlet配置,不配置也不影響,但是jsp會報錯 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 加載jackson包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.7.3</version> </dependency> <!-- druid數據源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.16</version> </dependency> <!-- spring和mybatis整合 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!-- MySQL數據庫連接驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency> <!-- MyBatis框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- 添加logback日誌 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>

 2、編寫配置文件

  MyWebAppInitializer繼承AbstractAnnotationConfigDispatcherServletInitializer,並重寫其中的方法(另外一種方式是MyWebAppInitializer直接實現WebApplicationInitializer接口,不過會復雜一點),它是我們程序的入口,web容器啟動後會調其中相關的方法從而啟動整個應用。主要實現3個方法:getRootConfigClasses,負責加載spring容器,本例中我們只加載了RootConfig類,其它一些spring相關配置類也可以在這裏加載;getServletConfigClasses,加載springmvc容器,本例中我們加載了MvcConfig;getServletMappings,設置映射的路徑。配置代碼如下:

  MyWebAppInitializer.java

package powerx.io.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{MvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

  RootConfig.java

package powerx.io.config;

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.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableTransactionManagement //開啟事務支持
@Import(DruidDataSourceConfig.class)//導入數據源的配置
@ComponentScan(basePackages = {"powerx.io.service","powerx.io.dao","powerx.io.config"},
    excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig {
}

  MvcConfig.java

package powerx.io.config;

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.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan("powerx.io.controller")
public class MvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        super.addViewControllers(registry);
    }

    //配置jsp視圖
    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    //配置靜態資源處理
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();//將靜態資源的請求轉發到servlet容器中默認的servlet上
    }
}

  DruidDataSourceConfig.java

package powerx.io.config;

import java.io.IOException;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration
@PropertySource("classpath:jdbc.properties")
@MapperScan(basePackages="powerx.io.dao")
public class DruidDataSourceConfig{
    
    
    @Value("${spring.datasource.url}")  
    private String dbUrl;  
      
    @Value("${spring.datasource.username}")  
    private String username;  
      
    @Value("${spring.datasource.password}")  
    private String password;  
      
    @Value("${spring.datasource.driverClassName}")  
    private String driverClassName;  
      
    @Value("${spring.datasource.initialSize}")  
    private int initialSize;  
      
    @Value("${spring.datasource.minIdle}")  
    private int minIdle;  
      
    @Value("${spring.datasource.maxActive}")  
    private int maxActive;  
      
    @Value("${spring.datasource.maxWait}")  
    private int maxWait;  
      
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")  
    private int timeBetweenEvictionRunsMillis;  
      
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")  
    private int minEvictableIdleTimeMillis;  
      
    @Value("${spring.datasource.validationQuery}")  
    private String validationQuery;  
      
    @Value("${spring.datasource.testWhileIdle}")  
    private boolean testWhileIdle;  
      
    @Value("${spring.datasource.testOnBorrow}")  
    private boolean testOnBorrow;  
      
    @Value("${spring.datasource.testOnReturn}")  
    private boolean testOnReturn;  
      
    @Value("${spring.datasource.poolPreparedStatements}")  
    private boolean poolPreparedStatements;  
      
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")  
    private int maxPoolPreparedStatementPerConnectionSize;  
      
    @Value("${spring.datasource.filters}")  
    private String filters;  
      
    @Value("{spring.datasource.connectionProperties}")  
    private String connectionProperties;  
      
    @Bean     //聲明其為Bean實例  
    public DataSource dataSource(){
        DruidDataSource datasource = new DruidDataSource();  
          
        datasource.setUrl(this.dbUrl);  
        datasource.setUsername(username);  
        datasource.setPassword(password);  
        datasource.setDriverClassName(driverClassName);  
        datasource.setInitialSize(initialSize);  
        datasource.setMinIdle(minIdle);  
        datasource.setMaxActive(maxActive);  
        datasource.setMaxWait(maxWait);  
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
        datasource.setValidationQuery(validationQuery);  
        datasource.setTestWhileIdle(testWhileIdle);  
        datasource.setTestOnBorrow(testOnBorrow);  
        datasource.setTestOnReturn(testOnReturn);  
        datasource.setPoolPreparedStatements(poolPreparedStatements);  
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
        try {  
            datasource.setFilters(filters);  
        } catch (SQLException e) {  
        }  
        datasource.setConnectionProperties(connectionProperties);  
        return datasource;  
    }
    
    //mybatis的配置
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException{
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();  
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//mybatis-plus插件類
        sqlSessionFactoryBean.setDataSource(dataSource());//數據源
        sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath:mappers/*.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("powerx.io.model");//別名,讓*Mpper.xml實體類映射可以不加上具體包名
        return sqlSessionFactoryBean;
    }
}

  3、配置數據源和mapper映射文件等

  jdbc.properties

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/testssm
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

  UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="powerx.io.dao.UserDao">
    <resultMap type="User" id="UserResult">
        <!-- 數據庫字段和實體類屬性映射關系,名稱一樣的字段可以無需映射。column對應數據庫的實際字段,property對應實體類的屬性 -->
        <result column="USER_NAME" property="userName" />
        <result column="USER_PWD" property="userPwd" />
    </resultMap>
    
    <select id="findByName" parameterType="String" resultMap="UserResult">
        SELECT USER_NAME,USER_PWD FROM USER WHERE USER_NAME=#{userName} 
    </select>
    
    <insert id="insertUser" parameterType="powerx.io.model.User">
    INSERT INTO USER(USER_NAME,USER_PWD) VALUES(#{userName},#{userPwd})
  </insert>
    
</mapper>

  User.java

package powerx.io.model;

public class User {

    private String userName;
    private String userPwd;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPwd() {
        return userPwd;
    }
    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }
    
}

  UserDao.java 

package powerx.io.dao;

import powerx.io.model.User;

public interface UserDao {

    User findByName(String userName);
    
    int insertUser(User user);
}

4、控制層和service層

  UserService.java

package powerx.io.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import powerx.io.dao.UserDao;
import powerx.io.model.User;

@Service
public class UserService {
    
    @Autowired
    private UserDao userDao;
    public Object findByName(String userName) {
        return userDao.findByName(userName);
     }
    
    @Transactional
    public int insertUser(User user) {
        //測試事務是否起作用
        userDao.insertUser(user);
        return userDao.insertUser(user);
     }

}

  UserContoller.java

package powerx.io.controller;

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.bind.annotation.ResponseBody;

import powerx.io.model.User;
import powerx.io.service.UserService;

@Controller
public class UserContoller {

    public static Logger logger = LoggerFactory.getLogger("monitor");
    @Autowired
    private UserService userService;
    
    @ResponseBody
    @RequestMapping("/get")
    public Object getData(String userName) {
        logger.info("獲取用戶信息");
        return userService.findByName(userName);
    }
    
    @ResponseBody
    @RequestMapping("/insert")
    public Object insert(User user) {
        logger.info("添加用戶");
        return userService.insertUser(user);
    }
}

5、項目結構圖

  技術分享圖片

  總結

  寫完代碼,在往tomcat中部署運行的時候遇到了一個問題,tomcat啟動失敗,報了一大堆異常,其中一個是java.util.zip.ZipException: invalid LOC header (bad signature),從網上找了一大堆答案,基本肯定是依賴的jar包不完整造成的,但是我搜索了一下maven倉庫,刪除了所有in_progress的包,依然不行,無奈只能一個一個的排除,浪費了好久時間,最後查出原因是因為mysql的包沒有下載完整,但是依然是一個.jar結尾的文件,只不過大小不對,所以在此記錄一下,以後在遇到tomcat啟動失敗問題,一定要細心排查所依賴的jar。

  至此,整個ssm框架搭建完畢,在其中我加入了事務控制和日誌管理,基本上可以作為一個生產項目的基礎demo。項目代碼基本上都以貼上,我也上傳到了碼雲上面,方便自己使用,地址:https://gitee.com/hehang_com/ssm.git。

  

  

spring、springmvc和mybatis整合(java config方式)