目录
1 创建webapp结构
打开如图所示的idea界面
找到archetype下的webapp,点击,next
再编写包命名以及存放路径
再点finish
然后会生成一些文件,像下面这样如果缺失了一些包的话去这里找
标准的是这样:
到此为止我们webapp结构就创建完毕了
2 导入坐标
在pom.xml里面导入需要的依赖
<dependency>
<!-- test测试依赖-->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<!-- mybatis依赖-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<!-- mysql驱动依赖-->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<!-- slf4j日志依赖-->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<!-- logback-classic日志依赖-->
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.7</version>
</dependency>
<dependency>
<!-- logback-core日志依赖-->
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.7</version>
<!-- servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp动态页面,我们暂且使用jsp作为前端-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependency>
同时我们还需要一个logback.xml
文件放到resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<logger name="cn.hoorus" level="DEBUG" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="DEBUG">
<appender-ref ref="Console"/>
</root>
</configuration>
运行处
由于我们之前没有导入tomcat&maven的坐标,所以需要在pom.xml
里面导一下(自带的几个功能可以删掉换成tomcat)
<build>
<!-- 下面这行是自己的项目名-->
<finalName>login_case</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
3 补全与配置
在resources下创建新文件mybatis.config.xml
然后从mybatis官网上找配置代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
然后需要自己改造
而这里的映射文件,需要我们后面再修改路径
现在补全Web文件夹
好的补完后我们开始编写实体类对象,在pojo里面新建一个User,里面使用快捷键alt+ins
来创建一些构造函数以及方法
package cn.calendo.pojo;
public class User {
private Integer id;
private String userName;
private String passWord;
private String userGender;
private String userAddress;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getUserGender() {
return userGender;
}
public void setUserGender(String userGender) {
this.userGender = userGender;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", passWord='" + passWord + '\'' +
", userGender='" + userGender + '\'' +
", userAddress='" + userAddress + '\'' +
'}';
}
}
配置包扫描映射xml,接下来是UserMapper.xml
映射文件,在resources下面创建对应文件夹,再把resources里面加上映射文件UserMapper.xml
然后再去mybatis-config.xml
里面修改UserMapper.xml
的位置坐标即可
这时候UserMapper.xml
会爆红,因为我们少了对应的映射接口,需要在mapper层里创建UserMapper.java
(这是一个接口类型的!因为我们在里面只写注解,映射以及方法名!)
然后我们回去发现UserMapper.xml
不爆红了
好了到此为止我们的结构都创建完毕了
4 编写前端(vue&element)
这里不多说,我们直接上代码(由于用了vue脚本和element组件所以需要自己从官网下载)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
</head>
<body>
<div id="app">
<!-- <!–搜索表单–>-->
<!-- <el-form :inline="true" :model="brand" class="demo-form-inline">-->
<!-- <el-form-item label="当前状态">-->
<!-- <el-select v-model="brand.status" placeholder="当前状态">-->
<!-- <el-option label="启用" value="1"></el-option>-->
<!-- <el-option label="禁用" value="0"></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="用户名称">-->
<!-- <el-input v-model="brand.companyName" placeholder="用户名称"></el-input>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="品牌名称">-->
<!-- <el-input v-model="brand.brandName" placeholder="品牌名称"></el-input>-->
<!-- </el-form-item>-->
<!-- <el-form-item>-->
<!-- <el-button type="primary" @click="onSubmit">查询</el-button>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!--按钮-->
<el-row>
<el-button type="danger" plain>批量删除</el-button>
<el-button type="primary" plain @click="(dialogVisible = true)" id="addUser">新增</el-button>
</el-row>
<!--添加数据对话框表单-->
<el-dialog
title="修改用户"
:visible.sync="dialogVisible"
width="30%"
ref="modify"
>
<el-form ref="form" :model="user" label-width="80px">
<el-form-item label="用户昵称">
<el-input v-model="user.userName"></el-input>
</el-form-item>
<el-form-item label="用户密码">
<el-input v-model="user.passWord"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-input v-model="user.userGender"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input type="textarea" v-model="user.userAddress"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="modify" v-if="remodify">修改</el-button>
<el-button type="primary" @click="addUser" v-if="readdUser">提交</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!--表格-->
<template>
<el-table
:data="tableData"
style="width: 100%"
:row-class-name="tableRowClassName"
@selection-change="handleSelectionChange"
>
<el-table-row
type="selection"
width="55">
</el-table-row>
<el-table-column
type="index"
width="50">
</el-table-column>
<el-table-column
prop="id"
label="唯一码"
align="center"
>
</el-table-column>
<el-table-column
prop="userName"
label="用户名称"
align="center"
>
</el-table-column>
<el-table-column
prop="passWord"
label="用户密码"
align="center"
>
</el-table-column>
<el-table-column
prop="userGender"
align="center"
label="性别">
</el-table-column>
<el-table-column
prop="userAddress"
align="center"
label="地址">
</el-table-column>
<el-table-column
align="center"
label="操作">
<template slot-scope="scope">
<el-button type="primary" @click="updateUser(scope.row)" id="modify">修改</el-button>
<el-button type="danger" @click="deleteById(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<!--分页工具条-->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="5"
layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
</div>
<script src="js/vue.js"></script>
<script src="element-ui/lib/index.js"></script>
<link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css">
<script src="js/axios-0.18.0.js"></script>
<!--<link rel="script" href="js/axios-0.18.0.js">-->
<script>
new Vue({
el: "#app",
mounted() {
//当页面加载完成后发生异步请求获取数据
this.selectAll();
},
methods: {
modify() {
// console.log(this.brand);
//发送ajax请求,添加数据
var _this = this;
axios({
method: "post",
url: "http://localhost:8080/login_case/User_UpdateServlet",
data: _this.user,
}).then(function (response) {
if (response.data === "success") {
//关闭窗口
_this.dialogVisible = false
//重新查询数据
_this.selectAll();
// 下面是element抬头显示
_this.$message({
message: '成功新增一条数据',
type: 'success'
});
} else {
_this.$message({
message: '新增失败!',
type: 'error'
});
}
})
},
updateUser(data) {
var _this = this;
// console.log(data.id);
axios({
method: "post",
url: "http://localhost:8080/login_case/User_SelectByIdServlet",
data: data.id,
}).then(function (response) {
if (response.data !== null) {
_this.dialogVisible = true
// response.data.userName
_this.user = response.data
// console.log(_this.data)
// console.log(response.data)
// console.log(_this.user)
} else {
_this.$message({
message: '出错了,请重试!',
type: "warning",
})
}
})
},
deleteById(data) {
var _this = this;
axios({
method: "post",
url: "http://localhost:8080/login_case/User_DeleteUserServlet",
data: data.id,
}).then(function (response) {
if (response.data === "success") {
_this.selectAll();
_this.$message({
message: '成功删除一条数据',
type: 'success'
});
} else {
_this.$message({
message: '删除失败!',
type: 'error'
});
}
})
},
selectAll() {
var _this = this;
axios({
method: "get",
url: "http://localhost:8080/login_case/User_SelectAllUserServlet",
}).then(function (response) {
_this.tableData = response.data;
})
},
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
},
// 复选框选中后执行的方法
handleSelectionChange(val) {
this.multipleSelection = val;
console.log(this.multipleSelection)
},
// 查询方法
onSubmit() {
console.log(this.user);
},
// 添加数据
addUser() {
// console.log(this.brand);
//发送ajax请求,添加数据
var _this = this;
axios({
method: "post",
url: "http://localhost:8080/login_case/User_AddUserServlet",
data: _this.user,
}).then(function (response) {
if (response.data === "success") {
//关闭窗口
_this.dialogVisible = false
//重新查询数据
_this.selectAll();
// 下面是element抬头显示
_this.$message({
message: '成功新增一条数据',
type: 'success'
});
} else {
_this.$message({
message: '新增失败!',
type: 'error'
});
}
})
},
//分页
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
},
data() {
return {
remodify: true,
readdUser: true,
// 当前页码
currentPage: 4,
// 添加数据对话框是否展示的标记
dialogVisible: false,
//选中的id
selectedId: '',
// 品牌模型数据
user: {
id: '',
userName: '',
passWord: '',
userGender: '',
userAddress: '',
},
// 复选框选中数据集合
multipleSelection: [],
// 表格数据
tableData: [{}]
}
}
})
</script>
</body>
</html>
5 说一下编写位置与规范
增add()
&查select()
我们对于新增的逻辑是:void add(对象)
,它需要引入一个对象格式的数据来对数据库进行添加,而且,它不需要返回值!因此,在mapper层内,我们就可以很容易地写出增
这个接口
//注册一个用户
@Insert("insert into table1 values(null,#{userName}, #{passWord}, #{userGender}, #{userAddress})")
@ResultMap("userResultMap")
void addUser(User user);
//查询所有用户
@Select("select * from 20220806lige.all_user")
@ResultMap("userResultMap")
List<User> selectAllUser();
所以对应的service思路是:
add的service
public void addUser(User user) {//实现一下add这个方法
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);//得到代理对象
mapper.addUser(user);//不需要返回任何值
sqlSession.commit();//除了select其它都要commit一下
sqlSession.close();
}
select的service
public List<User> selectAllUser() {
//获取sqlsession对象
SqlSession sqlSession = factory.openSession();
// 通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper()
// 方法最终获取到 org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,
// 而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用方法,并返回users的list值
List<User> users = mapper.selectAllUser();
// 关闭会话
sqlSession.close();
return users;
}
add的servlet:
//1接收用户数据
BufferedReader bufferedReader = request.getReader();
//json字符串
String json = bufferedReader.readLine();
//转化为User对象
User users = JSON.parseObject(json, User.class);
//调用方法
service.addUser(users);
//下面都是response
response.getWriter().write("success");
select的servlet
//调用方法
List<User> users = service.selectAllUser();
//转为json
String jsonString = JSON.toJSONString(users);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
`跑起项目后测试请求成功转发
数据库成功插入,表明这个方法成功实现!
删delete()
首先还是编写dao层
//注销一个用户,只要返回一个id即可删除一行
@Delete("delete from 20220806lige.all_user where id = #{id}")
@ResultMap("userResultMap")
void deleteUser(int id);
然后是service层
public void deleteUser(int id) {
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(id);
sqlSession.commit();
sqlSession.close();
}
然后就是servlet
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1接收用户数据
BufferedReader bufferedReader = request.getReader();
//json字符串
String json = bufferedReader.readLine();
//转化为int对象
int id = JSON.parseObject(json, int.class);
//调用方法
service.deleteUser(id);
//下面都是response
response.getWriter().write("success");
}
前端:
然后点击删除,成功:
改update()
我们可以利用新增里面的数据对话框进行修改提交,逻辑为这样:①点击修改,触发对话框显示,②并把修改那一行的数据填充到对话框内,③接下来就是用户自己修改,修改完后提交,④重新select即可
由于改
这个方法有点复杂,我们可以看作是根据id选择一条记录,并由发送给selectById的servlet来查询到一条数据,并回显给表单提交页面,再由add方法接管
因此我们需要增加底层代码:
UserMapper层:
//修改用户信息
@Update("update 20220806lige.all_user set username = #{userName},password=#{passWord},gender=#{userGender},address=#{userAddress} where id = #{id}")
@ResultMap("userResultMap")
void updateUser(User user);
service:
public void updateUser(User user) {
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(user);
sqlSession.commit();
sqlSession.close();
}
selectByIdServlet(回显数据的servlet)
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1接收用户数据
BufferedReader bufferedReader = request.getReader();
//json字符串
String json = bufferedReader.readLine();
//转化为int对象
int id = JSON.parseObject(json, int.class);
//调用方法
User user = service.selectById(id);
//转为json
String jsonString = JSON.toJSONString(user);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(jsonString);
}
updateServlet(增加数据的servlet)
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1接收用户数据
BufferedReader bufferedReader = request.getReader();
//json字符串
String json = bufferedReader.readLine();
//转化为User对象
User users = JSON.parseObject(json, User.class);
//调用方法
service.updateUser(users);
//下面都是response
response.getWriter().write("success");
}
这里说一下,由于本人尚未系统学习前端,因此不知道如何给按钮添加可切换的触发事件,导致修改数据会让修改后的数据执行了addUser
方法,导致新增一条数据!
6 编写方式
Dao层(UserMapper.java
与UserMapper.xml
)
这个显而易见的是写CRUD操作的地方,而且我们是用了注解(简化sql)以及映射,然后只要提供一个方法即可
我们显而易见的是,add
方法,dlt
方法,upd
方法返回值为void
,slt
方法与返回值为List<你实体类名>
这里我们要说一下,映射需要我们在UserMapper.xml
里面编写,接下来是编写规则:
service层(UserService.java
与SqlSessionFactoryUtils.java
)
我们命名一个service放在service包下,命名SqlSessionFactoryUtils.java
放在utils包下
将下列sqlsession工厂(mybatis需求)创建的代码放在里面然后导入(alt+enter)即可(我们做了抽出,不在每个service里面频繁调用)
package cn.calendo.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
//静态代码块会随着类的加载而自动执行,且只执行一次
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
这样的话我们就只要在service里面通过factory来获取sqlSessionFactory对象以及对方法进行调用就好了
编写service
我们因为建好了sqlsession工厂,所以在service里面调用一下,然后写一下逻辑即可,现在我们来演示查询全部的service
下面这句话(创建工厂对象)作为service的头
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
然后我们编写service里面的那些方法来实现mapper的接口:
public List<User> selectAllUser() {
//获取sqlsession对象
SqlSession sqlSession = factory.openSession();
// 通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper()
// 方法最终获取到 org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,
// 而这个代理对象正是 MyBatis 使用了 JDK 的动态代理技术,帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用方法,并返回users的list值
List<User> users = userMapper.selectAllUser();
// 关闭会话
sqlSession.close();
return users;
}
编写Web层(servlet)
我们发现idea其实知道我们需要什么,所以直接用它给我们提供的servlet模板创建即可
我们命名一下
我们就可以发现其实已经帮我们写好了doget与dopost方法了
然后我们再写方法即可