Spring Boot(二):web應用開發,實現CRUD

1、開發web應用javascript

Spring Boot Web 開發很是的簡單,其中包括經常使用的 json 輸出、filters、property、log 等css

2、json接口開發html

之前使用spring開發項目,須要提供json接口時須要作什麼呢?前端

一、 添加jackjson等相關的jar包vue

二、配置spring controller掃描包java

三、對接的方法添加 @ResponseBodymysql

咱們常常因爲配置錯誤出現406錯誤,因爲掃描包理解不到位的配置錯誤(SSM框架就遇到了,搞了好幾天才解決掉!)等等,springboot如何作呢,只須要類添加 @RestController  便可,默認類中的方法都會以json的格式返回jquery

@RestController
public class HelloController {
    @RequestMapping("/getUser")
    public User getUser() {
    	User user=new User();
    	user.setUserName("素小暖");
    	user.setPassWord("xxxx");
        return user;
    }
}

若是須要使用頁面開發只要使用@Controller註解便可,下面會結合模板來講明。web

3、自定義filterspring

咱們經常在項目中會使用filters用於調用日誌、排除有XXS威脅的字符、執行權限驗證等等。

springboot自動添加了 OrderedCharacterEncodingFilter 和 HiddenHttpMethodFilter, 而且咱們能夠自定義filter。

兩個步驟

(1)實現filter接口,實現filter方法

(2)添加 @Configuration 註解,將自定義filter加入過濾鏈

@Configuration
public class WebConfiguration {
    @Bean
    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }
    
    @Bean
    public FilterRegistrationBean testFilterRegistration() {

        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.setName("MyFilter");
        registration.setOrder(1);
        return registration;
    }
    
    public class MyFilter implements Filter {
		@Override
		public void destroy() {
			// TODO Auto-generated method stub
		}

		@Override
		public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
				throws IOException, ServletException {
			// TODO Auto-generated method stub
			HttpServletRequest request = (HttpServletRequest) srequest;
			System.out.println("this is MyFilter,url :"+request.getRequestURI());
			filterChain.doFilter(srequest, sresponse);
		}

		@Override
		public void init(FilterConfig arg0) throws ServletException {
			// TODO Auto-generated method stub
		}
    }
}

4、自定義property

在 Web 開發的過程當中,我常常須要自定義一些配置文件,如何使用呢?

一、配置在application.properties中

server.port=8081
#spring.profiles.active=dev

# idea\uFF0Cproperties\u914D\u7F6E\u6587\u4EF6utf-8
# \uFFFD\uFFFD\uFFFD\uFFFDperson\uFFFD\uFFFD\u05B5
person.last-name=\u5F20\u4E09${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15

二、自定義配置類

@Component
public class NeoProperties {
	@Value("${person.last-name}")
	private String last-name;//此處last-name與lastName同樣
	@Value("${person.age}")
	private int age;
    ...
	//省略getter settet方法

}

三、log配置

配置輸出的地址和輸出級別

logging.path=/user/local/log
logging.level.com.favorites=DEBUG
logging.level.org.springframework.web=INFO
logging.level.org.hibernate=ERROR

path 爲本機的 log 地址,logging.level 後面能夠根據包路徑配置不一樣資源的 log 級別

5、數據庫操做

這裏咱們重點講述MySQL、spring data jpa的使用。jpa是利用hibernate生成各類自動化的sql,若是隻是簡單的增刪改查,基本不用手寫,spring內部已經封裝好了。

下面介紹一下在springboot中的使用

一、添加相關jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
 <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

二、添加配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

其實這個 hibernate.hbm2ddl.auto 參數的做用主要用於:自動創。

驗證數據庫表結構有四個值:

  • create:每次加載hibernate時都會刪除上一次生成的表,而後根據你的model類再從新來生成新表,哪怕;兩次沒有任何改變也要這樣執行,這就是致使了數據庫表數據丟失的一個重要緣由。
  • create-drop:每次加載hibernate時根據model類生成表,可是sessionFactory一關閉,表就自動刪除了。
  • update:最經常使用的屬性,第一次加載hibernate時根據model類會自動創建標的結構,之後加載hibernate時根據model類自動更新表結構,即便表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器後,表結構是不會被立刻創建起來的,是要等應用第一次運行起來後纔會。
  • validate:每次加載hibernate時,驗證建立數據庫表結構,只會和數據庫中的表踐行比較,不會建立新表,可是會插入新值。

dialect 主要是指定生成表名的存儲引擎爲 InnoDBD
show-sql 是否打印出自動生成的 SQL,方便調試的時候查看

三、添加實體類和dao

@Entity
public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Long id;
	@Column(nullable = false, unique = true)
	private String userName;
	@Column(nullable = false)
	private String passWord;
	@Column(nullable = false, unique = true)
	private String email;
	@Column(nullable = true, unique = true)
	private String nickName;
	@Column(nullable = false)
	private String regTime;

	//省略getter settet方法、構造方法

}

