1.springboot是什么,給我們帶來了什么方便?
通過閱讀springboot的書籍發現springboot最便利的是為我們自動配置了很多的東西,幾乎可以實現無xml,甚至簡單的無sql,為我們帶來了很大的遍歷,下面我們看看springboot為我們提供了那些配置:
這些所有的包都可以在spring-boot-autoconfigure上都可以看到
2.這里做的是一個學生表
package com.yangchao.spring.boot.blog.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.hibernate.validator.constraints.NotEmpty; @Entity public class Student implements Serializable { /** * */ private static final long serialVersionUID = 1L; //標識其是一個主鍵id @Id @GeneratedValue(strategy = GenerationType.IDENTITY)//表示其增長策略為自增長 private Long id;//學生的唯一標識 @NotEmpty(message = "姓名不能為空") @Column(nullable = false, length = 20,name="name") // 映射為字段,值不能為空,name標識的是數據庫的名字 private String name;//學生的姓名 @NotEmpty(message = "性別不能為空")//NotEmpty只能針對字符型才能進行判斷空 @Column(nullable = false, length =2,name="sex") // 映射為字段,值不能為空,name標識的是數據庫的名字 private String sex; @Column(nullable = false,name="age") // 映射為字段,值不能為空,name標識的是數據庫的名字 private Integer age; @Column(name="course_id") private Integer course_id;//學生所選的所有課程 protected Student() {//按照JPA規范定義的一個protected的構造函數,防止被外部使用 } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public void setName(String name) { this.name = name; } public Integer getCourse_id() { return course_id; } public void setCourse_id(Integer course_id) { this.course_id = course_id; } public Student(String name, String sex, Integer age, Integer course_id) { super(); this.name = name; this.sex = sex; this.age = age; this.course_id = course_id; } /** * 重寫tostring的原因其實就是數據的傳輸,所以也必須實現序列化接口serialize接口 * 自從jquery1.9后,json的格式必須滿足的是:[{"key":"value"},{"key":"value"}]的格式,除了Boolean型不需要外,其余都是需要的 */ @Override public String toString() { // TODO Auto-generated method stub return "{\"id\":"+"\""+getId()+"\""+","+"\""+name+"\":"+"\""+"getName()"+"\","+"\""+sex+"\":"+"\""+"getSex()"+"\","+"\""+age+"\":"+"\""+getAge()+"\""; } }
3.需要引入的依賴
// buildscript 代碼塊中腳本優先執行 buildscript { // ext 用於定義動態屬性 ext { springBootVersion = '1.5.2.RELEASE' } // 自定義 Thymeleaf 和 Thymeleaf Layout Dialect 的版本 ext['thymeleaf.version'] = '3.0.3.RELEASE' ext['thymeleaf-layout-dialect.version'] = '2.2.0' // 自定義 Hibernate 的版本 ext['hibernate.version'] = '5.2.8.Final' // 使用了 Maven 的中央倉庫(你也可以指定其他倉庫) repositories { //mavenCentral() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } // 依賴關系 dependencies { // classpath 聲明說明了在執行其余的腳本時,ClassLoader 可以使用這些依賴項 classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } // 使用插件 apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' // 打包的類型為 jar,並指定了生成的打包的文件名稱和版本 jar { baseName = 'blog-comment' version = '1.0.0' } // 指定編譯 .java 文件的 JDK 版本 sourceCompatibility = 1.8 // 默認使用了 Maven 的中央倉庫。這里改用自定義的鏡像庫 repositories { //mavenCentral() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } // 依賴關系 dependencies { // 該依賴對於編譯發行是必須的 compile('org.springframework.boot:spring-boot-starter-web') // 添加 Thymeleaf 的依賴 compile('org.springframework.boot:spring-boot-starter-thymeleaf') // 添加 Spring Data JPA 的依賴 compile('org.springframework.boot:spring-boot-starter-data-jpa') // 添加 MySQL連接驅動 的依賴 compile('mysql:mysql-connector-java:6.0.5') // 添加 Apache Commons Lang 依賴 compile('org.apache.commons:commons-lang3:3.5') // 該依賴對於編譯測試是必須的,默認包含編譯產品依賴和編譯時依 testCompile('org.springframework.boot:spring-boot-starter-test') }
3.JPA
package com.waylau.spring.boot.blog.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import com.waylau.spring.boot.blog.domain.Student; /** * 使用JPA自定義接口進行實現,少些代碼 * 這個例子在原有的接口方法上多定義了一些方法,以便應用 * @author lenovo * */ public interface StudentRepository extends JpaRepository<Student, Long> { //根據方法名實現底層自動化生成sql,根據學生性別查詢學生信息 List<Student> findBySex(String sex); //根據學生的姓模糊查詢學生的詳細信息,該方法名等同於where name like ?1; @Query("select s from Student s where name like CONCAT('%',:name,'%')") List<Student> findByNameLike(@Param("name") String name); //根據學生年齡段查詢學生的詳細信息 List<Student> findByAgeBetween(Integer age1,Integer age2); //如果感覺JPA不能滿足需求也可以自定義sql;注意這里占位符?后面是數字1,select后面不能使用*,必須要給表取個別名,否則會報錯 @Query("select s from Student s where s.name =?1") List<Student> getStudent(); }
4.定義學生類接口和實現類
package com.waylau.spring.boot.blog.service; import java.util.List; import com.waylau.spring.boot.blog.domain.Student; public interface StudentService { /** * 增加學生 * @param student * @return */ Student saveStudent(Student student); /** * 刪除單個學生 * @param id * @return */ void removeStudent(Long id); /** * 更新學生信息 * @param student * @return */ Student updateStudent(Student student); /** * 根據id獲取學生信息 * @param id * @return */ Student getStudentById(Long id); /** * 獲取學生列表 * @param user * @return */ List<Student> listStudents(); /** * 根據前台的姓名,性別,年齡進行查詢學生的基本信息 * @param name * @param sex * @param age * @return */ List<Student> listStudentsByNameAndAgeAndSex(String name,String sex,Integer age1,Integer age2); }
package com.waylau.spring.boot.blog.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.waylau.spring.boot.blog.domain.Student; import com.waylau.spring.boot.blog.repository.StudentRepository; @Service public class StudentServiceImpl implements StudentService{ //注入StudentRepositoryJPA @Autowired StudentRepository studentReposutory; @Override public Student saveStudent(Student student) { // TODO Auto-generated method stub return studentReposutory.save(student); } @Override public void removeStudent(Long id) { // TODO Auto-generated method stub studentReposutory.delete(id); } @Override public Student updateStudent(Student student) { // TODO Auto-generated method stub return studentReposutory.save(student); } @Override public Student getStudentById(Long id) { // TODO Auto-generated method stub return studentReposutory.findOne(id); } @Override public List<Student> listStudents() { // TODO Auto-generated method stub return studentReposutory.findAll(); } @Override public List<Student> listStudentsByNameAndAgeAndSex(String name, String sex,Integer age1,Integer age2) { // TODO Auto-generated method stub if(name != null) { return studentReposutory.findByNameLike(name); }else if(sex != null) { return studentReposutory.findBySex(sex); }else { return studentReposutory.findByAgeBetween(age1,age2); } } }
5.controller層
package com.waylau.spring.boot.blog.controller; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import com.waylau.spring.boot.blog.domain.Student; import com.waylau.spring.boot.blog.service.StudentService; import net.minidev.json.JSONArray; @RestController//使用rest風格實現controller映射 @RequestMapping("/user") public class StudentController { @Autowired StudentService studentService; /** * 通過Get請求user,直接進入到這里的映射中 * @param model * @return */ @GetMapping public ModelAndView queryAllStudent(Model model) { List<Student> students = studentService.listStudents(); model.addAttribute("allStudent", students); model.addAttribute("title","學生信息表"); return new ModelAndView("index", "userModel", model); } /** * 根據id查詢學生的詳細信息 */ @GetMapping("{id}")//通過傳遞的是一個參數id進行的映射 public ModelAndView view(@PathVariable("id") Long id,Model model){ Student student = studentService.getStudentById(id); model.addAttribute("student",student); model.addAttribute("sex",student.getSex()); model.addAttribute("title","查看學生"); return new ModelAndView("view","userModel",model); } /** * 返回學生新增界面 * @param model * @return */ @RequestMapping("add") public ModelAndView addStudent(Model model) { model.addAttribute("title","新增"); return new ModelAndView("add","userModel",model); } // /** // * 新增學生 // * @param student // * @return // */ // @RequestMapping("insert") // public ModelAndView insertStudent(HttpServletRequest req,Model model) { // String name = req.getParameter("name"); // Integer age =Integer.parseInt(req.getParameter("age")); // String sex = req.getParameter("sex"); // String[] course_ids = req.getParameterValues("course_id"); // Integer course_id = Integer.parseInt(course_ids[0]); // Student student = new Student(name,sex,age,course_id); // studentService.saveStudent(student); // return new ModelAndView("redirect:/user");//重新定向到index頁面 // } /** * 這里直接定義Student對象,前端使用 * th:value="*{name}",和后端的對象直接進行了映射 * @param student * @param model * @return */ @RequestMapping("insert") public ModelAndView insertStudent(Student student) { studentService.saveStudent(student); return new ModelAndView("redirect:/user");//重新定向到index頁面 } /** * 學生信息的刪除 * @param id * @param model * @return */ @GetMapping("del/{id}") public ModelAndView deleteStudent(@PathVariable("id") Long id,Model model) { studentService.removeStudent(id); return new ModelAndView("redirect:/user");//重新定向到index頁面 } /** * 學生信息的修改 * @param student * @return */ @PostMapping public ModelAndView updateStudent(Student student) { studentService.updateStudent(student); return new ModelAndView("redirect:/user");//重新定向到index頁面 } /** * 根據姓名查詢學生詳細信息 * @param req * @param model * @return * @throws IOException */ @PostMapping("queryStudentByCondition") public void queryStudentByCondition(HttpServletRequest req,HttpServletResponse response) throws IOException { String name = req.getParameter("name"); //防止前台的亂碼問題 response.setCharacterEncoding("utf-8"); String sex = null; Integer age1 = null; Integer age2 = null; List<Student> students = studentService.listStudentsByNameAndAgeAndSex(name, sex, age1, age2); PrintWriter wirte; //聲明JSONArray對象並輸入JSON字符串 String array = JSONArray.toJSONString(students); wirte = response.getWriter(); wirte.print(array); } }
6.jsp學生列表頁面index.jsp
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <!-- 定義頁面顯示的編碼格式 --> <meta charset="utf-8"> <script th:src="@{../js/jquery-3.1.1.min.js}"></script> <script> function queryStudentByName(){ $.ajax({ type:'POST', data:{name:'楊超'}, url:"/user/queryStudentByCondition",//請求的action路徑 success:function(returnValue){ //請求成功后處理函數。 //處理后端傳送過來json格式數據 var msg=jQuery.parseJSON(returnValue); }, error:function () {//請求失敗處理函數 alert('請求失敗'); } }); } </script> </head> <body> <!-- 獲取model屬性中的title值,定義標題 --> <h3 th:text="${userModel.title}"></h3> <input type="search" onblur="queryStudentByName()" id="name"/> <div> <a href="add.html" th:href="@{/user/add}">新增</a> </div> <table border="1"> <thead> <tr> <td>id</td> <td>姓名</td> <td>性別</td> <td>年齡</td> <td>課程</td> <td>刪除</td> </tr> </thead> <!--對於學生信息做一個判斷,沒有顯示一個默認的 --> <tr th:if="${userModel.allStudent.size()} eq 0"> <td colspan="3">沒有學生信息</td> </tr> <!-- 對學生信息進行迭代 --> <tbody id="tbody"> <tr th:each="user : ${userModel.allStudent}"> <!-- 類似於jstl的用法,可以直接從上面的對象中獲取值 --> <td th:text="${user.id}"></td> <td><a th:href="@{'/user/'+${user.id}}" th:text="${user.name}"></a></td> <!-- 動態生成一個查看用戶信息的鏈接 --> <td th:text="${user.sex}"></td> <td th:text="${user.age}"></td> <td th:text="${user.course_id}"></td> <td ><a th:href="@{'/user/del/'+${user.id}}">刪除</a></td> </tr> </tbody> </table> </body> </html>
新增頁面add.jsp
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h3 th:text="@{userModel.title}"></h3> <form action="/user/insert" method="post"> <input type="hidden" name="id" th:value="*{id}"/> 姓名:<input type="text" placeholder="姓名" name="name" th:value="*{name}" /></br> 年齡:<input type="text" placeholder="年齡" name="age" th:value="*{age}" /></br> 性別:<select name="sex" th:value="*{sex}"> <option value="男">男</option> <option value="女">女</option> </select> 選課:<input type="checkbox" name="course_id" value="1"/>語文 <input type="checkbox" name="course_id" value="2"/>數學 <input type="checkbox" name="course_id" value="3"/>英語</br> <input type="submit" value="提交"/> <input style="margin-left:30px" type="button" value="取消"/> </form> </body> </html>
顯示和修改頁面:view.jsp
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>學生詳細信息</title> <script th:src="@{../js/jquery-3.1.1.min.js}"></script> </head> <!-- 為了在js中使用thymeleaf --> <script th:inline="javascript"> //將下拉框和復選框進行選中 function onload(){ //在js中引用thymeleaf的語法 var sex = [[${userModel.student.sex}]]; document.getElementById("sex").value =sex; var course = [[${userModel.student.course_id}]]; $("input:checkbox[value='"+course+"']").attr("checked","checked"); } </script> <body onload="onload()"> <form action="/user" method="post" th:object="${userModel.student}"> <input type="hidden" name="id" th:value="*{id}" /> 姓名:<input type="text" placeholder="姓名" name="name" th:value="*{name}" /></br> 年齡:<input type="text" placeholder="年齡" name="age" th:value="*{age}" /></br> 性別:<select name="sex" th:value="*{sex}" id="sex"> <option value="男">男</option> <option value="女">女</option> </select> 選課:<input type="checkbox" name="course_id" value="1" id="1"/>語文 <input type="checkbox" name="course_id" value="2" id="2"/>數學 <input type="checkbox" name="course_id" value="3" id="3"/>英語</br> <input type="submit" value="修改"/> <input style="margin-left:30px" type="button" value="取消"/> </form> </body> </html>
7.application.properties配置
server.port=8080 debug=false # THYMELEAF spring.thymeleaf.encoding=UTF-8 # 熱部署靜態文件 spring.thymeleaf.cache=false # 使用HTML5標准 spring.thymeleaf.mode=HTML5 # DataSource spring.datasource.url=jdbc:mysql://localhost/blog?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # JPA,表示是否在控制台輸出sql spring.jpa.show-sql=true #使用hibernate創建表格,是否將已存在的表格進行刪除,這個配置只適用於生產測試環節 spring.jpa.hibernate.ddl-auto=create-drop
今天寫的有點沖忙,后面再做詳細解釋.我將源碼附在后面,各位可自行下載
https://pan.baidu.com/s/1smjNqUT
減壓密碼:957p