我们在浏览页面的时候,是不是经常看到网页经常是以页面的形式给我们展现出来的,我们以淘宝的页面为例(如下图),那这样按照页面呈现有什么好处呢?这篇文章让我们来深入探究了解这其中的奥秘。
优点:分页可以减少数据库的搜索次数,降低数据库的压力,每次只需要查询该页的数据,不需要向原来一样每次查询都查询数据库里的全部的数据。
前端:
1.我们在Element中找到对应组件
2. 找到一个合适的组件,赋值粘贴到HTML中
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="form.pageNum"
:page-sizes="[2, 4, 6, 10]"
:page-size="2"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</el-card>
</template>
后续操作后端说完再进行介绍
后端:
以前在数据库中,我们经常用limit进行分页
/*
分页;一个显示一部分数据,可以分页显示
假定有5条数据,每一页想显示2条数据
第一页查询前两条数据 limit 0,2
第二页查询 limit 2,2
第三页查询 limit 4,2
在mysql数据库中可以使用limit实现分页功能
需要掌握的条件:
总共多少页:总条数(可以查出来的)/每页显示的数量 (前端可以计算)
每页显示多少条数据(已知)
当前页数:默认是第一页(已知)
*/
但是今天给大家介绍一个更加简便的方法进行分页
1.在poml.xml中添加相关的依赖
<!-- pagehelper依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
2.在相关类中添加属性,并生成get、set方法
3..在Service类中添加以下代码:
具体的类以自己的为主,我这里的类是Admin
PageHelper.startPage(admin.getPageNum(),admin.getPageSize());//自动生成limit,添加到sql后面
List<Admin> adminList = admindao.adminList(admin);//查询数据,拼接limit,还会自动的生成sql,查询总记录数
PageInfo<Admin> pageInfo = new PageInfo<>(adminList);//把所有分页相关的数据封装到PageInfo对象中
return pageInfo;
3.利用mybatis进行映射
<select id="adminList" resultType="Admin">
SELECT * FROM admin WHERE TYPE=1
</select>
注意:在映射时,会有映射失败的时候。有的属性为nul,这种情况又怎么回事呢?
映射的方法有两种:
-
resultMap
-
resultType
resultMap:
<mapper namespace="com.ffyc.dao.RoleListDao">
<resultMap id="RoleMap" type="Role">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="oper_time" property="oper_time"></result>
<association property="admin" javaType="Admin">
<result column="account" property="account"></result>
</association>
</resultMap>
<select id="roleList" parameterType="Role" resultMap="RoleMap">
SELECT
r.id,
r.name,
a.account,
r.oper_time
FROM ROLE r LEFT JOIN admin a ON r.adminid=a.id
</select>
通过编写resultMap。如下,将数据库字段和实体类字段进行映射。其中,column为数据库字段,property为实体类字段。
resultType:
<select id="adminList" resultType="Admin">
SELECT * FROM admin WHERE TYPE=1
</select>
此时resultType 指向具体的实体类。
映射成功需要满足两个条件
- 数据库中的表名要与实体类的对应字段相同+
- 如果数据库表名中包含有下划线-,那么实体类的对应字段必须要用驼峰命名,才可以映射成功
在sprigboot要成功进行映射的话,必须要进行的一步:
#mybatis配置 创建SqlsessionFactory
mybatis:
type-aliases-package: com.ffyc.model
mapper-locations: classpath:mappers/*Mappers.xml
configuration: #mybatis settings配置
map-underscore-to-camel-case: true #自动映射
cache-enabled: true
还有一个错误需要大家小心
在mybatis查询时,SQL语句对的情况下也未必能查到数据,例如上图
在映射的时候,是通过属性类型进行映射,类中的属性与映射的类型不一致时,也无法进行映射
private Integer password;
public int getPassword() {
return password;
}
public void setPassword(int password) {
this.password = password;
}
我们再说前端
//查询管理员列表
findAdmins(){
this.$http.post("adminList",this.form).then((resp)=>{
this.adminlist = resp.data.data.list; //resp.commonResult.pageInfo.list;
this.total = resp.data.data.total;//把总条数赋分页组件,组件就可以计算总页数...
});
}
下面给大家奉上前端代码
<template>
<el-card class="box-card">
<!-- 查询条件-->
<el-row :gutter="20">
<el-col :span="6">
<el-input placeholder="请输入账号" v-model="form.account"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" @click="findAdmins()" >查询</el-button>
</el-col>
</el-row>
<br/>
<el-table :data="adminlist" border style="width: 100%">
<el-table-column prop="account" label="账号" width="100"></el-table-column>
<el-table-column prop="account" label="操作人"></el-table-column>
<el-table-column prop="operTime" label="操作时间" align="center"></el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button size="mini" >编辑</el-button>
<el-button size="mini" type="danger" >删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="form.pageNum"
:page-sizes="[2, 4, 6, 10]"
:page-size="2"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</el-card>
</template>
<script>
export default {
data() {
return {
adminlist: [],
total:0,
form:{ //都是每次向后端发送的值
account:"",//查询条件 ,
pageNum:1,//默认是第一页
pageSize:2//默认每一页显示2条数据
}
}
},
methods: {
//当改变下拉框页数大小时触发
handleSizeChange(val) {
this.form.pageSize = val;
this.findAdmins();
},
//当改变当前页数时触发
handleCurrentChange(val) {
this.form.pageNum=val;
this.findAdmins();
},
//查询管理员列表
findAdmins(){
this.$http.post("adminList",this.form).then((resp)=>{
console.log(resp);
this.adminlist = resp.data.data.list; //resp.commonResult.pageInfo.list;
this.total = resp.data.data.total;//把总条数赋分页组件,组件就可以计算总页数...
});
}
},
mounted() {
this.findAdmins();
}
}
</script>
<style>
</style>
以上分页是针对一对一查询,但是多对多查询时,又有些特殊的情况,下面让我们来了解多对多查询
多对多查询:
一个人可以身兼数职,每个职位又有不同的功能,这所以让我们在查询数据库的时候要利用的多表查询
我们先从数据库入手
SELECT
a.id,
a.account,
a.password,
a.gender,
a.phone,
oa.account,
r.name
FROM
admin a LEFT JOIN admin oa ON a.adminid=oa.id
LEFT JOIN admin_role ar ON a.id=ar.adminid
LEFT JOIN ROLE r ON r.id=ar.roleid
WHERE a.type=1
前端页面:
在数据库中,我们查出来14条数据,但是在前端分页只有7条数据,我们怎样才能使这14条数据变为7条数据呢?接下来给大家介绍两种方法:
1.直接在数据库进行处理
SELECT
a.id,
a.account,
a.password,
a.gender,
a.phone,
oa.account oper_account,
GROUP_CONCAT(r.name)
FROM
admin a LEFT JOIN admin oa ON a.adminid=oa.id
LEFT JOIN admin_role ar ON a.id=ar.adminid
LEFT JOIN ROLE r ON r.id=ar.roleid
WHERE a.type=1
GROUP BY
a.id,
a.account,
a.password,
a.gender,
a.phone,
oa.account
2.在mybatis中自己进行封装
在自己的类中定义一个集合进行封装
private List<Role> roles;
进行嵌套查询
<resultMap id="adminMap" type="Admin">
<id column="id" property="id"></id>
<result column="account" property="account"></result>
<result column="gender" property="gender"></result>
<result column="oper_time" property="operTime"></result>
<result column="phone" property="phone"></result>
<association property="admin" javaType="Admin">
<result column="oper_account" property="account"></result>
</association>
<collection property="roles" javaType="list" ofType="Role" column="id" select="findAdminRoles">
</collection>
</resultMap>
<select id="adminList" resultMap="adminMap">
SELECT
a.id,
a.account,
a.gender,
a.oper_time,
a.phone,
oa.account oper_account
FROM admin a inner JOIN admin oa ON a.adminid=oa.id
WHERE a.type=1
<if test="account!=null &account!=''">
and a.account=#{account}
</if>
</select>
<select id="findAdminRoles" resultType="Role">
select r.name from admin_role ar left join role r on ar.roleid=r.id
where ar.adminid=#{id}
</select>
在这里给大家在加点小知识:密码加密
在数据库中明码保存,危险性极高,极易发生事故,但是如果我们可以用一种方法使得它变成
这样就不易被人破解,它们是怎么来的呢?
//密码加密 返回32位的字符串 得到一个字符串
//DigestUtils.md5DigestAsHex("1111".getBytes());
这里奉上前端代码
<template>
<el-card class="box-card">
<!-- 查询条件-->
<el-row :gutter="20">
<el-col :span="6">
<el-input placeholder="请输入账号" v-model="form.account"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" icon="el-icon-search" @click="findAdmins()" >查询</el-button>
</el-col>
</el-row>
<br/>
<el-button type="primary" icon="el-icon-plus" @click="openAddDialog()" >新增</el-button>
<el-table :data="adminlist" border style="width: 100%">
<el-table-column prop="account" label="账号" width="100"></el-table-column>
<el-table-column prop="gender" label="性别" width="100"></el-table-column>
<el-table-column prop="phone" label="电话" width="100"></el-table-column>
<el-table-column prop="roles" label="角色" width="200">
<template slot-scope="scope">
<span v-for="role in scope.row.roles">{{role.name}} </span>
</template>
</el-table-column>
<el-table-column prop="admin.account" label="操作人"></el-table-column>
<el-table-column prop="operTime" label="操作时间" align="center"></el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button size="mini" >编辑</el-button>
<el-button size="mini" type="danger" >删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="form.pageNum"
:page-sizes="[2, 4, 6, 10]"
:page-size="2"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
<adminAdd ref="adminAdd"></adminAdd>
</el-card>
</template>
<script>
import adminAdd from "./adminAdd.vue";
export default {
components:{
adminAdd
},
data() {
return {
adminlist: [],
total:0,
form:{ //都是每次向后端发送的值
account:"",//查询条件 ,
pageNum:1,//默认是第一页
pageSize:2//默认每一页显示2条数据
}
}
},
methods: {
openAddDialog(){
this.$refs.adminAdd.dialogVisible=true;
},
//当改变下拉框页数大小时触发
handleSizeChange(val) {
this.form.pageSize = val;
this.findAdmins();
},
//当改变当前页数时触发
handleCurrentChange(val) {
this.form.pageNum=val;
this.findAdmins();
},
//查询管理员列表
findAdmins(){
this.$http.post("admin/adminCtl/adminList",this.form).then((resp)=>{
console.log(resp);
this.adminlist = resp.data.data.list; //resp.commonResult.pageInfo.list;
this.total = resp.data.data.total;//把总条数赋分页组件,组件就可以计算总页数...
});
}
},
mounted() {
this.findAdmins();
}
}
</script>
<style>
</style>
//获取当前任的id
int adminid= JWTUtil.getAdminid(adminToken);
Admin operAdmin=new Admin();
operAdmin.setId(adminid);
admin.setAdmin(operAdmin);
//密码加密 返回32位的字符串
//DigestUtils.md5DigestAsHex("1111".getBytes());
String password=DigestUtils.md5DigestAsHex(admin.getPhone().substring(5).getBytes());//截取手机号的后六位
admin.setPassword(password);
//将管理员的信息进行管理
admindao.insertAdmin(admin);
//保存管理员的角色之间的关系
for(int roleid:admin.getRoleIds()){
admindao.insertAdminRole(admin.getId(),roleid);
}