java springBoot连接数据库进行增删改查、模糊查询、表连接、全选操作、分页操作、数据回显。学习项目实例

java springBoot连接数据库进行增删改查、模糊查询、表连接、全选操作、分页操作、数据回显

1. 声明一下:自己也是一知半解,并不是完全理解,写这篇博客,一是为了帮大家一块入门,共同进步,二也是为了让自己有所进步,下面代码有冗余现象正常,有不规范的地方也是正常,入门阶段,代码能跑,心满意足。

2. 代码摆在这了,在我这里是可以运行的,不然我也不会发出来,看的时候仔细看,需要注意的地方我都标出来了,只要注意,完全没问题的,报错,是你自己写错代码了,不要埋怨自己的机子不行、环境不行什么的。从自身出发,寻找自己的问题,同时也欢迎大佬斧正。

3. 进入正题。首先看下目录结构,我把需要注意的用红色码标注了,没必要看的就用黄色的挡住了。这次主要操作的是work这个数据表

4. 每一个文件都要注意下有没有注解。就是以@开头的东西

5. 这里需要注意的是,所有的目录,都是在启动项目录的下层的。这个是必须在它下层的(同级可能也可以,没试过)。

在这里插入图片描述

连接数据库前的配置

先实在跟application.properties文件相同的位置新键一个application.yml文件(直接新键文件,然后改后缀就行,这个没必要讲,常识)。
8080是端口号,我是默认的,没有修改,改了的话就用自己的。
下面url地方有需要改的。
url里面有个yhy?,yhy是我的数据库名,这个改成自己的,问号要保留。
其他地方都不需要改,包括dirver-class-name。

server:
  port: 8080 
  servlet:
    context-path:      
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/yhy?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver

实体类代码

这里的代码没什么好说的,就是根据数据表里面的字段名,封装起来,然后写getter、setter方法。我把需要导的包页写上了,不合适的可以对照一下,写这个报错的话,一定别把包导错了。
必须要说的一点是,必须要写注解!!!实体里面我写了三个注解

package com.example.stu;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//work是我的表名,到时候替换成自己的就可以了
@Entity(name = "work")
@Table(name = "work")//这个貌似可以不写,到时候试试,不行就删了,
public class Work {
	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)//规定默认的id
	private String id;//id
	private String name;//姓名
	private String cla;//班级
	//这里我还省略了很多的字段名,下面代码碰到字段名我会指出
	//写getter/setter方法

关键部分①DAO部分代码

因为大部分的方法都来自继承的对象,所以基本用不到sql语句了,用sql语句纯粹是无奈之举,实在不会了才用sql语句。而且在这里使用sql语句,就失去了springBoot的意义了。(个人理解,大佬指点批评,虚心接受)

package com.example.dao;

import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;

import com.example.stu.Work;

public interface WorkDAO extends PagingAndSortingRepository<Work, String>,JpaSpecificationExecutor<Work>{

	//查询所有数据的方法
	@Query("from work w order by w.id asc")
	List<Work> findAll();//findAll方法有内置的,这里写sql语句是刚开始学的时候用的。而且这里用的sql语句已经不是原生的sql语句了,原生的sql语句写法见表连接方法
	//模糊查询  findBy**Like*(参数)是内置的方法,**代表字段名,详细的介绍我有一篇单独的博客,可以参考一下
	List<Work> findByidLike(String id);
	//通过tell字段名进行精确查询,效果跟下面的sql相同
	//原生sql:select * from work where tell = ?
	List<Work> findBytell(String tell);
	//修改,因为要数据回显,所以要有一个单独的方法查询,返回值是Work,根据id查询
	Work findByid(String id);
	//表连接,实属无奈,不会,只能用sql语句了,还是用原生的。在最后加上那个,就是代表的原生sql cla是我的另一个表
	@Query(value="select * from work w join cla c on w.cla = c.cid",nativeQuery = true)
	List<Map> findAllData();//表连接返回值是list!!!
	//分页,这里的findAll参数跟上面的findAll参数不同,所以问题不大。返回值是page的findAll方法也是有内置的,但是没用过,当时时间不充足,没时间试,就写了sql语句
	//@Query("from work w order by w.id asc")
	Page<Work> findAll(Pageable page);
	//分页表连接
	@Query(value="select * from work w join cla c on w.cla = c.cid",nativeQuery = true)
	Page<List<Map>> findAllMap(Pageable page);
}


