奋斗的Fly

springboot+thymeleaf+springbootJPA实现一个简单的增删改查

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

 

posted on 2018-02-08 17:37  奋斗的Fly  阅读(12267)  评论(0编辑  收藏  举报

导航