中软实习培训记录八(0728)
今天主要是实现新闻后台系统的分类模块的增删改查以及开始新的模块功能实现。
分类新增
设计思路
以上是新增的静态界面,可以看到,在分类管理部分,我们只要输入新类别的名称即可,若是已有同名类别存在则进行提示。
新增功能实现
1、在TypeRepository中定义findByName方法,实现根据类别名字在数据库中进行数据搜索,SpringBoot已经封装了基本的增删改查的方法
public interface TypeRepository extends JpaRepository<Type,Long> {
Type findByName(String name);
}
2、接下来在Service中添加定义新增方法,有两个【listType不是今天内容,具体查看上一篇文章】:
public interface TypeService {
//分页查看
Page<Type> listType(Pageable pageable);
//新增
Type saveType(Type type);
//新增前查看是否有同名类存在
Type getTypeByName(String name);
}
在TypeServiceImpl中进行实现
@Override
public Type saveType(Type type) {
return typeRepository.save(type);
}
@Override
public Type getTypeByName(String name) {
return typeRepository.findByName(name);
}
3、在Service中完成实现后,到TypeController中,我们在此部分要实现的很多,包括了:
- 点击新增,跳转到新增页面
- 输入内容点击新增
除此之外为了防止用户输入内容为空,我们需要添加一个注解进行输入校验。
//界面跳转
@GetMapping("/types/input")
public String input(Model model){
model.addAttribute("type",new Type());
return "admin/types-input";
}
@PostMapping("/types/add")
public String add(@Valid Type type, BindingResult result, RedirectAttributes attributes){
Type type1=typeService.getTypeByName(type.getName());
if(type1!=null){
result.rejectValue("name","nameError","不能添加重复分类");
}
if(result.hasErrors()){
return "admin/types-input";//出现上述问题就保留在当前界面
}
Type type2=typeService.saveType(type);//保存之后会有返回type
if(type2==null){
attributes.addFlashAttribute("message","新增失败");
}else{
attributes.addFlashAttribute("message","新增成功");
}
return "redirect:/admin/types";
}
实现校验的话,有两处地方要进行注解添加:
1》上面代码add函数中的type前面的加上@Valid;
2》Type实体类中,name属性上方加上@NotBlank:
@NotBlank(message="分类名称不为空")
private String name;
新增功能演示
运行时发现错误提示没有出现,检查发现是界面设计时出现了问题,修改部分如下【读者可根据自己的实际情况和需求进行修改】
<div class="ui error message"></div>
<div class="ui negative message" th:if="${#fields.hasErrors('name')}">
<i class="close icon"></i>
<p th:errors="*{name}">提交信息不符合规则</p>
</div>
重新运行,输入重复的类别,点击提交后,提示“不能添加重复分类”
若一点都不填,直接提交,则会提示“请输入分类名称”
分类删除
删除功能实现
1、TypeService中定义删除方法,因为是根据id进行删除,因此传入id:
//删除
void delete(Long id);
在TypeServiceImpl中进行实现
@Override
public void delete(Long id) {
typeRepository.deleteById(id);
}
2、在TypeController中写删除操作
在界面设计时,我们对于删除按钮进行了如下设计:
<a href="#" th:href="@{/admin/types/{id}/delete(id=${type.id})}" class="ui mini red basic button">删除</a>
因此在Controller中我们就要与界面设计对应:
@RequestMapping("/types/{id}/delete")
public String delete(@PathVariable Long id,RedirectAttributes attributes){
typeService.delete(id);
attributes.addFlashAttribute("message","删除成功");
return "redirect:/admin/types";
}
删除功能演示
对第一个“数学”类别进行删除,点击删除按钮
删除成功,并进行了提示
分类修改
设计思路
点击新增按钮,跳转到修改界面,该界面与新增界面一致。该部分关键在于,点击按钮之后,能够通过类别id,获得类型数据,同时在修改了之后能再根据id进行数据更新。
修改功能实现
1、在TypeService中添加修改的相关方法定义
//更新
Type getType(Long id);
Type updateType(Long id,Type type);
在TypeServiceImpl进行实现:
@Override
public Type getType(Long id) {
return typeRepository.findById(id).orElse(null);
}
@Override
public Type updateType(Long id, Type type) {
Type type1=typeRepository.findById(id).orElse(null);
if(type1==null){
System.out.println("未获得更新对象");
return null;
}
BeanUtils.copyProperties(type,type1);//把传入的type信息保存到实例化的对象type1中
return typeRepository.save(type1);
}
2、在TypeController中写修改操作
在界面设计时,我们对于删除按钮进行了如下设计:
<a href="#" th:href="@{/admin/types/{id}/toUpdate(id=${type.id})}" class="ui mini teal basic button">编辑</a>
因此在Controller中我们就要与界面设计对应:
- 首先进行跳转操作
@RequestMapping("/types/{id}/toUpdate")
public String toUpdate(@PathVariable Long id,Model model){
model.addAttribute("type",typeService.getType(id));
return "admin/types-input";
}
- 然后再更新
@RequestMapping("/types/update/{id}")
public String update(@Valid Type type,BindingResult result,@PathVariable Long id,RedirectAttributes attributes){
Type type1=typeService.getTypeByName(type.getName());
if(type1!=null){
result.rejectValue("name","nameError","不能添加重复分类");
}
if(result.hasErrors()){
return "admin/types-input";
}
Type type2=typeService.updateType(id,type);
if(type2!=null){
attributes.addFlashAttribute("message","更新成功");
}else {
attributes.addFlashAttribute("message","更新失败");
}
return "redirect:/admin/types";
}
修改功能演示
选择一类别点击“编辑”按钮
得到修改界面,界面上会显示原有的类别名称
修改内容,点击提交
可以看到,类别名称已经正确修改了,还出现了更新成功的提示
除此之外,在修改名称时,若是出现重名、未填写等情况,与新增部分一样,会出现错误提示
新模块——标签
标签实体类设计
@Entity
@Table(name = "t_tag")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message="分类名称不为空")
private String name;
public Tag() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Tag{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
该实体类中后续会补充一个Tag与News之间的关系,暂时还未用到所以先不写了。
具体各部分设计
今天我们对于标签管理部分主要实现其新增和更新功能,删除功能的controller部分相对简单,此处就不多写了。
Repository
public interface TagRepository extends JpaRepository<Tag,Long> {
Tag findByName(String name);
}
TagService
有了“分类管理”的实现经验,我们直接在TagService中定义所有我们可能会用到的方法,注意pageable导入的包是:import org.springframework.data.domain.Pageable;不要导错
public interface TagService {
Page<Tag> listTag(Pageable pageable);
Tag saveTag(Tag tag);
void deleteTag(Long id);
Tag getTagByName(String name);
Tag getTag(Long id);
Tag updateTag(Long id,Tag tag);
}
TagServiceImpl
@Service
public class TagServiceImpl implements TagService {
@Autowired
private TagRepository tagRepository;
@Override
public Page<Tag> listTag(Pageable pageable) {
return tagRepository.findAll(pageable);
}
@Override
public Tag saveTag(Tag tag) {
return tagRepository.save(tag);
}
@Override
public void deleteTag(Long id) {
tagRepository.deleteById(id);
}
@Override
public Tag getTagByName(String name) {
return tagRepository.findByName(name);
}
@Override
public Tag getTag(Long id) {
return tagRepository.findById(id).orElse(null);
}
@Override
public Tag updateTag(Long id, Tag tag) {
Tag tag1=tagRepository.findById(id).orElse(null);
if(tag1==null){
System.out.println("未获得更新对象");
return null;
}
BeanUtils.copyProperties(tag,tag1);
return tagRepository.save(tag1);
}
}
TagController
controller部分中,我们只实现了标签展示、新增和更新,当然与Type等一样都加上分页功能。
@Controller
@RequestMapping("/admin")
public class TagController {
@Autowired
private TagService tagService;
@RequestMapping("/tags")
public String tags(@PageableDefault(size = 3,sort = {"id"},direction = Sort.Direction.DESC)
Pageable pageable, Model model){
model.addAttribute("page",tagService.listTag(pageable));
return "admin/tags";
}
@GetMapping("/tags/input")
public String input(Model model){
model.addAttribute("tag",new Tag());
return "admin/tags-input";
}
@PostMapping("/tags/add")
public String add(@Valid Tag tag, BindingResult result, RedirectAttributes attributes){
Tag tag1=tagService.getTagByName(tag.getName());
if(tag1!=null){
result.rejectValue("name","nameError","不能添加重复标签");
System.out.println(result);
}
if(result.hasErrors()){
return "admin/tags-input";
}
Tag tag2=tagService.saveTag(tag);
if(tag2==null){
attributes.addFlashAttribute("message","新增失败");
}else{
attributes.addFlashAttribute("message","新增成功");
}
return "redirect:/admin/tags";
}
@RequestMapping("/tags/{id}/toUpdate")
public String toUpdate(@PathVariable Long id,Model model){
model.addAttribute("tag",tagService.getTag(id));
return "admin/tags-input";
}
@RequestMapping("/tags/update/{id}")
public String update(@Valid Tag tag, BindingResult result, @PathVariable Long id, RedirectAttributes attributes){
System.out.println("type"+tag);
Tag tag1=tagService.getTagByName(tag.getName());
if(tag1!=null){
result.rejectValue("name","nameError","不能添加重复标签");
}
if(result.hasErrors()){
return "admin/tags-input";
}
Tag tag2=tagService.updateTag(id,tag);
if(tag2!=null){
attributes.addFlashAttribute("message","更新成功");
}else {
attributes.addFlashAttribute("message","更新失败");
}
return "redirect:/admin/tags";
}
}
功能演示
新增标签
标签管理界面展示:
点击新增按钮,跳转到新增界面
输入新标签名字,点击提交:
若是出现重复标签或未填写就进行了提交,就会出现报错提示
更新标签
点击标签的“编辑”按钮,跳转到编辑界面,界面上会出现原有的标签名字,输入新标签名,点击提交
更新成功:
同样的,若是出现重复标签或未填写就进行了提交,就会像新增一样出现报错提示。