1、我的环境
- jdk8
- maven3.6.1
- mysql8.0
- tomcat9.0.48
2、创建一个数据库为testdb
在testdb中创建一个students表并插入几条数据
create table students(
stuId int primary key,
stuName varchar(10),
stuMajor varchar(10)
);
insert into students values
(1800500926,'谭熙','信息管理与信息系统'),
(1800500924,'施彦宏','信息管理与信息系统'),
(1800501501,'冯雪儿','工业工程');
3、创建maven工程
项目名为springmvc-all
不使用模板创建,就创建一个普通的mavenx项目即可。
4、导入我们需要的依赖
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!--servlet,jsp,jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--springMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--mybatis-spring整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!--spring的jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.8</version>
</dependency>
<!--c3p0数据源-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
5、设置资源过滤
确保我们的mapper.xml可以导出出来,不然最后运行打包的时候可能会异常
在pom.xml 与dependencies同级插入以下代码(固定格式的)
<!--资源过滤-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<!-- 如果有其他的继续加就行-->
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
6、创建包结构 cn.butcher(可以自己写)
7、添加web框架支持
- 右键我们的项目名
- 添加框架支持
这样我们的web结构也出来了。
8、创建spring配置文件
在resources下创建两个配置文件
- db.properties
这里写上连接数据库的配置 数据库的配置
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF8&userSSL=true&serverTimezone=GMT
jdbc.username=root
jdbc.password=tx123
注意注意,前面要有jdbc. 这是规范,不然会报错的。。。
- spring-dao.xml
如果报错,就把中文注释去掉,下同!
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--关联数据库配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--数据源连接配置-->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--c3p0连接池私有属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动提交-->
<property name="autoCommitOnClose" value="false"/>
<!--连接超时时间-->
<property name="checkoutTimeout" value="10000"/>
<!--失败后重试次数-->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--自动扫描pojo下的实体类,设置别名-->
<property name="typeAliasesPackage" value="cn.butcher.pojo"/>
</bean>
<!--spring自动扫描我们的mapper接口,bean的id就是接口名(第一个字母小写)-->
<bean id="mapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="mapperInterface" value="cn.butcher.mapper.UserMapper"/>
</bean>
</beans>
可以为每个接口配置一份实例交给spring接管,但是这样接口多了,就不好玩了
<!--配置mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--绑定sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--自动扫描mapper下的映射文件,前提是隐射文件的名字要和接口一样-->
<property name="basePackage" value="cn.butcher.mapper"/>
</bean>
除了上面的两种方式我比较推荐的,其他还有两种方式在spring中使用mybatis,都是实现接口的方式,要再建一个接口实现类,感觉多了一步,不喜欢!
参考大佬文章
- application-context.xml
再总的spring配置文件中引入spring-dao.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
</beans>
9、好了,编写我们的dao层(也就是,mapper)
whatever,按官方的规范是这样,但你怎么命名无所谓
- 创建Student实体类
package cn.butcher.pojo;
public class Student {
private int stuId;
private String stuName;
private String stuMajor;
public Student() {
}
public Student(int stuId, String stuName, String stuMajor) {
this.stuId = stuId;
this.stuName = stuName;
this.stuMajor = stuMajor;
}
public int getStuId() {
return stuId;
}
public void setStuId(int stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public String getStuMajor() {
return stuMajor;
}
public void setStuMajor(String stuMajor) {
this.stuMajor = stuMajor;
}
@Override
public String toString() {
return "Student{" +
"stuId=" + stuId +
", stuName='" + stuName + '\'' +
", stuMajor='" + stuMajor + '\'' +
'}';
}
}
- 编写接口
package cn.butcher.mapper;
import cn.butcher.pojo.Student;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface StudentMapper {
/**
* 查询所有学生
* @return 学生列表
*/
List<Student> selectStudents();
/**
* 删除一个学生
* @param id 学号
* @return 状态
*/
int deleteStudentById(@Param("stuId") int id);
/**
* 更新一个学生的信息
* @param student 学生
* @return 状态
*/
int updateStudent(Student student);
/**
* 添加一个学生
* @param student 学生
* @return 状态
*/
int addStudent(Student student);
}
- 编写mapper映射文件
<?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="cn.butcher.mapper.StudentMapper">
<!--我们已经在配置文件中扫描了所有实体类,所以在这我们直接使用别名即可-->
<select id="selectStudents" resultType="student">
select * from students
</select>
<delete id="deleteStudentById">
delete from students where stuId = #{stuId}
</delete>
<!--动态sql多看看官方的帮助文档就好了-->
<update id="updateStudent" parameterType="student">
update students
<set>
<if test="stuName!=null">
stuName=#{stuName},
</if>
<if test="stuMajor!=null">
stuMajor=#{stuMajor},
</if>
</set>
where stuId = #{stuId}
</update>
<insert id="addStudent" parameterType="student">
insert into students(stuId, stuName, stuMajor) values (#{stuId}, #{stuName}, #{stuMajor})
</insert>
</mapper>
- 单元测试
package cn.butcher;
import cn.butcher.mapper.StudentMapper;
import cn.butcher.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
StudentMapper studentMapper = context.getBean("studentMapper", StudentMapper.class);
@Test
public void test01() {
List<Student> students = studentMapper.selectStudents();
for (Student student : students) {
System.out.println(student.toString());
}
}
@Test
public void test02() {
int res = studentMapper.deleteStudentById(1800500926);
System.out.println(res);
}
@Test
public void test03() {
Student student = new Student(1800500926, "谭熙", "信管-信息管理");
int res = studentMapper.updateStudent(student);
System.out.println(res);
}
@Test
public void test04() {
Student student = new Student(1800500926, "谭熙", "信管");
int res = studentMapper.addStudent(student);
System.out.println(res);
}
}
以上测试都是成功的,你可以在你那里跑一下。如果出问题,记得把中文注释去掉!
10、整合service层
- 创建StudentService接口
package cn.butcher.service;
import cn.butcher.pojo.Student;
import java.util.List;
public interface StudentService {
/**
* 查询所有学生
* @return 学生列表
*/
List<Student> selectStudents();
/**
* 删除一个学生
* @param id 学号
* @return 状态
*/
int deleteStudentById(int id);
/**
* 更新一个学生的信息
* @param student 学生
* @return 状态
*/
int updateStudent(Student student);
/**
* 添加一个学生
* @param student 学生
* @return 状态
*/
int addStudent(Student student);
}
- 创建StudentServiceImpl是实现类
package cn.butcher.service;
import cn.butcher.mapper.StudentMapper;
import cn.butcher.pojo.Student;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentServiceImpl implements StudentService {
private StudentMapper studentMapper;
public void setStudentMapper(StudentMapper studentMapper) {
this.studentMapper = studentMapper;
}
/**
* 查询所有学生
*
* @return 学生列表
*/
public List<Student> selectStudents() {
return studentMapper.selectStudents();
}
/**
* 删除一个学生
*
* @param id 学号
* @return 状态
*/
public int deleteStudentById(int id) {
return studentMapper.deleteStudentById(id);
}
/**
* 更新一个学生的信息
*
* @param student 学生
* @return 状态
*/
public int updateStudent(Student student) {
return studentMapper.updateStudent(student);
}
/**
* 添加一个学生
*
* @param student 学生
* @return 状态
*/
public int addStudent(Student student) {
return studentMapper.addStudent(student);
}
}
- 在resources里创建spring-service.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--自动扫描service包-->
<context:component-scan base-package="cn.butcher.service"/>
<!--显式定义StudentServiceImpl-->
<bean id="studentServiceImpl" class="cn.butcher.service.StudentServiceImpl">
<property name="studentMapper" ref="studentMapper"/>
</bean>
<!--配置事务管理器-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
测试没有问题
package cn.butcher;
import cn.butcher.pojo.Student;
import cn.butcher.service.StudentServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest2 {
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
StudentServiceImpl studentServiceImpl = context.getBean("studentServiceImpl", StudentServiceImpl.class);
@Test
public void test01() {
List<Student> students = studentServiceImpl.selectStudents();
for (Student student : students) {
System.out.println(student.toString());
}
}
@Test
public void test02() {
int res = studentServiceImpl.deleteStudentById(1800500926);
System.out.println(res);
}
@Test
public void test03() {
Student student = new Student(1800500926, "谭熙", "信管-信息管理");
int res = studentServiceImpl.updateStudent(student);
System.out.println(res);
}
@Test
public void test04() {
Student student = new Student(1800500926, "谭熙", "信管");
int res = studentServiceImpl.addStudent(student);
System.out.println(res);
}
}
11、开始我们的web
- 配置dispatcherServlet
在web.xml中
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--注意这里是总的配置文件-->
<param-value>classpath:application-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--解决编码问题-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--会话超时时间-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
- 创建是spring-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描controller包-->
<context:component-scan base-package="cn.butcher.controller"/>
<!--开启注解支持-->
<mvc:annotation-driven/>
<!--静态资源默认设置-->
<mvc:default-servlet-handler/>
</beans>
- 编写StudentController
package cn.butcher.controller;
import cn.butcher.pojo.Student;
import cn.butcher.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class StudentController {
@Autowired
@Qualifier("studentServiceImpl")
StudentService studentService;
@GetMapping("/list")
public List<Student> selectStudents(){
return studentService.selectStudents();
}
@GetMapping("/delete/{id}")
public String deleteStudent(@PathVariable int id){
int res = studentService.deleteStudentById(id);
if (res>=1)return id+"删除成功!";
return id+"删除失败了!";
}
@GetMapping("/update")
public String updateStudent(Student student){
int res = studentService.updateStudent(student);
if (res>=1)return student.getStuName()+"更新成功!";
return student.getStuName()+"更新失败了!";
}
@GetMapping("/add")
public String addStudent(Student student){
int res = studentService.addStudent(student);
if (res>=1)return student.getStuName()+"添加成功!";
return student.getStuName()+"添加失败了!";
}
}
- 启动tomcat前
检查lib目录中是否添加了jar包,如果没有,创建一个lib目录
如果没有,创建一个lib目录
应用即可
- 启动tomcat
在地址栏输入:http://localhost:8080/list
- 删除一个学生
在地址栏输入:http://localhost:8080/delete/1800500926
删除成功了,但是中文出现了乱码,排查一下:
它在返回数据的时候就乱码了
是我们的过滤器没起作用,可以暂时这样解决
@GetMapping(value = "/update" ,produces = "application/json;charset=UTF-8")
或者在spring-mvc.xml中修改配置(参考自:响应数据中文乱码)
<mvc:annotation-driven>
<mvc:message-converters>
<!-- 解决@ResponseBody返回中文乱码 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
<value>*/*;charset=UTF-8</value>
</list>
</property>
<!-- 用于避免响应头过大 -->
<property name="writeAcceptCharset" value="false" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
- 更新一个学生
- 添加一个学生
在地址栏输入:
12、总结
呼呼呼,终于结束了!
总结一下:征途漫漫,唯有奋斗!