dao 只要繼承 JpaRepository 類就能夠,幾乎能夠不用寫方法,還有一個特別有尿性的功能很是贊,就是能夠根據方法名來自動的生成 SQL,好比findByUserName 會自動生成一個以 userName 爲參數的查詢方法,好比 findAlll 自動會查詢表裏面的全部數據,好比自動分頁等等。。

Entity中不該是成列的字段得加 @Transient 註解,不加註解也會映射成列

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUserName(String userName);
    User findByUserNameOrEmail(String username, String email);
}

四、測試

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class UserRepositoryTests {

	@Autowired
	private UserRepository userRepository;

	@Test
	public void test() throws Exception {
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);        
		String formattedDate = dateFormat.format(date);
		
		userRepository.save(new User("aa1", "aa@126.com", "aa", "aa123456",formattedDate));
		userRepository.save(new User("bb2", "bb@126.com", "bb", "bb123456",formattedDate));
		userRepository.save(new User("cc3", "cc@126.com", "cc", "cc123456",formattedDate));

		Assert.assertEquals(9, userRepository.findAll().size());
		Assert.assertEquals("bb", userRepository.findByUserNameOrEmail("bb", "cc@126.com").getNickName());
		userRepository.delete(userRepository.findByUserName("aa1"));
	}

}

6、Thymeleaf 模板

Spring Boot 推薦使用 Thymeleaf 來代替 Jsp。

一、Thymeleaf介紹

Thymeleaf是一款用於渲染 XML/XHTML/HTML5 內容的模板引擎。 相似於JSP。它能夠輕易的與springMVC框架進行集成做爲web應用的模板引擎。與其餘模板引擎相比, Thymeleaf  最大的特色是可以直接在瀏覽器中打開並正確顯示模板頁面,而不須要啓動整個web應用。

Thymeleaf 使用了天然的模板技術,這意味着 Thymeleaf 的模板語法不會破壞文檔的結構,模板依舊是有效的XML文檔。模板還能夠用做工做原型, Thymeleaf 會在運行期替換掉靜態值。

URL 在 Web 應用模板中佔據着十分重要的地位,須要特別注意的是 Thymeleaf 對於 URL 的處理是經過語法 @{...} 來處理的。Thymeleaf 支持絕對路徑 URL:

<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>

條件求值

<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>

 for循環

<tr th:each="prod : ${prods}">
      <td th:text="${prod.name}">Onions</td>
      <td th:text="${prod.price}">2.41</td>
      <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>

二、頁面即原型

  在傳統 Java Web 開發過程當中,前端工程師和後端工程師同樣,也須要安裝一套完整的開發環境,而後各種 Java IDE 中修改模板、靜態資源文件,啓動/重啓/從新加載應用服務器,刷新頁面查看最終效果。

但實際上前端工程師的職責更多應該關注頁面,使用JSP很難作到這點,由於JSP必須在應用服務器中渲染完成後才能在瀏覽器中看到效果,而 Thymeleaf從跟不上解決了這個問題,經過屬性進行模板渲染不會引入任何新的瀏覽器不能識別的標籤,例如JSP中,不會再Tag內部寫表達式。 整個頁面直接做爲 HTML 文件用瀏覽器打開,幾乎就能夠看到最終的效果,這大大解放了前端工程師的生產力,它們的最終交付物就是純的 HTML/CSS/JavaScript 文件。

7、Gradle構建工具

