SpringBootWeb案例
前端web开发:
技术 | 描述 |
---|---|
HTML | 用于构建网站的基础结构的 |
css | 用于美化页面的,作用和化妆或者整容作用一样 |
JavaScript | 实现网页和用户的交互 |
Vue | 主要用于将数据填充到html页面上的 |
Element | 主要提供了一些非常美观的组件 |
Nginx | 一款web服务器软件,可以用于部署我们的前端工程 |
后端web开发:
技术 | 描述 |
---|---|
Maven | 一款java中用于管理项目的软件 |
Mysql | 最常用的一款数据库软件之一 |
SpringBoot | spring家族的产品,当前最为主流的项目开发技术。 |
Mybatis | 用于操作数据库的框架 |
1.准备工作
mybatis实施前的准备工作:
- 准备数据库表
- 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)
- application.properties中引入数据库连接信息
- 创建对应的实体类 Emp(实体类属性采用驼峰命名)
- 准备Mapper接口 EmpMapper
1.准备数据库表
2.创建springboot工程,引入对应起步依赖(web,mybatis,mysql驱动,lombok)
3.配置文件application.properties中引入mybatis的配置信息,准备对应的实体类
4.准备对应的Mapper,Service(接口,实现类),Controller基础结构
之前知识的重点回顾
HTML(结构)CSS(表现)
杂糅案例,包含大部分内容
<html>
<head>
<title>HTML</title>
<!-- 方式二: 内嵌样式 -->
<style>
h1 {}/*选中了所有h1标签*/
span {}/* 元素选择器 */
.cls {}/* 类选择器 */
#time {}/* ID选择器 */
a {}/*选中所有超链接*/
div {}/*盒子模型*/
td {
text-align: center; /* 单元格内容居中展示 */
}
</style>
<!-- 方式三: 外联样式 -->
<link rel=".css">
</head>
<body>
<h1>Hello HTML</h1>
<span class="cls" id="time">2023年03月02日 21:50</span>
<span class="cls">央视网</span>
<img src="照片路径" width="80%" >
<a href="http...." target="_self">新浪政务</a>
/*target属性 _self页面跳转 _blank新页面 _parent _top*/
<hr>//水平分页线标签
<table border="1px" cellspacing="0" width="600px">
<tr>
<th>序号</th>
<th>品牌Logo</th>
<th>品牌名称</th>
<th>企业名称</th>
</tr>
<tr>
<td>1</td>
<td> <img src="img/huawei.jpg" width="100px"> </td>
<td>华为</td>
<td>华为技术有限公司</td>
</tr>
<tr>
<td>2</td>
<td> <img src="img/alibaba.jpg" width="100px"> </td>
<td>阿里</td>
<td>阿里巴巴集团控股有限公司</td>
</tr>
</table>
<form action="表单提交地址" method="get">/*get拼在当前地址后面 post请求体携带*/
用户名: <input type="text" name="username">
<input type="submit" value="提交">/*表单项,下面有*/
</form>
</body>
</html>
表单项
<input>: 表单项 , 通过type属性控制输入形式。
type取值 | 描述 |
---|---|
text | 默认值,定义单行的输入字段 |
password | 定义密码字段 |
radio | 定义单选按钮 |
checkbox | 定义复选框 |
file | 定义文件上传按钮 |
date/time/datetime-local | 定义日期/时间/日期时间 |
number | 定义数字输入框 |
定义邮件输入框 | |
hidden | 定义隐藏域 |
submit / reset / button | 定义提交按钮 / 重置按钮 / 可点击按钮 |
-
<select>: 定义下拉列表, <option> 定义列表项
-
<textarea>: 文本域
JavaScript(行为)
引入1:JavaScript代码必须位于<script></script>标签之间,一般放在body下面
引入2:注意:demo.js中只有js代码,没有<script>标签
<script src="js/demo.js"></script>
js中3钟输出语句
api | 描述 |
---|---|
window.alert() | 警告框 |
document.write() | 在HTML 输出内容 |
console.log() | 写入浏览器控制台 |
变量
关键字 | 解释 |
---|---|
var | 早期ECMAScript5中用于变量声明的关键字 |
let | ECMAScript6中新增的用于变量声明的关键字,相比较var,let只在代码块内生效 |
const | 声明常量的,常量一旦声明,不能修改 |
数据类型
数据类型 | 描述 |
---|---|
number | 数字(整数、小数、NaN(Not a Number)) |
string | 字符串,单双引皆可 |
boolean | 布尔。true,false |
null | 对象为空 |
undefined | 当声明的变量未初始化时,该变量的默认值是 undefined |
函数
<script>
//定义函数-1
// function add(a,b){
// return a + b;
// }
//定义函数-2
var add = function(a,b){
return a + b;
}
//函数调用
var result = add(10,20);
alert(result);
</script>
基本对象
Array数组
var shuzu = new Array(1,2,3);/数组Array/
var shuzu = [1,2,3,4];
shuzu.length/数组的长度属性/
方法:
方法方法 | 描述 |
---|---|
forEach() | 遍历数组中的每个有值得元素,并调用一次传入的函数 |
push() | 将新元素添加到数组的末尾,并返回新的长度 |
splice() | 从数组中删除元素 |
var arr = [1,2,3,4];
arr[10] = 50;
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);//控制台展示
}
String字符串
var str = new String("Hello String");
var str = 'Hello String';
str.length/*字符串长度*/
方法:
方法 | 描述 |
---|---|
charAt() | 返回在指定位置的字符。 |
indexOf() | 检索字符串。 |
trim() | 去除字符串两边的空格 |
substring() | 提取字符串中两个指定的索引号之间的字符。 |
JSON对象
那么json这种数据格式的文本经常用来作为前后台交互的数据载体
自定义对象
<script>
//自定义对象
var user = {
name: "Tom",
age: 10,
gender: "male",
eat: function(){
console.log("用膳~");
}
}
console.log(user.name);
user.eat();
<script>
json
var jsonstr = '{"name":"Tom", "age":18, "addr":["北京","上海","西安"]}';
var obj = JSON.parse(jsonstr);
alert(obj.name);/*不能直接jsonsrr.name直接输出*/
BOM对象
对象名称 | 描述 |
---|---|
Window | 浏览器窗口对象 |
Navigator | 浏览器对象 |
Screen | 屏幕对象 |
History | 历史记录对象 |
Location | d地址栏对象 |
window对象提供了获取其他BOM对象的属性: |
属性 | 描述 |
---|---|
history | 用于获取history对象 |
location | 用于获取location对象 |
Navigator | 用于获取Navigator对象 |
Screen | 用于获取Screen对象 |
Window
函数 | 描述 |
---|---|
alert() | 显示带有一段消息和一个确认按钮的警告框。 |
comfirm() | 显示带有一段消息以及确认按钮和取消按钮的对话框。 |
setInterval() | 按照指定的周期(以毫秒计)来调用函数或计算表达式。 |
setTimeout() | 在指定的毫秒数后调用函数或计算表达式。 |
var flag = confirm("您确认删除该记录吗?");
alert(flag);
var i = 0;
setInterval(function(){
i++;
console.log("定时器执行了"+i+"次");
},2000);
setTimeout(function(){
alert("JS");
},3000);
Location对象
//获取浏览器地址栏信息
alert(location.href);
//设置浏览器地址栏信息
location.href = "https://www.itcast.cn";
//根据函数通过判断来决定跳转,超链接是点了就跳
DOM对象
作用如下:
- 改变 HTML 元素的内容
- 改变 HTML 元素的样式(CSS)
- 对 HTML DOM 事件作出反应
- 添加和删除 HTML 元素
HTML 文档是浏览器解析。封装的对象分为
- Document:整个文档对象
- Element:元素对象
- Attribute:属性对象
- Text:文本对象
- Comment:注释对象
document对象提供的用于获取Element元素对象的api如下表所示:
函数 | 描述 |
---|---|
document.getElementById() | 根据id属性值获取,返回单个Element对象 |
document.getElementsByTagName() | 根据标签名称获取,返回Element对象数组 |
document.getElementsByName() | 根据name属性值获取,返回Element对象数组 |
document.getElementsByClassName() | 根据class属性值获取,返回Element对象数组 |
常见事件
事件属性名 | 说明 |
---|---|
onclick | 鼠标单击事件 |
onblur | 元素失去焦点 |
onfocus | 元素获得焦点 |
onload | 某个页面或图像被完成加载 |
onsubmit | 当表单提交时触发该事件 |
onmouseover | 鼠标被移到某元素之上 |
onmouseout | 鼠标从某元素移开 |
<input type="button" value="全选" onclick="checkAll()">
/*点击按钮就执行checkAll函数*/
Vue
创建
1.vs code里创建一个.html文件,同级再建一个js目录,导入vue.js文件
2.编写<script>标签来引入vue.js文件
3.在js代码区域定义vue对象,代码如下:
4.html区域编写视图,其中{{}}是插值表达式,用来将vue对象中定义的model展示到页面上的
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue-快速入门</title>
<script src="js/vue.js"></script>//1.引入文件
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
</body>
<script>
//定义Vue对象
new Vue({
el: "#app", //vue接管区域
data:{
message: "Hello Vue"
}
})
</script>
</html>
vue属性:
- el: 用来指定哪儿些标签受 Vue 管理。 该属性取值
#app
中的app
需要是受管理的标签的id属性值 - data: 用来定义数据模型
- methods: 用来定义函数。这个我们在后面就会用
vue指令
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置 href , css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-else | |
v-else-if | |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
v-bind v-model
<a v-bind:href="url" target="_blank">链接1</a>
<input type="text" v-model="url">
只有表单项标签!所以双向绑定一定是使用在表单项标签上的
双向绑定的作用:可以获取表单的数据的值,然后提交给服务器
v-on
<input onclick="demo()"> //js,类似内嵌式
<input v-on:click="demo()"> //vue,类似外联式
v-if和v-show
指令 | 描述 |
---|---|
v-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-if-else | |
v-else | |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
<span v-if="age <= 35">年轻人(35及以下)</span>
<span v-show="age <= 35">年轻人(35及以下)</span>
v-for
<标签 v-for="(变量名,索引变量) in 集合模型数据">
<!--索引变量是从0开始,所以要表示序号的话,需要手动的加1-->
{{索引变量 + 1}} {{变量名}}
</标签>
<div id="app">
<div v-for="addr in addrs">{{addr}}</div>
<hr>
<div v-for="(addr,index) in addrs">{{index + 1}} : {{addr}}</div>
</div>
生命周期(钩子函数)
状态 | 阶段周期 |
---|---|
beforeCreate | 创建前 |
created | 创建后 |
beforeMount | 挂载前 |
mounted | 挂载完成 |
beforeUpdate | 更新前 |
updated | 更新后 |
beforeDestroy | 销毁前 |
destroyed | 销毁后 |
<script>
//定义Vue对象
new Vue({
el: "#app", //vue接管区域
data:{
},
methods: {
},
mounted () {//钩子函数
//发送异步请求,加载数据
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
})
}
})
</script>
Axios
axios()是用来发送异步请求的
步骤
1.引入Axios文件
<script src="js/axios-0.18.0.js"></script>
2.使用Axios发送请求,并获取响应结果,官方提供的api很多,此处给出2种,如下
- 发送 get 请求
- 发送 post 请求
//通过axios发送异步请求-get
axios({
method: "get",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/list"
}).then(result => {
console.log(result.data);
})
//通过axios发送异步请求-post
axios({
method: "post",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/deleteById",
data: "id=1"
}).then(result => {
console.log(result.data);
})
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/axios-0.18.0.js"></script>
</head>
<body>
<input type="button" value="获取数据GET" onclick="get()">
<input type="button" value="删除数据POST" onclick="post()">
</body>
<script>
function get(){
//通过axios发送异步请求-get
}
function post(){
//通过axios发送异步请求-post
}
</script>
</html>
Maven
Maven项目的目录结构:
maven-project01
|--- src (源代码目录和测试代码目录)
|--- main (源代码目录)
|--- java (源代码java文件目录)
|--- resources (源代码配置文件目录)
|--- test (测试代码目录)
|--- java (测试代码java目录)
|--- resources (测试代码配置文件目录)
|--- target (编译、打包生成文件存放目录)
环境配置步骤:
全局/文件/设置/构建、执行、部署/构建工具/Maven/运行程序()/编译器/java编译器/字节码版本
导入maven项目 jar包
Springboot
Spring Boot 可以帮助我们非常快速的构建应用程序、简化开发、提高效率 。
步骤
1.创建springboot工程,并勾选web开发相关依赖
IDEA/文件/新建/模块/Spring Boot/ 改名什么的/确认
依赖项/Spring Boot 3.4.0(最新稳定版本)/Web/Spring Web/创建
2.定义HelloController类,添加方法hello,并添加注释,然后启动。
src/main/java/在自动创建的软件包里新建一个包(control)包下放置相关请求处理类/找到启动类启动/浏览器输入网址localhost:8080/hello( @RequestMapping("/hello")//网址)
起步依赖
spring-boot-starter-web:包含了web应用开发所需要的常见依赖
- spring-boot-starter-test:包含了单元测试所需要的常见依赖
Spring的官方提供了很多现成的starter(起步依赖),我们在开发相关应用时,只需要引入对应的starter即可。
springboot
springbootweb创建步骤
1.创建springboot工程,并勾选web开发相关依赖
IDEA/文件/新建/模块/Spring Boot/ 改名什么的/确认
依赖项/Spring Boot 3.4.0(最新稳定版本)/Web/Spring Web/创建
请求
@RestController
public class RequestController {
@RequestMapping("/simpleParam")
public String simpleParam(String name , Integer age ){//形参名和请求参数名保持一致}
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){//数组
System.out.println(Arrays.toString(hobby));
return "OK";}
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){//日期
System.out.println(updateTime);
return "OK";}
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){//JSON参数
System.out.println(user);
return "OK";}
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){路径参数
System.out.println(id);
return "OK";}
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id, @PathVariable String name){//多个路径
System.out.println(id+ " : " +name);
return "OK";}
}
**也能调用pojo里面的实体参数(user)**
定义POJO实体类:
```java
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
```
###响应
###统一响应结果
```java
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应码 描述字符串
private Object data; //返回的数据
public Result() { }
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
//增删改 成功响应(不需要给前端返回数据)
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应(把查询结果做为返回数据响应给前端)
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
```
~~~java
@RestController
public class ResponseController {
//响应统一格式的结果
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello World ~");
//return new Result(1,"success","Hello World ~");
return Result.success("Hello World ~");
}
//响应统一格式的结果
@RequestMapping("/getAddr")
public Result getAddr(){
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
return Result.success(addr);
}
//响应统一格式的结果
@RequestMapping("/listAddr")
public Result listAddr(){
List<Address> list = new ArrayList<>();
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
Address addr2 = new Address();
addr2.setProvince("陕西");
addr2.setCity("西安");
list.add(addr);
list.add(addr2);
return Result.success(list);
}
}
分层解耦
三层架构
代码拆分
- Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
- Service:业务逻辑层。处理具体的业务逻辑。
- Dao:数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查。
完整的三层代码:
- Controller层:
@RestController
public class EmpController {
@Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
private EmpService empService ;
@RequestMapping("/listEmp")
public Result list(){
//1. 调用service, 获取数据
List<Emp> empList = empService.listEmp();
//3. 响应数据
return Result.success(empList);
}
}
- Service层:
@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpServiceA implements EmpService {
@Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
private EmpDao empDao ;
@Override
public List<Emp> listEmp() {
//1. 调用dao, 获取数据
List<Emp> empList = empDao.listEmp();
//2. 对数据进行转换处理 - gender, job
empList.stream().forEach(emp -> {
//处理 gender 1: 男, 2: 女
String gender = emp.getGender();
if("1".equals(gender)){
emp.setGender("男");
}else if("2".equals(gender)){
emp.setGender("女");
}
//处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
}else if("2".equals(job)){
emp.setJob("班主任");
}else if("3".equals(job)){
emp.setJob("就业指导");
}
});
return empList;
}
}
Dao层:
@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp() {
//1. 加载并解析emp.xml
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
}
}
IOC&DI
IOC详解
bean
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一:
注解 | 说明 | 位置 |
---|---|---|
@Controller | @Component的衍生注解 | 标注在控制器类上 |
@Service | @Component的衍生注解 | 标注在业务类上 |
@Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) |
@Component | 声明bean的基础注解 | 不属于以上三类时,用此注解 |
在IOC容器中,每一个Bean都有一个属于自己的名字,可以通过注解的value属性指定bean的名字。如果没有指定,默认为类名首字母小写。
注意事项:
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
数据库(另看MySQL全集吧)
Mybatis
- MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。
- 持久层:指的是就是数据访问层(dao),是用来操作数据库的。
- 框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。
Mybatis操作数据库的步骤
- 准备工作(创建springboot工程、数据库表user、实体类User)
创建springboot工程,并导入 mybatis的起步依赖、mysql的驱动包。
菜单 新建 模块 springboot(配置好名字什么的) 下一步
SQL 点上MyBatis Framework和MySOL Driver 创建
- 引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)
在Mybatis中要连接数据库,需要以下4个参数配置(和数据库连接一样)
- MySQL驱动类
- 登录名
- 密码
- 数据库连接字符串
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234
- 编写SQL语句(注解/XML)
在创建出来的springboot工程中,在引导类所在包下,在创建一个包 mapper。
在mapper包下创建一个接口 UserMapper
这是一个持久层接口(Mybatis的持久层接口规范一般都叫 XxxMapper)。
UserMapper:
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
//查询所有用户数据
@Select("select id, name, age, gender, phone from user")
public List<User> list();
}
@Mapper注解:表示是mybatis中的Mapper接口
- 程序运行时:框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理
@Select注解:代表的就是select查询,用于书写select查询语句
简化代码Lombok
import lombok.Data;
@Data //包含getter方法、setter方法、toString方法、hashCode方法、equals方法
@NoArgsConstructor //无参构造
@AllArgsConstructor//全参构造
public class User {
private Integer id;
private String name;
private Short age;
private Short gender;
private String phone;
}
Lombok的注意事项:
- Lombok会在编译时,会自动生成对应的java代码
- 在使用lombok时,还需要安装一个lombok的插件(新版本的IDEA中自带)
功能
@Mapper
public interface EmpMapper {//**删除**
@Delete("delete from emp where id = #{id}")//使用#{key}方式获取方法中的参数值
public void delete(Integer id);
public interface EmpMapper {//**增加**
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
public void insert(Emp emp);
}
public interface EmpMapper {//**主键返回**
//会自动将生成的主键值,赋值给emp对象的id属性
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
public void insert(Emp emp);}
public interface EmpMapper {//**改**
@Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image}, job=#{job}, entrydate=#{entrydate}, dept_id=#{deptId}, update_time=#{updateTime} where id=#{id}")
public void update(Emp emp);}
public interface EmpMapper {//**查**
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
public Emp getById(Integer id);
}
如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写,如:#{id}、#{value}。但是建议保持名字一致。
XML配置文件实现
第1步:创建XML映射文件
第2步:编写XML映射文件
xml映射文件中的dtd约束,直接从mybatis官网复制即可
配置:XML映射文件的namespace属性为Mapper接口全限定名
配置:XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--查询操作-->
<select id="list"//list是方法名 resultType="com.itheima.pojo.Emp">
select * from emp
where name like concat('%',#{name},'%')
and gender = #{gender}
and entrydate between #{begin} and #{end}
order by update_time desc
</select>
</mapper>
小事项(持续更新)
数据库方面
1.如何在navicat里使用SQL语句?
右键数据库 命令行界面