N0.3 SpringBoot 2.X 之 CRUD(增删查改)实现

在系统开发过程中,对数据库的操作是必不可少的一项内容,SpringBoot为我们提供了 SpringDataJPA 来快速实现对数据库的 CRUD(Create,Read,Update,Delete)操作。

JPA 是 Java Persistence API 的简称,中文名 Java 持久层 API,是官方(Sun)在 JDK5.0 后提出的 Java 持久化规范。其目的是为了简化现有 JAVA EE 和 JAVA SE 应用开发工作,以及整合现有的 ORM 技术实现规范统一。

下面将使用SpringBoot访问MySQL数据库,并且结合SpringDataJPA完成CRUD简单操作。

首先在N0.1 SpringBoot 2.X 之 SpringBoot初体验已经创建好了对应的项目,在此基础上,还需要引入另外的SpringBoot组件来支持CRUD操作。
添加组件
其中,必须的组件为 JPA,MySql和Web,DevTools用来实现SpringBoot项目热部署,修改代码会自动部署项目,Freemarker 是模板引擎,用来实现页面。

打开项目自动生成的 Application.java 文件:

package com.minstone;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloSpringBootApplication {

	public static void main(String[] args) {
		SpringApplication.run(HelloSpringBootApplication.class, args);
	}
}

其中 @SpringBootApplication 是 Spring Boot 项目的核心注解,主要目的是开启自动配置,main 方法是应用的入口。

接下来,需要在 application.yml 中配置数据源和 JPA 等信息。
application.yml 配置数据源和JPA等信息

可以看到在配置文件中,我们使用了本地的一个mysql数据库,并且创建了一个名叫 db_book 的数据库,JPA 配置了 ddl-aoto 来实现根据实体类自动建表,show-sql 用来在控制台输出JPA自动生成的sql语句。

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_book
    username: root
    password: 123456
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

除此之外,还需要配置DevTools的一些信息。

  devtools:
    restart:
      enabled: true
      additional-paths: src/main/java

接下来,需要创建一个 Book 实体。

package com.minstone.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name="t_book")
public class Book {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	@Column(length=100)
	private String bookName;
	
	@Column(length=50)
	private String author;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	
}

然后我们要创建一个 DAO,并继承 JpaRepository 用于简单查询,继承 JpaSpecificationExecutor 来实现复杂查询。

简单查询不需要代码实现,当简单查询无法满足我们的需求时,需要我们自己用代码去实现。

package com.minstone.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;

import com.minstone.entity.Book;

/**
 *  图书dao
 * @author ChenDongWei
 *
 */
public interface BookDao extends JpaRepository<Book, Integer>, JpaSpecificationExecutor<Book>{
	
	/**
	 * 
	 * queryByName:(根据名称查询图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月10日上午10:26:20
	 * @param bookName
	 * @return
	 */
	@Query(value = "select * from t_book where book_name like %?1%", nativeQuery=true)
	public List<Book> queryByName(String bookName);
}

创建完 DAO 后,我们再创建一个 BookService
类,在该项目中,我并没有编写 Service 接口,而是直接编写 BookService 来操作 DAO,在实际开发工作中,我们往往需要创建 Service 接口的。

package com.minstone.service;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.minstone.dao.BookDao;
import com.minstone.entity.Book;

@Service
@Transactional
public class BookService {
	@Autowired
	private BookDao bookDao;
	
    //查询所有
    public List<Book> findAll(){
        return bookDao.findAll();
    }

    //添加图书
	public void add(Book book) {
		bookDao.save(book);
	}
	
	//根据ID查找图书
	public Book preUpdate(int id) {
		Book book = bookDao.getOne(id);
		return book;
	}
	
	//修改图书
	public void update(Book book) {
		bookDao.save(book);
	}
	
	//删除图书
	public void delete(int id) {
		bookDao.deleteById(id);
	}
	
	//根据书名查找图书
	public List<Book> queryByName(String bookName){
		return bookDao.queryByName(bookName);
	}
	
	//根据名称或作者查询(高级)
	public List<Book> queryByNameOrAuthor(Book book) {
		List<Book> bookList = bookDao.findAll(new Specification<Book>() {
			
			@Override
			public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate predicate = cb.conjunction();
				if (book != null) {
					if (StringUtils.isNotBlank(book.getBookName())) {
						predicate.getExpressions().add(cb.like(root.get("bookName"), "%"+book.getBookName().trim()+"%"));
					}
					if (StringUtils.isNotBlank(book.getAuthor())) {
						predicate.getExpressions().add(cb.like(root.get("author"), "%"+book.getAuthor().trim()+"%"));
					}
				}
				return predicate;
			}
		});
		
