一.高级查询
1.1 拼接where条件的字符串(第一个条件前面加where,其它的条件前面加and)
a. 先加一个 where 1=1 -> 影响查询性能
//接收前端传过来数据
private String title;//工作名称
private Integer positiontype;//工作类型
。。。。。。
/**
* 拼接条件的第一种方式:不建议使用
* 这种1=1的方式,会影响咱们SQL查询的性能(索引)
*/
/*
public String createWhereSql(){
String whereSql = " where 1=1 ";
//title不为null,并且不为空字符串
if(title!=null && !"".equals(title)){
whereSql += " and title like '%"+title+"%' ";
}
if(positiontype!=null){
whereSql += " and positiontype = "+positiontype;
}
return whereSql;
}
b. 准备一个标签 flag=true -> true就是where,false就加and
默认是true,每一次就加where,加完后把它改回成false(第n次就改加使用and)
代码量比较大
/**
* 方案二:准备一个标识(立一个flag)
* 如果标识是true,就加where,如果是false,就是and
* 有点麻烦 -> 如果有更简单的我肯定要选更简单的
* @return
*/
/*
public String createWhereSql(){
boolean flag = true;
String whereSql = "";
//title不为null,并且不为空字符串
if(title!=null && !"".equals(title)){
if(flag){
whereSql+= " where ";
flag = false;
}else{
whereSql+= " and ";
}
whereSql += " title like '%"+title+"%' ";
}
if(positiontype!=null){
if(flag){
whereSql+= " where ";
flag = false;
}else{
whereSql+= " and ";
}
whereSql += " positiontype = "+positiontype;
}
return whereSql;
}
*/
c. 准备一个List<String>,装的就是每一个条件(前面没有where与and)
遍历这个集合的时候,第一次加where,其它的情况加and
在理解上,使用就还是有点麻烦
/**
* 方案三:把SQL存在一个集合中
* 比方案二要灵活一些,扩展性要强一些
* 不是很好理解,代码量也不少
* @return
*/
/*
public String createWhereSql(){
//准备一个集合(里面会装咱们的所有条件)
List<String> sqlList = new ArrayList<>();
String whereSql = "";
//title不为null,并且不为空字符串
if(title!=null && !"".equals(title)){
sqlList.add(" title like '%"+title+"%' ");
}
if(positiontype!=null){
sqlList.add(" positiontype = "+positiontype);
}
//遍历这个集合
for (int i = 0; i < sqlList.size(); i++) {
if(i==0){
//第一次循环,前面肯定是加where
whereSql += " where ";
}else{
//第n次循环,前面肯定是加and
whereSql += " and ";
}
whereSql += sqlList.get(i);
}
return whereSql;
}
*/
d. 把第一个and替换成where -> 比较简单,不影响性能
whereSql.replaceFirst(“and”, “where”);
/**
* 方案四:把第一个and替换成where就可以了
* @return
*/
public String createWhereSql(){
String whereSql = "";
//title不为null,并且不为空字符串
if(title!=null && !"".equals(title)){
whereSql += " and title like '%"+title+"%' ";
}
if(positiontype!=null){
whereSql += " and positiontype = "+positiontype;
}
//把第一个and替换成where
//replace:替换 First:第一个 (替换这个字符串第一个满足条件的值)
return whereSql.replaceFirst("and", "where");
}
1.2 dao中需要加上where条件
查询总条数与查询当前页的数据 -> where条件是一样的
/**
* 最后返回的是PageList对象,里面都要有值
* PageList(int currentPage, int pageSize, int totalCount, List<T> data)
*/
@Override
public PageList<Jobs> queryAll(SqlCondition condition) {
//①.拿到当前页与每页条数
int currentPage = condition.getCurrentPage();
int pageSize = condition.getPageSize();
//②.获取当前查询的条件sql
String whereSql = condition.createWhereSql();
//一.查询总条数
//1.1 准备查询总条数的sql
String sql = "select count(*) from v_jobs "+whereSql;
//1.2执行sql拿到总条数
Integer totalCount = jdbcTemplate.queryForObject(sql, Integer.class);
//二.查询当前页的数据
//2.1 计算当前页是从第几条数据开始的
int beginIndex = (currentPage-1) * pageSize;
//2.2 准备相应的SQL
String dataSql = "select * from v_jobs "+whereSql+" limit "+beginIndex+","+pageSize;
//2.3 执行查询功能
List<Jobs> data= jdbcTemplate.query(dataSql, new BeanPropertyRowMapper<>(Jobs.class));
//三.创建PageList对象并且返回
PageList pageList = new PageList(currentPage,pageSize,totalCount,data);
return pageList;
}
二.高级查询+分页
-
- 之前的分页是直接一个超连接,发送请求就可以成功了。但是当我们有了高级查询条件后,这个分页会导致高级查询的条件丢失!
-
- 解决方案:点击分页的时候提交表单(表单中就有咱们的分页以及查询数据)
2.1 在form中加上了一个隐藏域 (当前页)
注意:这里必需给一个初始页数
- 解决方案:点击分页的时候提交表单(表单中就有咱们的分页以及查询数据)
<input type="hidden" name="currentPage" id="currentPage" value="1" />
代码如下:
<form class="form-inline" id="searchForm" action="/joinus" method="post">
<!-- 准备当前页的条件 -->
<input type="hidden" name="currentPage" id="currentPage" value="1">
2.2 修改咱们的a标签(访问我们的一个js方法)
<a href="javascript:goPage(传的页数); "> 上一页/下一页/..</a>
代码如下:
<!--分页-->
<nav class="navbar-right">
<ul class="pagination" id="paging">
<li>
<span>当前第${pageList.currentPage }页</span>
</li>
<li>
<a href="javascript:goPage(1);">
<span aria-hidden="true">首页</span>
</a>
</li>
<li>
<a href="javascript:goPage (${pageList.prevPage})" aria-label="上一页">
<span aria-hidden="true">上一页</span>
</a>
</li>
<li>
</li>
<li>
<a href="javascript:goPage (${pageList.nextPage})" aria-label="下一页">
<span aria-hidden="true">下一页</span>
</a>
</li>
<li>
<a href="javascript:goPage (${pageList.lastPage})" aria-label="尾页">
<span aria-hidden="true">尾页</span>
</a>
</li>
<li>
<span>总页数:共${pageList.totalPage}页</span>
<span>总数据:共${pageList.totalCount}条</span>
</li>
</ul>
</nav>
-
- 2.3 完成goPage方法
<script type="text/javascript">
function goPage(page) {
//把当前要跳转到第几页的值放到表单的页数中
document.getElementById("currentPage").value=page;
//提交表单
document.getElementById("searchForm").submit();
}
</script>
三.登录功能(Spring的拦截器)
UserDaoImpl:
@Override
public User login(String username, String password) {
try {
return jdbc.queryForObject("select * from t_user where username=? and password=?", new BeanPropertyRowMapper<>(User.class) , username,password);
} catch (Exception e) {
return null;
}
}
3.1 登录的功能:
1.获取前台传过来的用户名与密码
2.根据用户名与密码到数据库中查询当前登录用户
3.如果查询到了用户 -> 把用户存在sessoin中,跳转到主页面
如果没有查询到用户 -> 跳转到登录页面
代码如下:
package cn.itsource.cms.web.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.sun.org.apache.regexp.internal.recompile;
import cn.itsource.cms.domain.User;
import cn.itsource.cms.service.IUserService;
@Controller
public class LoginController {
@Autowired
private IUserService userService;
@RequestMapping(value="/login",method =RequestMethod.GET)
public String index(){
return "forward:/login.jsp";//跳转到登录界面
}
/**
* 完成登录功能
* @param username
* @param password
* @param session
* @return
*/
@RequestMapping(value="/login", method =RequestMethod.POST)//表单POST请求
public String login(String username,String password , HttpSession session){
//根据用户名和密码到后台拿到用户
User login = userService.login(username, password);
//如果用户名存在,代表登录成功,存到session里,跳转到主页面
if (login != null) {
session.setAttribute("loginUser", login);
return "redirect:/system/index";
}
return "forword:/login.jsp";//如果用户名不存在,则跳回登录页面
}
}
-
- 3.2 登录的拦截
- - 1.准备一个Spring的拦截器
class LoginInterceptor 实现 HandlerInterceptor
preHandle:在执行方法之前进行的拦截
返回false代表不放行
返回true代表放行
- 3.2 登录的拦截
package cn.itsource.cms.web.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import cn.itsource.cms.domain.User;
/**
* Handler(处理)Interceptor(拦截器)
*
*/
public class LoginInterceptor implements HandlerInterceptor {
//拦截前执行的功能
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object obj) throws Exception {
//1.从session中拿到当前登录用户
HttpSession session = req.getSession();
User loginUser = (User)session.getAttribute("loginUser");
//2.如果当前登录用户不存在,跳回到主页面
if(loginUser==null){
resp.sendRedirect("/login");
return false;
}
//3.当前登录用户存在,放行
return true;
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
//拦截完要执行的功能
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
//拦截时执行的功能
}
}
-
- 2.对拦截器进行相应的配置(applicationContext-mvc.xml)
<!--
配置一个拦截器
interceptors:代表可以配置多个拦截器
-->
<mvc:interceptors>
<mvc:interceptor>
<!--你要拦截的是哪些请求 -->
<mvc:mapping path="/**"/>
<!--配置你不拦截的请求 -->
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/assets/**"/>
<!-- 所有请求都会经过这个拦截器 -->
<bean class="cn.itsource.cms.web.interceptor.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
3.在拦截器中实现功能
到session中拿当前登录用户
如果没有拿到 -> 跳回登录页面
如果拿到,直接放行