spring項目建議使用 Maven/Gradle 進行構建項目 ,相比Maven來說Gradle更簡潔,並且Gradle更適合大型複雜項目的構建。Gradle吸取了maven和ant的特色,不過目前maven仍然是java界的主流,先了解一下嘛。

一個使用 Gradle 配置的項目:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
    }
}

apply plugin: 'java'  //添加 Java 插件, 代表這是一個 Java 項目
apply plugin: 'spring-boot' //添加 Spring-boot支持
apply plugin: 'war'  //添加 War 插件, 能夠導出 War 包
apply plugin: 'eclipse' //添加 Eclipse 插件, 添加 Eclipse IDE 支持, Intellij Idea 爲 "idea"

war {
    baseName = 'favorites'
    version =  '0.1.0'
}

sourceCompatibility = 1.7  //最低兼容版本 JDK1.7
targetCompatibility = 1.7  //目標兼容版本 JDK1.7

repositories {     //  Maven 倉庫
    mavenLocal()        //使用本地倉庫
    mavenCentral()      //使用中央倉庫
    maven { url "http://repo.spring.io/libs-snapshot" } //使用遠程倉庫
}
 
dependencies {   // 各類 依賴的jar包
    compile("org.springframework.boot:spring-boot-starter-web:1.3.6.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf:1.3.6.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-data-jpa:1.3.6.RELEASE")
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
    compile("org.springframework.boot:spring-boot-devtools:1.3.6.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-test:1.3.6.RELEASE")
    compile 'org.webjars.bower:bootstrap:3.3.6'
	compile 'org.webjars.bower:jquery:2.2.4'
    compile("org.webjars:vue:1.0.24")
	compile 'org.webjars.bower:vue-resource:0.7.0'

}

bootRun {
    addResources = true
}

8、 WebJars

WebJars 是一個很神奇的東西,可讓你們以jar包的形式來使用前端的各類框架、組件。

一、什麼是 WebJars

WebJars是將客戶端資源打包成jar包文件,以對資源進行統一依賴管理。 WebJars 的jar包部署在maven中央倉庫上。

二、爲何使用

咱們在開發java web項目的時候會使用Maven、 Gradle等構建工具以實現對jar包版本依賴管理,以及項目的自動化管理,可是對於JavaScript、css等前端資源包,咱們只能採用拷貝到webapp下的方式,這樣作就沒法對這些資源進行依賴管理,那麼WebJars就提供給咱們這些前端資源的jar包資源,咱們就能夠進行依賴管理了。

三、如何使用

(1)添加依賴

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>vue</artifactId>
    <version>2.5.16</version>
</dependency>

(2)頁面引入

<link th:href="@{/webjars/bootstrap/3.3.6/dist/css/bootstrap.css}" rel="stylesheet"></link>

9、CRUD

已經完成了springboot的CRUD

關鍵的代碼貼出來,分享一下吧

一、先看一下項目架構

二、擴展SpringMVC的功能

package com.springboot.config;

import com.springboot.component.LoginHandlerInterceptor;
import com.springboot.component.MyLocaleResolver;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

//使用WebMvcConfigurerAdapter能夠來擴展SpringMVC的功能
//@EnableWebMvc   不要接管SpringMVC
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
       // super.addViewControllers(registry);
        //瀏覽器發送 /atguigu 請求來到 success
        registry.addViewController("/atguigu").setViewName("success");
    }

    //全部的WebMvcConfigurerAdapter組件都會一塊兒起做用
    @Bean //將組件註冊在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
                registry.addViewController("/main.html").setViewName("dashboard");
            }

            //註冊攔截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                //super.addInterceptors(registry);
                //靜態資源;  *.css , *.js
                //SpringBoot已經作好了靜態資源映射
//                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
//                        .excludePathPatterns("/index.html","/","/user/login");
            }
        };
        return adapter;
    }

    @Bean
    public LocaleResolver localeResolver(){

        return new MyLocaleResolver();
    }

}

三、controller

package com.springboot.controller;

import com.springboot.dao.DepartmentDao;
import com.springboot.dao.EmployeeDao;
import com.springboot.entities.Department;
import com.springboot.entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@Controller
public class EmployeeController {
    @Autowired
    EmployeeDao employeeDao;

