使用IDEA搭建一个 Spring + Spring MVC + Mybatis 的Web项目 ( 零配置文件 )
前言:
除了mybatis 不是零配置,有些还是有xml的配置文件在里面的。
注解是Spring的一个构建的一个重要手段,减少写配置文件,下面解释一下一些要用到的注解:
@Configuration 作用于类上面,声明当前类是一个配置类(相当于一个Spring的xml文件)
@ComponentScan(“xxx”) 作用于类上面,自动扫描xxx包名下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean
@Bean 作用与类和方法上,相当于Spring配置文件bean节点
@EnableWebMvc 作用于类,开启一些默认配置,如一些ViewResolver或者MessageConverter
@RequestMapping 作用于类、方法,配置URL和方法之间的映射
@RequestBody 作用于参数前,允许request的参数在request体中,而不是在直接链接在地址后面
@ResponseBody 作用于返回值、方法上,支持将返回值放在response体中,而不是返回一个页面。
@RequestParam 作用于参数前,将form的对应name值映射到当前参数中。
从一开始。
先搭建一个 Spring + Spring MVC 的web 项目
创建项目。
然后 点击 Finish 完成 创建项目。
这里开始配置我们的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>com.oukele.ssm</groupId> <artifactId>MyDemo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>MyDemo 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> </properties> <dependencies> <!--spring 的依赖管理 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.3.RELEASE</version> </dependency> <!--spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.3.RELEASE</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> </project>
导入静态资源(jsp 页面 ........)。
在WEB-INF中,直接粘贴boostrap的标准资源,并新建一个views文件夹,将index.jsp拉进去,将自己写的Login.jsp(想要示例的登陆页面的话在本文的最下面有个github地址可以去下载)复制进去,效果如下(顺便删了web.xml):
目录结构如下:
在 main 目录 下 新建 java 文件夹 (注意 java 文件夹 的颜色哦 )
在 java 文件夹 新建几个包 比如 --> com --> oukele --> config (先这样吧。)
开始配置 SpringWebConfig类 (类似 spring-web.xml):
新建一个SpringWebConfig 类,实现 WebMvcConfigurer接口,并配置一些必要的方法。
package com.oukele.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @Configuration//声明当前类是一个配置类 类似于 ( spring-web.xml ) @EnableWebMvc//若无此注解 WebMvcConfigurer 接口 将无效 @ComponentScan("com.oukele")//自动扫描spring注解 比如@Service、@Component、@Repository和@Controller的类,并注册为Bean public class SpringWebConfig implements WebMvcConfigurer { //添加一个ViewResolver 解析 view @Bean//相当于Spring配置文件bean节点 public InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); viewResolver.setViewClass(JstlView.class); viewResolver.setExposeContextBeansAsAttributes(true); return viewResolver; } //注册静态资源,比如(css,js,.....) @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/"); registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/"); registry.addResourceHandler("/fonts/**").addResourceLocations("/WEB-INF/fonts/"); } //根目录直接跳转到登录页面 Login.jsp @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("Login"); } }
与xml配置文件 对比:
注意 @ComponentScan("com.oukele")这样写,扫描oukele 目录所有使用spring注解的类,这里我有点粗心大意了。^_^ 有点小尴尬了。
配置WebInit类 ( 相当于 web.xml 文件 ):
新建一个WebInit类 实现WebApplicationIntializer接口实现方法,方法的内容如:
package com.oukele.config; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; public class WebInit implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(SpringWebConfig.class);//注册springWebConfig类 ctx.setServletContext(servletContext); ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcher",new DispatcherServlet(ctx));//将 配置类 添加到DispatcherServlet上下文中 dynamic.addMapping("/"); dynamic.setLoadOnStartup(1); } }
与 web.xml 文件 对比:
添加Controller:
新建一个LoginController类
在 oukele 这层包 下 再新建 一个 web 包出来 将 LoginController类放到里面去。
新建一个LoginController 类
package com.oukele.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class LoginController { @RequestMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("pwd") String pwd) { String forword = null; if (username.equals("oukele") && pwd.equals("oukele")) { forword = "index";//登录成功跳转到index.jsp } else { System.out.println("no such user"); forword = "Login";//登录失败跳转到Login.jsp继续登录操作 } return forword; } }
到这里 我们试试能否启动这个web项目吧。
添加到Tomcat 运行:
这里 默认显示的就是登陆页面。
运行结果:
Spring + Spring MVC 的另一种写法 (零配置文件):https://www.cnblogs.com/oukele/p/10127915.html
开始整合Mybatis.
重新配置一下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>com.oukele.ssm</groupId> <artifactId>MyDemo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>MyDemo 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> </properties> <dependencies> <!--spring 的依赖管理 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.3.RELEASE</version> <scope>test</scope> </dependency> <!--spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.3.RELEASE</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <!--MariaDB 数据库驱动 --> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>2.3.0</version> </dependency> <!--c3p0 数据库连接池--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
在oukele 这层包下 新建 entity 、dao 包
在entity包新建一个Student类
package com.oukele.entity; public class Student { //学号 private String number; //姓名 private String name; //性别 private String sex; //年龄 private int age; //地址 private String address; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Student{" + "number='" + number + '\'' + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; } }
在dao包新建一个StudentMapper接口
package com.oukele.dao; import com.oukele.entity.Student; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface StudentMapper { //使用xml配置文件 Student getUserById(String number); //不使用配置文件使用注解 @Select("Select * from student where number = #{number}") Student getUserByIdForAnnotation(String number); @Select("Select * from student where name = #{student.name} and age = #{student.age}") Student checkUser(@Param("student") Student student); }
在main 目录下 新建一个resources 的文件夹。(注意看 resources文件夹的图标)
在resources中新建一个 mybatis-config.xml 文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 --> <setting name="useGeneratedKeys" value="true" /> <!-- 使用列别名替换列名 默认:true --> <setting name="useColumnLabel" value="true" /> <!-- 开启驼峰命名转换:Table {create_time} -> Entity {createTime} --> <setting name="mapUnderscoreToCamelCase" value="true" /> </settings> </configuration>
在 resources中新建一个mapper文件夹,此文件夹中新建一个StudentMapper.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="com.oukele.dao.StudentMapper"> <select id="getUserById" resultType="com.oukele.entity.Student"> select * from student where number =#{number} </select> </mapper>
开始配置SpringDaoConfig类。
在config包新建SpringDaoConfig类
package com.oukele.config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import javax.sql.DataSource; import java.beans.PropertyVetoException; @Configuration//声明当前类是一个配置类 public class SpringDaoConfig { @Bean public DataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl("jdbc:mariadb://localhost:3306/test"); dataSource.setDriverClass("org.mariadb.jdbc.Driver"); dataSource.setUser("oukele"); dataSource.setPassword("oukele"); return dataSource; } /*@Bean(name = "sqlSessionFactory") 如果不写就默认方法的名字*/ @Bean("sqlSessionFactory") public SqlSessionFactoryBean sqlSessionFactory() throws PropertyVetoException { SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); ClassPathResource resource = new ClassPathResource("mapper/StudentMapper.xml"); sqlSessionFactory.setTypeAliasesPackage("com.oukele.entity"); sqlSessionFactory.setMapperLocations(new Resource[]{resource}); sqlSessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml")); sqlSessionFactory.setDataSource(this.dataSource()); return sqlSessionFactory; } @Bean public MapperScannerConfigurer getMapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); configurer.setBasePackage("com.oukele.dao"); return configurer; } }
与xml文件对比:
到这里基本完成了ssm配置,我们来测试一下是否能使用。
在main包新建一个test文件夹(注意test文件夹的颜色),在test文件夹 中: --> com --> oukele --> StudentTest测试类
StudentTest类:
package com.oukele; import com.oukele.config.SpringDaoConfig; import com.oukele.dao.StudentMapper; import com.oukele.entity.Student; 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.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = {SpringDaoConfig.class}) public class StudentTest { @Autowired private StudentMapper studentMapper; @Test public void getIdInfo(){ Student student = studentMapper.getUserById("A101"); System.out.println(student); } @Test public void getName(){ Student student = studentMapper.getUserByIdForAnnotation("B211"); System.out.println(student); } @Test public void getNameAndSex(){ Student student = new Student(); student.setName("小兰"); student.setAge(18); Student result = studentMapper.checkUser(student); System.out.println(result); } }
测试结果:
1 Student{number='D331', name='小兰', sex='女', age=18, address='海南某个地方'} 2 Student{number='B211', name='小明', sex='男', age=19, address='广西某个地方'} 3 Student{number='A101', name='小华', sex='男', age=18, address='广东某个地方'}
我们到Logincontroller去使用。
修改一下 index.jsp页面:
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>主页面</title> 5 </head> 6 <body> 7 <h2>Hello World!</h2> 8 欢迎登录,${student.name} !!!! 9 </body> 10 </html>
运行结果:
测试数据:
create table student( number varchar(10) not null, name varchar(10) not null, sex varchar(4) not null, age int , address varchar(100) )default charset = utf8; insert into student values ("A101","小华","男",18,"广东某个地方"), ("B211","小明","男",19,"广西某个地方"), ("C111","小花","女",17,"珠海某个地方"), ("D331","小兰","女",18,"海南某个地方")
本次演示代码示例下载地址:https://github.com/oukele/Spring-SpringMVC-Mybatis