## **继承DAO service部分代码**
这里有两个注解,记得写上。
其他没什么要注意的了

```java
package com.example.service;

import java.util.List;

import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.example.dao.WorkDAO;
import com.example.stu.Work;

@Service
public class WorkService {
	@Autowired
	//查询全部
	private WorkDAO workDAO;
	public List<Work> findAll(){
		return workDAO.findAll();
	}
	public List<Map> findAllData(){
		return workDAO.findAllData();
	}
	//根据id查询
	public Work findId(String id){
		return workDAO.findByid(id);
	}
	//模糊查询
	public List<Work> findByIdLike(String id){
		return workDAO.findByidLike(id);
	}
	//添加
	public void save(Work work) {
		workDAO.save(work);
	}
	//验证手机号唯一
	public List<Work> findBytell(String tell){
		return workDAO.findBytell(tell);
	}
	//删除
	public void del(Work work) {
		workDAO.delete(work);
	}
	//分页
	public Page<Work> findpage(Pageable page){
		return workDAO.findAll(page);
	}
	//分页表连接
	public Page<List<Map>> findAllMap(Pageable page){
		return workDAO.findAllMap(page);
	}
}

重点 controller代码

这里我把导入的包先单独放一块了,分页要导入的包自己注意下,别导错了

package com.example.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;//分页
import org.springframework.data.domain.PageRequest;//分页
import org.springframework.data.domain.Pageable;//分页
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.service.ClaService;
import com.example.service.WorkService;
import com.example.stu.Cla;
import com.example.stu.Work;






@Controller
@RequestMapping("work")//应该可以解释为给以下内容起个名字
public class WorkController {
	@Autowired
	private WorkService workService;
	@Autowired
	private ClaService claService;
	/**
	 * @param 首页模块
	 * @return 首页
	 */
	@RequestMapping(value = "index")//给当前的方法起名字,调用的时候是work/index
	//这里是向html首页映射值的部分,还是映射了两个值,映射一个的话就省略一块就行
	public String index(Model model) {//model就是向模板映射的方法
		//传work
		List<Work> data = workService.findAll();
		model.addAttribute("data", data);//向模板映射值
		//传cla,这里是传的另一个表的数据,需要在同目录下新建entiy、dao、service什么的,我就不列出来了,下面的方法我没有写出来
		List<Cla> list = claService.findAll();
		model.addAttribute("list", list);
		return "/workIndex";//返回值是返回到首页,workindex是首页文件名,没有后缀是我提前在其他地方改好了,你没有改的话就写workindex.html。在stringBoot中,貌似不能直接打开html/jsp文件,只能通过controller中的方法来调用html/jsp文件。所以说在这要打开html文件的话用localhost:8080/work/index就可以了。index是注解中的index
	}
	/**
	 * @param 表连接向模板映射值
	 */
	 //这个跟上一个功能相同,都是向首页映射值,不过下面的是用表连接写,只能用其中一个,首页中我是接收的这个映射的值。(boss规定要用表连接,而且表连接方便后期修改)
	@RequestMapping(value = "indexAll")
	public String indexAll(Model model) {
		List<Map> list = workService.findAllData();
		model.addAttribute("data", list);
		return "/workIndex";
	}
	/**
	 * @prarm 添加模块
	 * @return 重定向返回首页模块
	 */
	//添加主体
	@RequestMapping("add")
	public String add(Model model) {
	//这里的这部分是向添加页面映射可选的班级有哪些,没有添加功能
		List<Cla> list = new ArrayList<Cla>();
		list = claService.findAll();
		model.addAttribute("data", list);
		return "/workAdd";
	}
	//添加功能在以下代码块实现
	@RequestMapping("save")
	public String save(HttpServletRequest req,Model model) {
		//获取值
		String id = req.getParameter("id");
		String ho[] = req.getParameterValues("hobby");//接收过来是数组的形式,然后用下面注释的那句转字符串格式,如果接收的是字符串,就没必要转,算是个例子
		//String province = StringUtils.join(pro,"|");
		String hobby = StringUtils.join(ho,"、");
		String intro = req.getParameter("intro");
		//赋值,这里字段名太多了,我删了几个,跟上面的对不起来页正常
		Work work = new Work();
		work.setId(id);
		work.setTell(tell);	
		//调用添加方法
		workService.save(work);//上面的基本都是废话,接收值和设置值的,只有这一步才是真正的实现添加功能
		//返回首页模块
		return "redirect:/work/indexAll";//redirect是重定向,不需要也不能导包,导了就报错。
	}
	/**
	 * @param 验证手机号唯一
	 * @return boolean
	 */
	 //规定的功能,没需求的话完全可以不写,就当是一个精确查询的模块
	@RequestMapping("tell")
	@ResponseBody
	public boolean tell(HttpServletRequest req) {
		String tell = req.getParameter("tell");
		List<Work> list = new ArrayList<Work>();
		list = workService.findBytell(tell);
		if(list.size()>0) {
			//>0查询到数据,不可以注册
			return false;
		}else {
			return true;
		}
	}
	
	/**
	 * @param 删除模块
	 * @return 重定向返回主页模块
	 */
	 //最喜欢删除模块了,简单直接,只需要传一个id就可以根据id进行删除,根据其他删除也类似
	@RequestMapping("del")
	public String del(HttpServletRequest req) {
		String id[] = req.getParameterValues("id");
		for(int i=0; i<id.length; i++) {
			Work work = new Work();
			work.setId(id[i]);
			workService.del(work);
		}
		return "redirect:/work/indexAll";
	}
	/**
	 * @param 修改模块
	 * @return 重定向返回主页模块
	 */
	//获取需要修改的那条的信息,映射的到修改页面,然后调用添加方法。添加方法规定id将新内容替换原来的内容,不规定id,就是普通的添加,规定新的id,也是添加
	//向模板映射值后,点击添加,调用save方法,进行添加。修改的方法跟添加共用一个save方法。一定要注意修改时id的接收情况,不然有可能会成添加
	@RequestMapping("findId")
	public String findId(HttpServletRequest req,Model model) {
		String id =req.getParameter("id");
		Work work = new Work();
		work = workService.findId(id);
		model.addAttribute("data",work);

		List<Cla> list = new ArrayList<Cla>();
		list = claService.findAll();
		model.addAttribute("list", list);
		return "/workExis";
	}

//分页
//分页是vue里面的,我给了他一个单独的index页面,因为这个不懂,所以就不写太多注释了
	//调用首页
	@RequestMapping("VueIndex")
	public String VueIndex() {
		return "/VueWorkIndex";//这个是分页的首页文件名
	}

@RequestMapping("VuePage")
	@ResponseBody
	public Page<List<Map>> VuePage(HttpServletRequest req){//这里一定要注意导的包是哪个;返回值是page类型的,里面的list是为了满足表连接的需求才写的,不需要的可以直接写page<实体名>
		//NowPage=0;
		Integer NowPage = Integer.parseInt(req.getParameter("page"));//获取当前页
		Sort sort = null;
		sort = new Sort(Sort.Direction.DESC,"id");//根据id进行排序
		Pageable Page = PageRequest.of(NowPage-1, 4, sort);//每四条数据为一页,这里为什么-1我也不知道,是自己试出来的,不-1出问题
		Page<List<Map>> data = workService.findAllMap(Page);
		return data;
}
}

前端代码,首页信息接收(无分页,分页在最下面)

这里的前端代码包含了全选效果,没必要的字段名都删了,表格对齐情况可能有点问题,自己使用的时候小细节修改一下


<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
script>
<script type="text/javascript">
$(function() {
	var i=false;
	//全选操作
	$("#all").on("click",function(){
		if(i==false){
			$("input[name='id']").prop("checked",true);
			i=true;
		}else{
			$("input[name='id']").prop("checked",false);
			i=false;
		}
	});
	
	//反选操作
	$("#Rev").on("click",function(){
		$("[type=checkbox]:checkbox").each(function() {
	        this.checked = !this.checked;
	        i=!i;
	    });
	});

	//全不选操作
	$("#allNot").on("click",function(){
			$("input[name='id']").prop("checked",false);
			i=false;
	});
	

});

//批量删除判断数据量
function del() {
	
	var j=0;
	$("[type=checkbox]:checkbox").each(function() {
		
      if(this.checked ==true ){
      	j++;
      }
      
  });
	if(j>=1){
      	return true;
      }else{
      	alert("至少选择一项内容");
      	return false;
      	
      }
}
script>

head>
<body>
<br />

<form action="del">
<table border="1" width="990px" cellspacing="0" cellpadding="5px" align="center" style="transparent;background-color:rgba(199,237,204,0.45)">

<tr>
	<td colspan="9">信息添加:  <a href="/work/add"><input type="button" value="添加"/>a>
	td>
tr>
<tr>
	<td colspan="9">批量操作:  
		<input type="submit" onclick="return del()" value="批量删除">
		    
		
		    
		
		    
		
	td>
tr>
	
	

<tr>
	<th width="60px">编号th>
	<th width="120px">账号th>

	<th width="350px">简介th>
	<th width="120px">操作th>
tr>

<tr th:each="work,loopStatus:${data}">
	
	<td align="center">
		<span th:text="${loopStatus.count}" >span>
		<span>span><input type="checkbox" name="id" th:value="${work.id}"> span>
	td>

	
	<td align="center" th:text="${work.province+','+work.city+','+work.area}">td>
	<td align="center" th:text="${work.hobby}">td>
	<td align="center" th:text="${work.intro}">td>
	<td align="center">
		<a th:href="@{findId(id=${work.id})}">
			<input type="button" value="修改" />a>
			
		<a th:href="@{del(id=${work.id})}">
		<input type="button" value="删除" />a>
	td>
tr>
table>
form>
body>
html>

添加页

有判断唯一性的(ajax)、省市级三级联动效果(自己百度的代码,直接复制上了)


<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
script>
<script type="text/javascript">
$(function () {
	
	//AJAX判断手机号唯一性
	$("#tell").keyup(function() {
		//获取输入的tell值
		//alert(2);
		var tell = $("#tell").val();
		//alert(tell);
		$.post("/work/tell",{tell:tell},function(data){
			//alert(data);
			if(tell != null){
				//接收到的data为Boolean型
				if(data){
					$("#text").html("  可以注册");
					$("#submit").attr('disabled',false);
				}else{
					$("#text").html("  重复,禁止注册");
					$("#submit").attr('disabled',true);
				}
			}
		});
	});
});
script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js">script>
<script src="https://cdn.bootcss.com/distpicker/2.0.1/distpicker.js">script>
head>
<body>
<br /><br />
<table border="1" cellspacing="0" cellpadding="5px" width="700px" align="center" >
<tr>
<td>
<form action="/work/save">

手机号:<input type="text" id="tell" name="tell"><span id="text">span><br /><br />    名:<input type="text" name="name"><br /><br />    级:
	<select name="cla" >
		<option  th:each="cla:${data}" th:value="${cla.cid}" th:text="${cla.cname}">option>
	select><br /><br />
    别:<input type="radio" name="sex" value="">  <input type="radio" name="sex" value=""><br /><br />

<div data-toggle="distpicker" data-autoselect="3">    址:
<select name="province">select>
<select name="city">select>
<select name="area">select>
div><br /><br />
    好:<input type="checkbox" value="代码" name="hobby">代码  
				<input type="checkbox" value="游戏" name="hobby">游戏  
				<input type="checkbox" value="音乐" name="hobby">音乐  <br /><br />
    介:<textarea rows="5" cols="35" name="intro" style=resize:none;>textarea><br /><br />
    <input type="submit" value="提交"><br />
form>
td>
tr>
table>
body>
html>

删除页

没有代码,直接在首页点删除,就直接删除了,没有什么多余的花里胡哨的代码

修改页

最烦的就是修改页了,代码多,花里胡哨的
实现效果:验证手机号是否唯一,文本域数据回显、单选框数据回显
bug:多选框、省市级三级联动(有自带的默认显示)没能实现数据回显;手机号部分,输入数据后,清空数据会提示可以注册/不能注册

<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
script>
<script type="text/javascript">
$(function () {
	//AJAX判断手机号唯一性
	$("#tell").keyup(function() {
		//获取输入的tell值
		//alert(2);
		var tell = $("#tell").val();//获取输入的tell
		//alert(tell);
		//将获取的tell传给controller,看返回值
		$.post("/work/tell",{tell:tell},function(data){
			//alert(data);
			if(tell != null){
				if(data){//接收到的data为Boolean型
					$("#text").html("  可以注册");
					$("#submit").attr('disabled',false);
				}else{
					$("#text").html("  重复,禁止注册");
					$("#submit").attr('disabled',true);
				}
				
			}
		});
	});
});
script>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js">script>
<script src="https://cdn.bootcss.com/distpicker/2.0.1/distpicker.js">script>

head>
<body>

<br /><br />
<table border="1" cellspacing="0" cellpadding="5px" width="700px" align="center">
<tr>
<td>
<form action="/work/save" method="post" th:object="${data}">

手机号:<input type="text" id="tell" name="tell"  th:value="*{tell}" placeholder="十个数以内"><span id="text">span><br /><br />

<input type="hidden" name="id" th:value="*{id}">    名:<input type="text" name="name" th:value="*{name}"><br /><br />    级:
	<select name="cla" >
		<option  th:each="cla:${list}" th:attr="selected=${data.cla==cla.cid?true:selected}" th:value="${cla.cid}" th:text="${cla.cname}" >option>
	select>
<br /><br />    别:
	<input type="radio" name="sex" value="" th:attr="checked=${data.getSex()==''?true:false}">  
	<input type="radio" name="sex" value="" th:attr="checked=${data.getSex()==''?true:false}"><br /><br />

<div data-toggle="distpicker" data-autoselect="3">    址:
<select name="province" th:text="${province}">select>
<select name="city" th:text="*{city}">select>
<select name="area" th:text="*{area}">select>
div><br /><br />    好:
				代码<input type="checkbox" value="代码" name="hobby">  
				游戏<input type="checkbox" value="游戏" name="hobby">  
				音乐<input type="checkbox" value="音乐" name="hobby">  <br /><br />
    介:<textarea rows="5" cols="35" th:text="${data.intro}" name="intro" style=resize:none; >textarea><br /><br />
<input type="submit" value="提交">
form>
td>
tr>
table>
body>
html>

分页index

分页index


<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js">script>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">script>


<style type="text/css">
.page-bar{margin:40px auto;margin-top: 150px;}
ul,li{margin: 0px;padding: 0px;}
li{list-style: none}
.page-bar li:first-child>a {margin-left: 0px}
.page-bar a{border: 1px solid #ddd;text-decoration: none;position: relative;float: left;padding: 6px 12px;margin-left: -1px;line-height: 1.42857143;color: #5D6062;cursor: pointer;margin-right: 20px;}
.page-bar a:hover{background-color: #eee;}
.page-bar a.banclick{cursor:not-allowed;}
.page-bar .active a{color: #fff;cursor: default;background-color: #E96463;border-color: #E96463;}
.page-bar i{font-style:normal;color: #d44950;margin: 0px 4px;font-size: 12px;}
style>
head>
<body>
	<br />
	<table border="1" width="990px" cellspacing="0" cellpadding="5px"
		align="center" style="background-color: rgba(199, 237, 204, 0.45)"
		id="app">
		<tr>
			<td colspan="10">
				
<div class="page-bar">
<ul>
<li v-if="cur>1"><a v-on:click="cur--,pageClick()">上一页a>li>
<li v-if="cur==1"><a class="banclick">上一页a>li>
<li v-for="index in indexs" v-bind:class="{ 'active': cur == index}">
<a v-on:click="btnClick(index)">{{ index }}a>
li>
<li v-if="cur!=all"><a v-on:click="cur++,pageClick()">下一页a>li>
<li v-if="cur == all"><a class="banclick">下一页a>li>
<li><a><i>{{all}}i>a>li>
ul>
div>
			td>
		tr>
		<tr>
			<th width="60px">编号th>
			<th width="120px">账号th>
			<th width="90px">姓名th>

			<th width="240px" colspan="2">操作th>
		tr>
		<tr v-for="(site,key) in sites">
			<td align="center">{{key+1}}td>
			<td align="center">{{site.tell}}td>
			<td align="center">{{site.name}}td>
			<td align="center">{{site.cname}}td>ype="button"
					value="删除">a>td>
			<td><a v-on:click="edit(site.id)"><input type="button"
					value="修改">a>td>
		tr>
	table>

	<script>
	var vm = new Vue({
		el: '#app',
		data:{
			sites:[],
			all:6,
			cur:1,
			totalPage:0
		},
		mounted(){
			this.dataListFn(1);
		},
		methods:{
			dataListFn:function(index){
				var page = index;
				//alert(page);
				$.post("/work/VuePage",{page:page},function(data){
					//alert(12);
					vm.sites=[];
					//var datalist=data.contene;
					//alert(JSON.stringify(data.content));//接收数据成功
					var len = data.content.length;
					for(var i=0;i<len;i++){
						vm.sites.push(data.content[i]);
					}
					vm.all = data.totalPages;
					vm.cur = data.number+1;
					vm.totalPage = data.numberOfElements;	
				});	
			},
			//要注意其他方法写的位置,位置不合适会报错not find,我也是试了很多地方才找到这里的
			del:function(id,key){
				$.post("/work/VueDel",{id,id},function(data){
					if(data==1){
						vm.sites.splice(key,1);
					}
				});
			},
			edit:function(id,key){
				window.location.href="/work/VueEdit?id="+id;
			},
			add:function(){
				window.location.href="/work/add";
			},
			//分页
			btnClick: function(data){//页码点击事件
				if(data != this.cur){
					this.cur = data
				}
				//根据点击页数请求数据
				this.dataListFn(this.cur.toString());
			},
			pageClick: function(){
				//根据点击页数请求数据
				this.dataListFn(this.cur.toString());
			}
		},
		computed: {
		//分页
			indexs: function(){
				var left = 1;
				var right = this.all;
				var ar = [];
				if(this.all>= 5){
					if(this.cur > 3 && this.cur < this.all-2){
						left = this.cur - 2
						right = this.cur + 2
					}else{
						if(this.cur<=3){
							left = 1
								right = 5
						}else{
							right = this.all
							left = this.all -4
						}
					}
				}
				while (left <= right){
				ar.push(left)
				left ++
			}
				return ar
			}
		},
		
		
	});
script>
body>
html>

你可能感兴趣的:(java)