    @Autowired
    DepartmentDao departmentDao;

    //查詢全部員工返回列表頁面
    @GetMapping("/emps")
    public String  list(Model model){
        Collection<Employee> employees = employeeDao.getAll();

        //放在請求域中
        model.addAttribute("emps",employees);
        // thymeleaf默認就會拼串
        // classpath:/templates/xxxx.html
        return "emp/list";
    }

    //來到員工添加頁面
    @GetMapping("/emp")
    public String toAddPage(Model model){
        //來到添加頁面,查出全部的部門,在頁面顯示
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("depts",departments);
        return "emp/add";
    }

    //員工添加
    //SpringMVC自動將請求參數和入參對象的屬性進行一一綁定;要求請求參數的名字和javaBean入參的對象裏面的屬性名是同樣的
    @PostMapping("/emp")
    public String addEmp(Employee employee){
        //來到員工列表頁面

        System.out.println("保存的員工信息:"+employee);
        //保存員工
        employeeDao.save(employee);
        // redirect: 表示重定向到一個地址  /表明當前項目路徑
        // forward: 表示轉發到一個地址
        return "redirect:/emps";
    }

    //來到修改頁面,查出當前員工,在頁面回顯
    @GetMapping("/emp/{id}")
    public String toEditPage(@PathVariable("id") Integer id,Model model){
        Employee employee = employeeDao.get(id);
        model.addAttribute("emp",employee);

        //頁面要顯示全部的部門列表
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("depts",departments);
        //回到修改頁面(add是一個修改添加二合一的頁面);
        return "emp/add";
    }

    //員工修改;須要提交員工id;
    @PutMapping("/emp")
    public String updateEmployee(Employee employee){
        System.out.println("修改的員工數據:"+employee);
        employeeDao.save(employee);
        return "redirect:/emps";
    }

    //員工刪除
    @DeleteMapping("/emp/{id}")
    public String deleteEmployee(@PathVariable("id") Integer id){
        employeeDao.delete(id);
        return "redirect:/emps";
    }

}

四、前端頁面

以list.html爲例,使用springboot特帶的Thymeleaf模板引擎

(1)引入

xmlns:th="http://www.thymeleaf.org"

(2)關鍵的js、css引入

script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
<script type="text/javascript" src="asserts/js/popper.min.js" th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script>
<script type="text/javascript" src="asserts/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script>

<!-- Icons -->
<script type="text/javascript" src="asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script>

(3)form表單提交

<div class="container-fluid">
  <div class="row">
	<!--引入側邊欄-->
	<div th:replace="commons/bar::#sidebar(activeUri='emps')"></div>

	<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
		<h2><a class="btn btn-sm btn-success" href="emp" th:href="@{/emp}">員工添加</a></h2>
		<div class="table-responsive">
		  <table class="table table-striped table-sm">
			<thead>
				<tr>
					<th>#</th>
					<th>lastName</th>
					<th>email</th>
					<th>gender</th>
					<th>department</th>
					<th>birth</th>
					<th>操做</th>
				</tr>
			</thead>
			<tbody>
				<tr th:each="emp:${emps}">
					<td th:text="${emp.id}"></td>
					<td>[[${emp.lastName}]]</td>
					<td th:text="${emp.email}"></td>
					<td th:text="${emp.gender}==0?'女':'男'"></td>
					<td th:text="${emp.department.departmentName}"></td>
					<td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"></td>
					<td>
					  <a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.id}">編輯</a>
					  <button th:attr="del_uri=@{/emp/}+${emp.id}" class="btn btn-sm btn-danger deleteBtn">刪除</button>
					</td>
				</tr>
			</tbody>
		  </table>
		</div>
	</main>
	<form id="deleteEmpForm"  method="post">
		<input type="hidden" name="_method" value="delete"/>
	</form>
  </div>
</div>

(4)jQuery實現

<script>
    $(".deleteBtn").click(function(){
	//刪除當前員工的
	$("#deleteEmpForm").attr("action",$(this).attr("del_uri")).submit();
		return false;
    });
</script>

五、實現效果

 

素小暖講Spring Boot

相關文章
相關標籤/搜索