基于SSM实现记账系统demo 1 前言 2 环境搭建 3

1 前言

  本demo是基于SSM框架完成的一个小项目,用于初学者进行基本的框架熟练度练习。源码获取方式在文末,以下是程序运行的几个页面:
在这里插入图片描述
在这里插入图片描述

2 环境搭建

2.1 基本架构

在这里插入图片描述
1. 添加依赖包,可以通过properties统一框架版本

1
2
3
xml复制代码<properties>
<springversion>5.0.8.RELEASE</springversion>
</properties>
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
xml复制代码<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<!-- 加入ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- MySQL依赖 start -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 加入MyBatis 依赖 start -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 引入Spring(包含SpringMVC) 依赖 start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springversion}</version>
</dependency>
<!-- 引用插件依赖:MyBatis整合Spring,如果mybatis版本在3.4及以上版本
mybatis-spring的版本要在1.3以上 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 德鲁伊数据连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<!--处理json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<!--javaee-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!--文件上传下载-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>

如果遇到声明式事务报错,需要添加下面的依赖包

1
2
3
4
5
xml复制代码<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>

2. 添加spring配置文件
实现8个关键步骤

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
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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--1 配置数据源-->
<bean id="db" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/kaikeba0917"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>

<!--2 创建sqlSessionFactory-->
<bean id="fac" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="db"/>
<!--指定mybatis的配置文件路径-->
<property name="configLocation" value="classpath:mybatis.xml"/>
<!--指定mybatis的mapper文件路径-->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>

<!--3 创建sqlSessionTemplate(这个类没有无参构造)-->
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="fac"/>
</bean>

<!--4 配置事务-->
<bean id="mytx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="db"/>
</bean>
<tx:annotation-driven transaction-manager="mytx"/>

<!--5 启用springMVC注解-->
<mvc:annotation-driven/>

<!--6 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!--7 扫描注解包-->
<context:component-scan base-package="com.wangjiawei"/>

<!--8 配置静态资源访问-->
<mvc:default-servlet-handler/>

</beans>

3. 配置web.xml文件,同时加载spring配置文件

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
xml复制代码<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">


<display-name>Archetype Created Web Application</display-name>

<!--1 配置前端控制器-->
<servlet>
<servlet-name>aa</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>aa</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!--2 处理post乱码-->
<filter>
<filter-name>bb</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>bb</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

4. 创建数据表,添加项目包结构,包括实体类等
  给dao,service,web(controller)包下使用注解创建对象,给service,web中的属性注入对象
dao:

1
2
3
java复制代码public interface BooksDao {
public List<Books> getAll();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码@Repository
public class BookDaoImpl implements BooksDao {

/** 该对象来源于配置文件
*
*/
@Resource
private SqlSessionTemplate sqlSessionTemplate;

@Override
public List<Books> getAll() {
return sqlSessionTemplate.selectList("com.wangjiawei.dao.BooksDao.getAll");
}
}

service:

1
2
3
java复制代码public interface BooksService {
public List<Books> getAll();
}
1
2
3
4
5
6
7
8
9
10
java复制代码@Service
public class BooksServiceImpl implements BooksService {
@Resource
private BooksDao dao;

@Override
public List<Books> getAll() {
return dao.getAll();
}
}

web(controller):

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码@Controller
public class BooksController {
@Resource
private BooksService booksService;

@RequestMapping("/getallbooks")
public String getAll(ModelMap map){
List<Books> books = booksService.getAll();
map.addAttribute("booklist", books);
return "show";
}
}

5. 配置文件代码mybatis.xml 及相应的 BooksMapper.xml
mybatis.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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>

<!--给类起别名-->
<typeAliases>
<!-- <typeAlias type="com.wangjiawei.bean.Student" alias="stu"></typeAlias>-->
<package name="com.wangjiawei.bean"/>
</typeAliases>

<!--分页插件-->
<plugins>
<!-- PageHelper4.1.6 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>

</configuration>

BooksMapper.xml:

1
2
3
4
5
6
7
8
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.wangjiawei.dao.BooksDao">
<select id="getAll" resultType="books">
select * from books
</select>
</mapper>

6. 配置controller文件
使用的注解:
@Controller
@RequestMapping
@AutoWired
@Qualifier(“empBiz”)
(同上面的步骤4)

7. 添加service,dao层
使用的注解:
@Service
@AutoWired
(1) dao层省略了实现类
(2) dao 层只定义接口,由小树叶创建dao层对象以及扫描mapper文件
注:当添加了spring-jdbc的jar包后,会自动提交事务

8. 前端测试网页
index.jsp:

1
2
3
4
5
6
html复制代码<html>
<body>
<h2>Hello World!</h2>
<a href="/getallbooks">getallbooks</a>
</body>
</html>

show.jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
html复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>show.jsp</h1>
<c:forEach items="${booklist}" var="book">
${book.bookId}——${book.bookName}
</c:forEach>
</body>
</html>

关于其中的配置文件:
  当项目启动时加载web.xml文件,web.xml文件加载spring.xml文件,spring的配置文件又去加载了mybatis的配置文件与mapper文件。

2.2 省略dao实现类

先将上面的dao实现类删掉

在这里插入图片描述
使用MapperScannerConfigurer替代SqlSessionTemplate

1
2
3
4
5
xml复制代码<!--省略实现类-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.dao"></property>
<property name="sqlSessionFactoryBeanName" value="fac"></property>
</bean>

注意:此时也可以测试使用属性文件的方式来加载数据源(支持属性文件链接数据源)
在这里插入图片描述

2.3 ssm整合mybatis反向生成工具

依赖包:

1
2
3
4
5
xml复制代码<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>

加载插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
xml复制代码<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<!--配置文件的路径-->
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

根据插件中的内容,在resource文件夹下创建generatorConfig.xml文件:

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
xml复制代码<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
<!--数据库驱动jar -->
<classPathEntry
location="F:\develop\maven_repository\mysql\mysql-connector-java\5.1.6\mysql-connector-java-5.1.6.jar" />
<context id="MyBatis" targetRuntime="MyBatis3">
<!--去除注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/kaikeba0917"
userId="root"
password="root">
</jdbcConnection>
<!--生成实体类 指定包名 以及生成的地址 (可以自定义地址,但是路径不存在不会自动创建
使用Maven生成在target目录下,会自动创建) -->
<javaModelGenerator targetPackage="com.wangjiawei.bean"
targetProject="D:\程序员\开课吧新职课\11SSM\5SSM整合\ssm\src\main\java">
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--生成SQLmapper文件 -->
<sqlMapGenerator targetPackage="mapper"
targetProject="D:\程序员\开课吧新职课\11SSM\5SSM整合\ssm\src\main\resources">
</sqlMapGenerator>
<!--生成Dao文件,生成接口 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.wangjiawei.dao"
targetProject="D:\程序员\开课吧新职课\11SSM\5SSM整合\ssm\src\main\java">
</javaClientGenerator>
<table tableName="student" enableCountByExample="false"
enableUpdateByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>

maven类型的web项目加载mybatis-generator插件:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
注意:反向生成后,最好把该指令删除,否则不小心点了之后,又会生成一遍代码,尤其是mapper.xml文件中sql语句又会生成一遍,运行时会报错。

3 记账项目

3.1 需求分析

3.1.1 记账管理

在这里插入图片描述
其中,查询条件中类型为下拉列表,可选值有“不限,支出,收入,转账,借出,借入,还入,还出”。日期输入框需要输入“yyyy-MM-dd”格式的日期字符串,点击“搜索”按钮提交表单,提交时如果输入项不符合输入要求,则显示相应提示信息。列表中根据记账类别在金额前添加相应的“+,-”符号,如果类别为“支出,借出,还出”时在金额前添加“-”。
如果类别为“收入,借入,还入”时在金额前添加“+”。如果根据输入项进行查询后没有找到账单数据,则给出提示信息,如图所示:

在这里插入图片描述
点击“记账”按钮后,进入记账页面。

3.1.2 记账

在这里插入图片描述

  • 类型属性是单选框, 标题输入框最长输入不能超过25 字符, 日期输入框需要输入“yyyy-MM-dd”格式的日期字符串,金额输入框必须为大于0 的数,说明输入框中最大输入长度为250 字符。
  • 点击“重置”按钮则恢复初始值
  • 点击“保存”按钮执行保存功能。提交数据至Controller 前必须使用JS 验证。如果各属性输入值不符合要求则需提示用户。
  • 点击“返回”按钮放弃当前记账操作。并返回首页。

功能补充:在“说明”列后加一列,叫“操作”。用户可以删除或修改数据。
分页显示:上一页 下一页 首页 尾页 当前页码 总页数 总条数

3.1.3 参考数据库

在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
sql复制代码create table bills(
id int primary key auto_increment,
title varchar(50),
billtime date,
typeid int,
price double,
explains varchar(50)
);

create table billtype(
id int primary key auto_increment,
bname varchar(5)
);

3.2 环境搭建

先创建基本的目录

在这里插入图片描述
然后按照上面的步骤配置pom.xml、spring.xml、mybatis.xml、generatorConfig.xml,接着使用mybatis的自动生成功能自动生成

3.3 查询数据

配置web.xml中的请求分发器,以及处理post乱码

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
xml复制代码<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Archetype Created Web Application</display-name>

<!--1 配置前端控制器-->
<servlet>
<servlet-name>aa</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>aa</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!--2 处理post乱码-->
<filter>
<filter-name>bb</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>bb</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


</web-app>

3.3.1 展示下拉列表和基本信息

在这里插入图片描述
dao:
BillsMapper

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
java复制代码package com.wangjiawei.dao;

import com.wangjiawei.bean.Bills;

import java.util.List;

public interface BillsMapper {

/**
* 查询所有账单
* @return
*/
public List<Bills> getBills();

int deleteByPrimaryKey(Integer id);

int insert(Bills record);

int insertSelective(Bills record);

Bills selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(Bills record);

int updateByPrimaryKey(Bills record);
}

在BillsMapper.xml中添加对应实现:

1
2
3
4
5
6
7
8
9
10
11
12
xml复制代码<resultMap id="BaseResultMap" type="com.wangjiawei.bean.Bills">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="billtime" jdbcType="DATE" property="billtime" />
<result column="typeid" jdbcType="INTEGER" property="typeid" />
<result column="price" jdbcType="DOUBLE" property="price" />
<result column="explains" jdbcType="VARCHAR" property="explains" />
</resultMap>

<select id="getBills" resultMap="BaseResultMap">
select * from bills
</select>

BillTypeMapper

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
java复制代码package com.wangjiawei.dao;

import com.wangjiawei.bean.Billtype;

import java.util.List;

public interface BilltypeMapper {

/**
* 查询所有账单类型
* @return
*/
public List<Billtype> getTypes();

int deleteByPrimaryKey(Integer id);

int insert(Billtype record);

int insertSelective(Billtype record);

Billtype selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(Billtype record);

int updateByPrimaryKey(Billtype record);
}

在BillTypeMapper.xml中添加对应实现:

1
2
3
4
5
6
7
8
xml复制代码<resultMap id="BaseResultMap" type="com.wangjiawei.bean.Billtype">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="bname" jdbcType="VARCHAR" property="bname" />
</resultMap>

<select id="getTypes" resultMap="BaseResultMap">
select * from billtype
</select>

service层:
BillsService接口:

1
2
3
4
5
6
7
8
java复制代码public interface BillsService {

/**
* 查询所有账单
* @return
*/
public List<Bills> getBills();
}

BillsServiceImpl实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码@Service
public class BillsServiceImpl implements BillsService {

@Resource
private BillsMapper billsMapper;

/**
* 查询所有账单
*
* @return
*/
@Override
public List<Bills> getBills() {
return billsMapper.getBills();
}
}

BillTypesService接口:

1
2
3
4
5
6
7
8
java复制代码public interface BillTypesService {

/**
* 查询所有账单类型
* @return
*/
public List<Billtype> getTypes();
}

BillTypesService实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码@Service
public class BillTypesServiceImpl implements BillTypesService {
@Resource
private BilltypeMapper billtypeMapper;

/**
* 查询所有账单类型
*
* @return
*/
@Override
public List<Billtype> getTypes() {
return billtypeMapper.getTypes();
}
}

controller层:
BillsController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
java复制代码@Controller
public class BillsController {
@Resource
private BillTypesService typesService;
@Resource
private BillsService billsService;

@RequestMapping("/gettypes")
public String gettypes(ModelMap map){
// 1 查询所有账单类型
List<Billtype> types = typesService.getTypes();
// 2 查询所有的账单
List<Bills> bills = billsService.getBills();
// 保存数据给前台
map.addAttribute("types", types);
map.addAttribute("bills", bills);
return "show";
}
}

相应的前端界面:
index.jsp

1
2
3
4
5
6
7
html复制代码<html>
<body>
<script type="application/javascript">
location.href = "/gettypes";
</script>
</body>
</html>

show.jsp

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
html复制代码<%--
Created by IntelliJ IDEA.
User: 12291
Date: 2020/10/30
Time: 10:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>记账管理</h1>

<p>
<form>
类型:
<select>
<option value="-1">不限</option>
<c:forEach items="${types}" var="tp">
<option value="${tp.id}">${tp.bname}</option>
</c:forEach>
</select>

时间:
从<input type="text" name="begin">到<input type="text" name="end">
<input type="submit" value="搜索">
</form>
<input type="button" value="记账">
</p>
<table border="1" width="500">
<tr>
<td>标题</td>
<td>记账时间</td>
<td>类别</td>
<td>金额</td>
<td>说明</td>
<td>操作</td>
</tr>

<c:forEach items="${bills}" var="bill">
<tr>
<td>${bill.title}</td>
<td><fmt:formatDate value="${bill.billtime}" pattern="yyyy-MM-dd"/></td>
<td>类别</td>
<td>${bill.price}</td>
<td>${bill.explains}</td>
<td>删除 修改</td>
</tr>
</c:forEach>
</table>
</body>
</html>

3.3.2 前端页面【类别】部分的显示

这里需要两表联查:

1
sql复制代码select * from bills b, billtype t where b.typeid = t.id;

在这里插入图片描述
先添加实体类的一对多关系:
Bills类中添加属性

1
java复制代码private Billtype billtype;

BillType中添加属性

1
java复制代码private List<Bills> billsList;

相应的要修改mapper.xml:
BillsMapper.xml(要展示类别只用修改这一个就行了)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xml复制代码<resultMap id="rs1" type="bills">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="billtime" jdbcType="DATE" property="billtime" />
<result column="typeid" jdbcType="INTEGER" property="typeid" />
<result column="price" jdbcType="DOUBLE" property="price" />
<result column="explains" jdbcType="VARCHAR" property="explains" />

<association property="billtype" javaType="com.wangjiawei.bean.Billtype">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="bname" jdbcType="VARCHAR" property="bname" />
</association>
</resultMap>

<select id="getBills" resultMap="rs1">
select * from bills b, billtype t where b.typeid = t.id;
</select>

修改前端show.jsp:
在这里插入图片描述
在这里插入图片描述

3.3.3 前端页面【金额】部分的显示

支出,借出时金额应该有一个负号
只用在前端界面中使用choose when即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
html复制代码<c:forEach items="${bills}" var="bill">
<tr>
<td>${bill.title}</td>
<td><fmt:formatDate value="${bill.billtime}" pattern="yyyy-MM-dd"/></td>
<td>${bill.billtype.bname}</td>
<td>
<c:choose>
<c:when test="${bill.billtype.bname =='支出' || bill.billtype.bname =='借出' || bill.billtype.bname =='还出'}">
-${bill.price}
</c:when>
<c:when test="${bill.billtype.bname =='收入' || bill.billtype.bname =='借入' || bill.billtype.bname =='还入'}">
+${bill.price}
</c:when>
<c:otherwise>
${bill.price}
</c:otherwise>
</c:choose>
</td>
<td>${bill.explains}</td>
<td>删除 修改</td>
</tr>
</c:forEach>

在这里插入图片描述

3.3.4 通过时间和类型模糊查询

实际上,查询所有的语句和模糊查询的语句是同一种语句,只不过模糊查询的语句是在查询所有语句的基础上进行一些拼接,这两种查询可以调用同一个接口。

前端页面:
为搜索这一部分添加一个form

1
2
3
4
5
6
7
8
9
10
11
12
13
14
html复制代码<form action="/getAllBills" method="post">
类型:
<select name="typeid">
<option value="-1">不限</option>
<c:forEach items="${types}" var="tp">
<option value="${tp.id}" ${tid==tp.id?'selected':''}>${tp.bname}</option>
</c:forEach>
</select>

时间:
从<input type="text" name="begin" value="${begintime}">到<input type="text" name="end" value="${endtime}">
<input type="submit" value="搜索">
</form>
<input type="button" value="记账">

controller层:
添加查询所有的方法 getAllBills。
其中添加了回显操作,由于回显操作也要根据type的id进行匹配展示(见前端界面),所以这里也要查询一下所有的type。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码/**
* 查询所有账单
* @return
*/
@RequestMapping("/getAllBills")
public String getBills(Integer typeid, String begin, String end, ModelMap map){

List<Bills> bills = billsService.getBills(typeid, begin, end);
map.addAttribute("bills", bills);
// 数据回显
// 将模糊查询的条件值再返回给前台
map.addAttribute("tid", typeid);
map.addAttribute("begintime", begin);
map.addAttribute("endtime", end);

List<Billtype> types = typesService.getTypes();
map.addAttribute("types", types);

return "show";
}

service层:
dao接口:

1
java复制代码public List<Bills> getBills(int typeid, String begin, String end);

dao实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码/**
* 查询所有账单
*
* @return
*/
@Override
public List<Bills> getBills(int typeid, String begin, String end) {
Map params = new HashMap();
params.put("tid", typeid);
params.put("begin", begin);
params.put("end", end);
return billsMapper.getBills(params);
}

dao:
修改BillsMapper的getBills方法

1
java复制代码public List<Bills> getBills(Map map);

相应的配置文件BillsMapper.xml

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
xml复制代码<resultMap id="rs1" type="bills">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="billtime" jdbcType="DATE" property="billtime" />
<result column="typeid" jdbcType="INTEGER" property="typeid" />
<result column="price" jdbcType="DOUBLE" property="price" />
<result column="explains" jdbcType="VARCHAR" property="explains" />

<association property="billtype" javaType="com.wangjiawei.bean.Billtype">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="bname" jdbcType="VARCHAR" property="bname" />
</association>
</resultMap>

<select id="getBills" resultMap="rs1">
select * from bills b, billtype t where b.typeid = t.id
<if test="tid != -1">
and t.id=#{tid}
</if>
<if test="begin!=null and begin!=''">
and b.billtime>=#{begin}
</if>
<if test="end!=null and end!=''">
and b.billtime <![CDATA[ <= ]]> #{end}
</if>
</select>

3.3.5 分页展示

使用工具类PageHelper进行分页操作,在service层进行这个操作。

service:
分页查询需要接收新的参数,当前页数:index和每页显示条数size
接口

1
java复制代码public PageInfo<Bills> getBills(int typeid, String begin, String end, int index, int size);

实现类:

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
java复制代码@Service
public class BillsServiceImpl implements BillsService {

@Resource
private BillsMapper billsMapper;

/**
* 查询所有账单
*
* @return
*/
@Override
public PageInfo<Bills> getBills(int typeid, String begin, String end, int index, int size) {
Map params = new HashMap();
params.put("tid", typeid);
params.put("begin", begin);
params.put("end", end);

// 1 指定分页数据
PageHelper.startPage(index, size);
// 2 查询数据
List<Bills> bills = billsMapper.getBills(params);
// 3 创建分页工具类
PageInfo<Bills> info = new PageInfo<>(bills);

return info;
}
}

controller层:
controller中修改查询操作的调用,传入一个size和index,并且返回给前端的数据变成PageInfo对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码@RequestMapping("/gettypes")
public String gettypes(ModelMap map){
// 1 查询所有账单类型
List<Billtype> types = typesService.getTypes();

// 2 查询所有的账单
PageInfo<Bills> info = billsService.getBills(-1, null, null, 1, PageUtil.PAGESIZE);

// 保存数据给前台
map.addAttribute("types", types);
map.addAttribute("info", info);

return "show";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码@RequestMapping("/getAllBills")
public String getBills(@RequestParam(defaultValue = "1") int index, @RequestParam(defaultValue = "-1") Integer typeid, String begin, String end, ModelMap map){

PageInfo<Bills> info = billsService.getBills(typeid, begin, end, index, PageUtil.PAGESIZE);
map.addAttribute("info", info);
// 数据回显
// 将模糊查询的条件值再返回给前台
map.addAttribute("tid", typeid);
map.addAttribute("begintime", begin);
map.addAttribute("endtime", end);

List<Billtype> types = typesService.getTypes();
map.addAttribute("types", types);

return "show";
}

其中index被定义为一个常量3

1
2
3
java复制代码public interface PageUtil {
public int PAGESIZE = 3;
}

前端页面:
后台返回给前端的数据变成PageInfo对象;
要控制点击上一页,下一页时显示的范围;
分页查询的时候记得要带上模糊查询的参数;

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
html复制代码<%--
Created by IntelliJ IDEA.
User: 12291
Date: 2020/10/30
Time: 10:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>记账管理</h1>

<p>
<form action="/getAllBills" method="post">
类型:
<select name="typeid">
<option value="-1">不限</option>
<c:forEach items="${types}" var="tp">
<option value="${tp.id}" ${tid==tp.id?'selected':''}>${tp.bname}</option>
</c:forEach>
</select>

时间:
从<input type="text" name="begin" value="${begintime}">到<input type="text" name="end" value="${endtime}">
<input type="submit" value="搜索">
</form>
<input type="button" value="记账">
</p>

<table border="1" width="500">
<tr>
<td>标题</td>
<td>记账时间</td>
<td>类别</td>
<td>金额</td>
<td>说明</td>
<td>操作</td>
</tr>

<c:if test="${info.list.size() > 0}">
<c:forEach items="${info.list}" var="bill">
<tr>
<td>${bill.title}</td>
<td><fmt:formatDate value="${bill.billtime}" pattern="yyyy-MM-dd"/></td>
<td>${bill.billtype.bname}</td>
<td>
<c:choose>
<c:when test="${bill.billtype.bname =='支出' || bill.billtype.bname =='借出' || bill.billtype.bname =='还出'}">
-${bill.price}
</c:when>
<c:when test="${bill.billtype.bname =='收入' || bill.billtype.bname =='借入' || bill.billtype.bname =='还入'}">
+${bill.price}
</c:when>
<c:otherwise>
${bill.price}
</c:otherwise>
</c:choose>
</td>
<td>${bill.explains}</td>
<td>删除 修改</td>
</tr>
</c:forEach>
</c:if>

<c:if test="${info.list.size() == 0}">
<tr>
<td colspan="6"> <h3>没有找到任何数据</h3> </td>
</tr>
</c:if>

<tr>
<td colspan="6">
<a href="/getAllBills?typeid=${tid}&begin=${begintime}&end=${endtime}">首页</a>

<a href="/getAllBills?index=${info.prePage==0?1:info.prePage}&typeid=${tid}&begin=${begintime}&end=${endtime}">上一页</a>

<a href="/getAllBills?index=${info.nextPage==0?info.pages:info.nextPage}&typeid=${tid}&begin=${begintime}&end=${endtime}">下一页</a>

<a href="/getAllBills?index=${info.pages}&typeid=${tid}&begin=${begintime}&end=${endtime}">尾页</a>

总页数:${info.pages}

总条数:${info.total}

</td>
</tr>

</table>
</body>
</html>

3.4 记账功能(新增数据)

前端页面:
注意,页面中的name要和后台Bill类的属性名一致

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
html复制代码<%--
Created by IntelliJ IDEA.
User: 12291
Date: 2020/10/30
Time: 16:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>记账</h1>
<form action="/insertBill" method="post">
<p>类型:
<c:forEach items="${types}" var="ty">
<input type="radio" value="${ty.id}" name="typeid">${ty.bname}
</c:forEach>
</p>
<p>标题:<input type="text" style="width: 500px" name="title"></p>
<p>日期:<input type="text" name="billtime">金额:<input type="text" name="price"></p>
<p>说明:<textarea cols="50" rows="4" name="explains"></textarea></p>
<input type="reset" value="重置">
<input type="submit" value="保存">
</form>
</body>
</html>

dao层的代码是自动生成的,所以已经有了insert方法,直接从service层开始写:
BillsService中添加:

1
java复制代码public int insert(Bills record);

实现类,注意要开启事务:

1
2
3
4
5
java复制代码@Override
@Transactional
public int insert(Bills record) {
return billsMapper.insert(record);
}

controller:

1
2
3
4
5
6
7
8
9
10
java复制代码@RequestMapping("/insertBill")
public String add(Bills bills){
int insert = billsService.insert(bills);
if (insert > 0){
// 回到主页面
return "redirect:/gettypes";
}
// 回到新增页面
return "redirect:/getBillType";
}

测试的时候需要注意,由于采用的是默认springMVC日期输入格式,所以需要的是2020/2/2这种以斜杠分割的方式。

3.5 更新账单

更新账单其实分了两个操作,一个是查询账单,一个是修改账单

3.5.1 查询账单

show.jsp中为修改操作添加a标签

1
html复制代码<a href="/findById?bid=${bill.id}">修改</a>

controller定义对应方法:

1
2
3
4
5
6
7
8
java复制代码@RequestMapping("/findById")
public String findById(int bid, ModelMap map){
Bills bills = billsService.selectByPrimaryKey(bid);
List<Billtype> types = typesService.getTypes();
map.addAttribute("bills", bills);
map.addAttribute("types", types);
return "update";
}

service层:
接口:

1
java复制代码Bills selectByPrimaryKey(Integer id);

实现类:

1
2
3
4
java复制代码@Override
public Bills selectByPrimaryKey(Integer id) {
return billsMapper.selectByPrimaryKey(id);
}

dao是自动生成的:

1
2
3
4
5
6
7
8
9
sql复制代码<sql id="Base_Column_List">
id, title, billtime, typeid, price, explains
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from bills
where id = #{id,jdbcType=INTEGER}
</select>

前端界面:
controller会返回一个update.jsp页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
html复制代码<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>更新</h1>
<form action="/updateBill" method="post">
<input type="hidden" name="id" value="${bills.id}">
<p>类型:
<c:forEach items="${types}" var="ty">
<input type="radio" value="${ty.id}" ${ty.id==bills.typeid?"checked":""} name="typeid">${ty.bname}
</c:forEach>
</p>
<p>标题:<input type="text" style="width: 500px" name="title" value="${bills.title}"></p>
<p>日期:<input type="text" name="billtime" value="<fmt:formatDate value="${bills.billtime}" pattern="yyyy/MM/dd"/>">金额:<input type="text" name="price" value="${bills.price}"></p>
<p>说明:<textarea cols="50" rows="4" name="explains">${bills.explains}</textarea></p>
<input type="reset" value="重置">
<input type="submit" value="保存">
</form>
</body>
</html>

3.5.2 修改操作

controller:

1
2
3
4
5
6
7
8
java复制代码@RequestMapping("/updateBill")
public String updateBill(Bills bills){
int i = billsService.updateByPrimaryKey(bills);
if (i > 0){
return "redirect:/gettypes";
}
return "redirect:/findById?bid=" + bills.getId();
}

修改成功返回show页面,修改失败返回update页面。

service层:

1
2
3
4
java复制代码@Override
public int updateByPrimaryKey(Bills record) {
return billsMapper.updateByPrimaryKey(record);
}

dao也是自动生成的:

1
2
3
4
5
6
7
8
9
sql复制代码<update id="updateByPrimaryKey" parameterType="com.wangjiawei.bean.Bills">
update bills
set title = #{title,jdbcType=VARCHAR},
billtime = #{billtime,jdbcType=DATE},
typeid = #{typeid,jdbcType=INTEGER},
price = #{price,jdbcType=DOUBLE},
explains = #{explains,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>

3.5.3 删除操作

show.jsp中为删除添加一个按钮

1
html复制代码<a href="/deleteById?bid=${bill.id}">删除</a>

controller层:
添加删除方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码@RequestMapping("/deleteById")
public void delete(int bid, HttpServletResponse response){
int i = billsService.deleteByPrimaryKey(bid);
response.setContentType("text/html;charset=utf-8");
try {
PrintWriter writer = response.getWriter();
if (i > 0){
writer.print("<script>alert('删除成功');location.href='/gettypes'</script>");
return;
}
writer.print("<script>alert('删除失败');location.href='/gettypes'</script>");
} catch (IOException e) {
e.printStackTrace();
}
}

service层:
接口

1
java复制代码public int deleteByPrimaryKey(Integer id);

实现类

1
2
3
4
5
java复制代码@Override
@Transactional
public int deleteByPrimaryKey(Integer id) {
return billsMapper.deleteByPrimaryKey(id);
}

关于源码:
  大家可以通过我的下载主业进行下载,或者公众号里由有我个人的联系方式
在这里插入图片描述

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%