记账管理项目
项目git地址:https://gitee.com/pdh_gitee/bill-manager.git
此项目简单的应用到的技术栈:springboot,mybatis和tk mybatis(持久化),thymeleaf(前端页面展示)和一些简单的前端基础知识。零基础即可入门,实现对springboot,mybatis和tk mybatis(持久化),thymeleaf的了解,也可在此基础之上,查看相关的文档,更进一步的了解学习这些知识。下面给两个文档:
SpringBoot中文文档:http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/
MyBatis中文文档:https://mybatis.org/mybatis-3/zh/index.html
文章目录
0.项目介绍
基于springboot,mybatis和tk mybatis(持久化),thymeleaf(前端页面展示),实现简单的记账管理功能,数据表有两张(bill和bill_type),bill表包括编号,标题,记账时间,账单类型,金额,解释;bill_type表应包括账单类型编号,账单类型名称。两表的详细信息如下:
0.1 bill_type表
bill_type表的详细信息
字段名 | 中文 | 类型 | 长度 | 约束 | 默认值 | 备注 |
---|---|---|---|---|---|---|
id | 类型编号 | bigint | 20 | 主键、自增、非空 | - | |
name | 类型名称 | varchar | 100 | null |
bill_type表索引
索引名 | 字段 | 索引类型 | 索引方法 | 注释 |
---|---|---|---|---|
id(默认字段) | id | PRIMARY | BTREE | 创建主键时自动生成,无需手动创建 |
建表语句
CREATE TABLE `bill_type` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '类型编号',
`name` varchar(100) DEFAULT NULL COMMENT '类型名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
0.2 bill_type表
bill表的详细信息
字段名 | 中文 | 类型 | 长度 | 约束 | 默认值 | 备注 |
---|---|---|---|---|---|---|
id | 账单编号 | bigint | 20 | 主键、自增、非空 | - | |
title | 账单标题 | varchar | 100 | null | ||
bill_time | 记账时间 | date | - | null | ||
type_id | 账单类型 | bigint | 20 | null | ||
price | 金额 | double | 10 | null | 长度为10,小数2位 | |
explain | 说明 | varchar | 100 | null |
bill_type表索引
foreign key:外键约束,其中bill表中的type_id是bill_type中的id主键。
索引名 | 字段 | 索引类型 | 索引方法 | 注释 |
---|---|---|---|---|
id(默认字段) | id | PRIMARY | BTREE | 创建主键时自动生成,无需手动创建 |
fk_type_bill | type_id | KEY | BTREE | 普通索引 |
fk_type_bill | type_id、id | CONSTRAINT | BTREE | 外键约束,type_id对应bill_type中的id |
建表语句
CREATE TABLE `bill` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '账单编号',
`title` varchar(100) DEFAULT NULL COMMENT '账单标题',
`bill_time` date DEFAULT NULL COMMENT '记账时间',
`type_id` bigint(20) DEFAULT NULL COMMENT '账单类型',
`price` double(10,2) DEFAULT NULL COMMENT '金额',
`explain` varchar(100) DEFAULT NULL COMMENT '说明',
PRIMARY KEY (`id`),
KEY `fk_type_bill` (`type_id`),
CONSTRAINT `fk_type_bill` FOREIGN KEY (`type_id`) REFERENCES `bill_type` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
1.项目搭建
我的环境:Win10、IDEA、JDK11、MAVEN,有网络。
新建一个SpringBoot项目(启动类存在,若不存在得先搭建),命名为bill-manager,下面是pom.xml配置文件中的依赖:
<dependencies>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis通用mapper,引入tk.mybatis就不需要再引入mybatis依赖,因为tk.mybatis包括mybatis了-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--页面的模板引擎thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
之后在java包下建立entity、dao、service、controller、utils包,存放相关的类,若resouce包下没有自动生成static和templates包,手动创建(详细的查看项目源码)。
2.连接数据库
数据库yml配置,application.yml文件,放在resources包下
# mysql连接池 我的数据库没设密码
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password:
url: jdbc:mysql://localhost:3306/bill-manager
# 关掉thymeleaf缓存
thymeleaf:
cache: false
# 整合mybatis
mybatis:
type-aliases-package: com.pdh.entity #别名搜索配置
mapper-locations: classpath:/mybatis/*.xml # 放置配置文件
之后就是执行sql脚本,bill-manager.sql文件在登陆数据库之后执行即可(会自动建库、建表、插入数据)。
3.创建实体类
实体类与数据库对应,在entity包下,还需生成getter/setter方法:
BillType类
package com.pdh.entity;
import javax.persistence.*;
import java.util.Date;
/**
* @Author: 彭_德华
* @Date: 2021-08-30 10:17
* @Description:
*/
@Table(name = "bill")
public class Bill {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "title")
private String title;
@Column(name = "bill_time")
private Date billTime;
@Column(name = "type_id")
private Long typeId;
@Column(name = "price")
private Double price;
@Column(name = "explain")
private String explain;
/**
* @Transient 瞬时属性,与字段没有映射
* 类型名称:用于查询
*/
@Transient
private String typeName;
/**
* 开始时间:用于查询
*/
@Transient
private Date dateBegin;
/**
* 结束时间:用于查询
*/
@Transient
private Date dateEnd;
}
Bill类
package com.pdh.entity;
import javax.persistence.*;
/**
* @Author: 彭_德华
* @Date: 2021-08-30 9:59
* @Description:
*/
@Table(name = "bill_type")
public class BillType {
/**
* @Id 表示为主键字段
* @GeneratedValue(strategy = GenerationType.IDENTITY) 自增主键策略
* @Column(name = "id_") 与数据库中的字段匹配
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
}
4.编写dao层
这里采用动态sql语句实现。dao层继承Maper类,减少个人代码开发。
4.1 BillMapper和TypeMapper接口
package com.pdh.dao;
import com.pdh.entity.Bill;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
* @Author: 彭_德华
* @Date: 2021-08-30 10:36
* @Description:
*/
public interface BillMapper extends Mapper<Bill> {
public List<Bill> select(Bill bill);
}
package com.pdh.dao;
import com.pdh.entity.BillType;
import tk.mybatis.mapper.common.Mapper;
/**
* @Author: 彭_德华
* @Date: 2021-08-30 10:34
* @Description: 目前还没有加入方法,有需求可以加入
*/
public interface TypeMapper extends Mapper<BillType> {
}
4.2 BillMapper.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.pdh.dao.BillMapper">
<!--原生sql语句-->
<sql id="selectSql">
SELECT
b.id as id,
b.title as title,
b.bill_time as billTime,
b.type_id as typeId,
b.price as price,
b.explain as `explain`,/*explain是mysql关键字,使用的话必须的使用``括住*/
t.name as typeName
FROM
bill as b
left join
bill_type as t
on
b.type_id = t.id
</sql>
<!--插入where条件,实现动态sql-->
<select id="select" resultType="com.pdh.entity.Bill">
<include refid="selectSql"/>
<where>
/*判断 为true就执行,false就跳过*/
<if test="typeId !=null">
b.type_id = #{typeId}
</if>
<if test="title !=null">
and b.title like '%${title}%'
</if>
<if test="dateBegin !=null">
and b.bill_time >= #{dateBegin}
</if>
<if test="dateEnd !=null">
and b.bill_time <= #{dateEnd}
</if>
</where>
</select>
</mapper>
编写service层
5.编写service层
此层作为dao层和controller层的中间层,作用就是减少dao和controller层的耦合。有两个service类:
5.1 BillService类
package com.pdh.service;
import com.github.pagehelper.<