		return bookList;
	}
}

上述方法中,queryByNameOrAuthor 方法是根据名称或作者查询,需要调用到我们在 DAO 中收到编写的代码,其他的方法,都是 SpringBoot JPA 内置的方法,当然,其支持分页的操作,在这里不做演示。

接着我们创建一个 BookController 类。

package com.minstone.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.minstone.entity.Book;
import com.minstone.service.BookService;

/**
 *  图书控制类
 * @author ChenDongWei
 *
 */
@RestController
@RequestMapping("/book/")
public class BookController {
	@Autowired
	private BookService bookService;
	
	/**
	 * 
	 * list:(查询所有图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月9日下午8:27:53
	 * @return
	 */
	@RequestMapping("list")
	public ModelAndView list() {
		ModelAndView modelAndView = new ModelAndView("bookList");
		modelAndView.addObject("bookList", bookService.findAll());
		return modelAndView;
	}
	
	/**
	 * 
	 * add:(添加图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月9日下午8:28:48
	 * @param book
	 * @return
	 */
	@RequestMapping("add")
	public ModelAndView add(Book book) {
		bookService.add(book);
		return list();
	}
	
	/**
	 * 
	 * preUpdate:(跳转到修改图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月9日下午8:29:07
	 * @param id
	 * @return
	 */
	@RequestMapping("preUpdate/{id}")
	public ModelAndView preUpdate(@PathVariable("id")Integer id) {
		ModelAndView modelAndView = new ModelAndView("bookUpdate");
		modelAndView.addObject("book", bookService.preUpdate(id));
		return modelAndView;
	}
	
	/**
	 * 
	 * update:(修改图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月9日下午8:29:25
	 * @param book
	 * @return
	 */
	@RequestMapping("update")
	public ModelAndView update(Book book) {
		bookService.update(book);
		return list();
	}
	
	/**
	 * 
	 * delete:(删除图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月9日下午8:29:43
	 * @param id
	 * @return
	 */
	@RequestMapping("delete")
	public ModelAndView delete(Integer id) {
		bookService.delete(id);
		return list();
	}
	
	/**
	 * 
	 * query:(根据名称查询图书). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月10日上午10:16:04
	 * @param bookName
	 * @return
	 */
	@RequestMapping("queryByName")
	public ModelAndView queryByName(String bookName) {
		ModelAndView modelAndView = new ModelAndView("bookList");
		modelAndView.addObject("bookList", bookService.queryByName("放弃"));
		return modelAndView;
	}
	
	/**
	 * 
	 * queryByNameOrAuthor:(根据名称或作者查询). <br/> 
	 * @author ChenDongWei
	 * @date 2018年8月10日下午1:46:57
	 * @param book
	 * @return
	 */
	@RequestMapping("queryByNameOrAuthor")
	public ModelAndView queryByNameOrAuthor(Book book) {
		ModelAndView modelAndView = new ModelAndView("bookList");
		modelAndView.addObject("bookList", bookService.queryByNameOrAuthor(book));
		return modelAndView;
	}
}

最后,需要用 freemarker 模板和 html 来实现页面。

在 src/main/webapp 目录下创建 bookAdd.html。
添加图书页面
在 src/main/resources/templates 页面下创建 bookList.ftl 和 bookUpdate.ftl 页面,其中 .ftl 是 freemarker 模板的后缀。
创建 bookList.ftl
图书列表页面
创建 bookUpdate.ftl
修改图书页面
至此,SpringBoot 实现 CRUD 的项目就完成了,我们启动项目测试一下。

注意:首次项目启动后,控制台会打印 Hibernate 的建表语句,这是因为我们在 application.yml 中配置了 ddl-auto: update,会根据实体类自动在数据库创建表。

创建的表如下,其中长度,主键等与实体类的配置是一致的。
db_book 表
然后我们在表中手动插入几条初始数据。
插入初始数据
运行项目成功后,访问 http://127.0.0.1:8082/book/list 查询图书列表
图书列表

此时,控制台打印出了执行的 sql 语句。

Hibernate: select book0_.id as id1_1_, book0_.author as author2_1_, book0_.book_name as book_nam3_1_ from t_book book0_

列表显示正常,搜索,添加,修改和删除功能也能正常实现。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值