这部分的学习内容主要在于维护我的个人笔记,将springboot步骤以博客的形式作为笔记。谢谢大家的阅读。
1、项目的简单介绍首先是任务目标:
- 业务目标:使用 Spring Boot + Mybatis + tk Mybatis + Thymeleaf 完成个 人记账管理
- 技能目标: Spring Boot、tk Mybatis、Thymeleaf、MySQL
其中的任务过程如下:
1.账单分类查询 2.账单分页查询 3.账单添加 4.账单修改 5.账单删除
部分截图实现如下:
大致是三个页面,其中第三个页面是修改,跟添加账单的显示类似。
以上的项目加上数据库目前已经打包成gitee打包:小艾扶/记账管理系统 - 码云
其中注意,我的MySQL使用的是8以上的版本,使用5的伙伴们就需要注意编码格式。
2、数据库表示首先是账单的内容,它里面还有包含账单分类。
这里稍微介绍一下数据库即可。
3、项目的环境构建&编写首先就是创建一个Maven项目,项目导入如下:
tk.mybatis mapper-spring-boot-starter mysql mysql-connector-java com.github.pagehelper pagehelper 5.1.11 junit junit test org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.springframework.boot spring-boot-starter-thymeleaf
添加依赖,其中包括分页、tkmybatis和springboot加上thymeleaf的前端编辑。
启动类加载:
@SpringBootApplication
@MapperScan("com.xaf.dao")
public class BillManagerApplication {
public static void main(String[] args) {
SpringApplication.run(BillManagerApplication.class, args);
}
}
将src/main/resource拷贝到resource下继续使用,稍微在配置文件稍作修改:
server:
port: 8001
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/bill-manager
thymeleaf:
cache: false #关闭thymeleaf缓存
#整合mybatis
mybatis:
type-aliases-package: com.xaf.entity #别名搜索
mapper-locations: classpath:/mybatis/*.xml
里面根据自己的需要进行修改。
实体类:
@Table(name = "bill_")
public class Bill implements Serializable {
@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
private String typeName;
@Transient
private Date date1;
@Transient
private Date date2;
@Table(name = "bill_type_")
public class BillType implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_")
public Long id;
@Column(name = "name_")
public String name;
}
简单介绍一下:
@Table(name = "bill_"):将数据库表指向里面内容 @GeneratedValue(strategy = GenerationType.IDENTITY):设置表排列 @Column(name = "id_"):对应数据库表对应名称 @Transient:设置其中的属性不随着其他属性一样被直接显示或者调用
Dao层:
public interface BillMapper extends Mapper{ public List select(Bill b); }
public interface TypeMapper extends Mapper{ }
Service:
@Service
public class BillService {
@Autowired
private BillMapper billMapper;
public List list(Bill b) {
return billMapper.select(b);
}
public int add(Bill b) {
return billMapper.insert(b);
}
public Bill get(Long id) {
return billMapper.selectByPrimaryKey(id);
}
public int update(Bill b) {
return billMapper.updateByPrimaryKey(b);
}
public int delete(Long id) {
return billMapper.deleteByPrimaryKey(id);
}
public PageInfo listPage(Bill b, int pageNum, int pageSize) {
return PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
billMapper.select(b);
});
}
}
@Service
public class TypeService {
@Resource
private TypeMapper typeMapper;
public List list() {
return typeMapper.selectAll();
}
}
跟前面学习spring一样。
Controller:
@Controller
@RequestMapping("/bill")
public class BillController {
@Resource
private TypeService typeService;
@Resource
private BillService billService;
@RequestMapping("/list")
public String list(Bill b, Model model) {
List types = typeService.list();
model.addAttribute("types", types);
List list = billService.list(b);
model.addAttribute("list", list);
model.addAttribute("bill", b);
return "/bill/list";
}
@GetMapping("/toAdd")
public String toAdd(Model model) {
List types = typeService.list();
model.addAttribute("types", types);
return "/bill/add";
}
@GetMapping("/add")
public String add(Bill b) {
billService.add(b);
return "redirect:/bill/list";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable("id") Long id) {
billService.delete(id);
return "redirect:/bill/list";
}
@GetMapping("/toUpdate/{id}")
public String toUpdate(@PathVariable("id") Long id, Model model) {
List types = typeService.list();
model.addAttribute("types", types);
Bill bill = billService.get(id);
model.addAttribute("bill", bill);
return "/bill/update";
}
@GetMapping("/update")
public String update(Bill b) {
billService.update(b);
return "redirect:/bill/list";
}
@GetMapping("/list-page")
public String listPage(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize, Bill b, Model model) {
List types = typeService.list();
model.addAttribute("types", types);
PageInfo pageInfo = billService.listPage(b, pageNum, pageSize);
model.addAttribute("page", pageInfo);
model.addAttribute("bill", b);
return "/bill/list-page";
}
}
最后就是resource下的mybatis-xml映射文件
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`, t.name_ as typeName FROM bill_ as b left join bill_type_ as t on b.type_id_ = t.id_
其中如下代码要看一下是否对应自己的项目路径下。
剩下的就是静态资源了,里面的静态资源需要通过后端Controller中的model.addAttribute("bill", bill);进行传值。目前我的项目时已经完成了这部分的内容。
4、附加 时间转换@Component public class DateConverterConfig implements Converter{ private static final List formarts = new ArrayList<>(4); static{ formarts.add("yyyy-MM"); formarts.add("yyyy-MM-dd"); formarts.add("yyyy-MM-dd hh:mm"); formarts.add("yyyy-MM-dd hh:mm:ss"); } @Override public Date convert(String source) { String value = source.trim(); if ("".equals(value)) { return null; } if(source.matches("^\d{4}-\d{1,2}$")){ return parseDate(source, formarts.get(0)); }else if(source.matches("^\d{4}-\d{1,2}-\d{1,2}$")){ return parseDate(source, formarts.get(1)); }else if(source.matches("^\d{4}-\d{1,2}-\d{1,2} {1}\d{1,2}:\d{1,2}$")){ return parseDate(source, formarts.get(2)); }else if(source.matches("^\d{4}-\d{1,2}-\d{1,2} {1}\d{1,2}:\d{1,2}:\d{1,2}$")){ return parseDate(source, formarts.get(3)); }else { throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); } } public Date parseDate(String dateStr, String format) { Date date=null; try { DateFormat dateFormat = new SimpleDateFormat(format); date = dateFormat.parse(dateStr); } catch (Exception e) { } return date; } }
就简单介绍一下,后面的Date parseDate方法是将String类型字符转换成Date类型字符;前面添加一个list放置格式内容,后面就对格式内容进行比较并返回。
5、前端回显(粗略)这里稍微介绍一部分内容即可。
这里面显示内容时,我们使用的是thymeleaf,用th:each在行标签设置循环,将内容以行的形式呈现出来才能完成最上面展示的样式。然后设置b以list类型,将list中的各个属性输出到内容上。
Listlist = billService.list(b); model.addAttribute("list", list);
这样子就完成了基本的显示内容。
再举例一个地方:
这里面就是进行下拉框的显示,也是在选择标签下设置循环,将value值传进去再显示文本。(前面的展示不需要value在于只需要能够显示即可,而这里设置value是因为还要将相关的值作为记录并回响数据。)
总结完成了以上的步骤,就基本上离完成项目项目的基本构建不远了。这部分笔记稍微作为个人笔记使用,也希望能够被大佬批评指正。谢谢阅读。



