SpringMVC和JDBC的连接
案例:使用Spring MVC和layui知识,实现数据展示
我们只是改变c,其他不变
最开始的servlect文件中,已经写了分页+查询和添加的的方法,使用op来区别这两种方法,现在使用Controller就不需要这个判断了,而是根据不同的操作定义不同的方法;一个方法add/query,分别增加@RequestMapping();/或者@GetMapping @PostMapping。
以下是原始的Servlect中的分页查询方法,也不需要了。
protected void doQuery(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// 接收表单提交的数据,获取name="webkeywords"的值,
String webkeywords = "";
String userkeywords = "";
if (request.getParameter("webkeywords") != null) {
webkeywords = request.getParameter("webkeywords");
}
if (request.getParameter("userkeywords") != null) {
userkeywords = request.getParameter("userkeywords");
}
int page = 1;
int pageSize = 10;
if (request.getParameter("page") != null) {
page = Integer.parseInt(request.getParameter("page"));
}
if (request.getParameter("limit") != null) {
pageSize = Integer.parseInt(request.getParameter("limit"));
}
// keywords就是传递的查询的关键字
PageData<Website> pd = ws.queryByLike(page, pageSize, webkeywords, userkeywords);
// pd.getTotalCount(), 总记录数
// pd.getList() 页面的数据
AjaxResponse<Website> ar = new AjaxResponse<Website>(0, "success", pd.getTotalCount(), pd.getList());
Gson gson = new Gson();
String str = gson.toJson(ar);
System.out.println("str: " + str);
out.print(str);
// out.append(str);
out.close();
}
采用以下的方式
1. 数据库设计
2. 工程目录结构:
3. 加入的jar包:
4. 实体类、Dao及Dao的实现、Service和Service的实现、通用类
com.etc.entity
Website:
/**
* <p>Title: Website.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.entity;
/**
*
* <p>
* Title: Website
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年2月22日
*
*/
public class Website {
private int id;
private String name;
private String url;
private int type_id;
private int access_num;
private String last_access_date;
private String create_date;
private int create_user_id;
// User 对象
private Users user = new Users();
public Users getUser() {
return user;
}
public void setUser(Users user) {
this.user = user;
}
public Website_Type getWt() {
return wt;
}
public void setWt(Website_Type wt) {
this.wt = wt;
}
// Website_Type 对象
private Website_Type wt = new Website_Type();
// 由于我们查询sql语句的typename为tname
public void setTname(String tname) {
wt.setName(tname);
}
//uname
public void setUname(String uname) {
user.setName(uname);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getType_id() {
return type_id;
}
public void setType_id(int type_id) {
this.type_id = type_id;
}
public int getAccess_num() {
return access_num;
}
public void setAccess_num(int access_num) {
this.access_num = access_num;
}
public String getLast_access_date() {
return last_access_date;
}
public void setLast_access_date(String last_access_date) {
this.last_access_date = last_access_date;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
public int getCreate_user_id() {
return create_user_id;
}
public void setCreate_user_id(int create_user_id) {
this.create_user_id = create_user_id;
}
public Website(int id, String name, String url, int type_id, int access_num, String last_access_date,
String create_date, int create_user_id) {
super();
this.id = id;
this.name = name;
this.url = url;
this.type_id = type_id;
this.access_num = access_num;
this.last_access_date = last_access_date;
this.create_date = create_date;
this.create_user_id = create_user_id;
}
public Website( String name, String url, int type_id, int access_num, String last_access_date,
String create_date, int create_user_id) {
super();
this.name = name;
this.url = url;
this.type_id = type_id;
this.access_num = access_num;
this.last_access_date = last_access_date;
this.create_date = create_date;
this.create_user_id = create_user_id;
}
/**
*
*/
public Website() {
// TODO Auto-generated constructor stub
}
public String toString() {
return "Website [id=" + id + ", name=" + name + ", url=" + url + ", type= " + wt.getName() + "+type_id"+type_id+"access_num="
+ access_num + ", last_access_date=" + last_access_date + ", create_date=" + create_date
+ ", create_user_name = " + user.getName() + "create_user_id"+create_user_id+"]";
}
}
Website_Type
/**
* <p>Title: Website_Type.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.entity;
/**
* <p>Title: Website_Type</p>
* <p>Description: </p>
* @author knowno
* @date 2021年2月22日
*/
public class Website_Type {
private int id;
private String name;
private int website_num;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWebsite_num() {
return website_num;
}
public void setWebsite_num(int website_num) {
this.website_num = website_num;
}
public Website_Type(int id, String name, int website_num) {
super();
this.id = id;
this.name = name;
this.website_num = website_num;
}
/**
*
*/
public Website_Type() {
// TODO Auto-generated constructor stub
}
public String toString() {
return "Website_Type [id=" + id + ", name=" + name + ", website_num=" + website_num + "]";
}
}
Users
/**
* <p>Title: Users.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.entity;
/**
* <p>Title: Users</p>
* <p>Description: </p>
* @author knowno
* @date 2021年2月22日
*/
public class Users {
private int id;
private String name;
private int website_num;
private int website_access_num;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWebsite_num() {
return website_num;
}
public void setWebsite_num(int website_num) {
this.website_num = website_num;
}
public int getWebsite_access_num() {
return website_access_num;
}
public void setWebsite_access_num(int website_access_num) {
this.website_access_num = website_access_num;
}
/**
*
*/
public Users() {
// TODO Auto-generated constructor stub
}
public Users(int id, String name, int website_num, int website_access_num) {
super();
this.id = id;
this.name = name;
this.website_num = website_num;
this.website_access_num = website_access_num;
}
@Override
public String toString() {
return "Users [id=" + id + ", name=" + name + ", website_num=" + website_num + ", website_access_num="
+ website_access_num + "]";
}
}
com.etc.dao和com.etc.dao.impl
WebsiteDao
/**
* <p>Title: WebsiteDao.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.dao;
import com.etc.entity.Website;
import com.etc.util.PageData;
/**
*
* <p>
* Title: WebsiteDao
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年2月22日
*
*/
public interface WebsiteDao {
/**
*
*
* <p>
* Title: queryByLike
* </p>
*
* <p>
* Description:
* </p>
*
* @param page
* @param pageSize
* @param webkeywords
* @param userkeywords
* @return
*/
public PageData<Website> queryByLike(int page, int pageSize, String webkeywords, String userkeywords);
/**
*
* <p>Title: add</p>
* <p>Description: </p>
* @param webs
* @return
*/
public boolean add(Website webs);
}
WebsiteDaoImpl:
/**
* <p>Title: WebsiteDaoImpl.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.dao.impl;
import com.etc.dao.WebsiteDao;
import com.etc.entity.Website;
import com.etc.util.DBUtil;
import com.etc.util.PageData;
/**
*
* <p>
* Title: WebsiteDaoImpl
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年2月22日
*
*/
public class WebsiteDaoImpl implements WebsiteDao {
/**
* (non-Javadoc)
*
* <p>
* Title: queryByLike
* </p>
*
* <p>
* Description:
* </p>
*
* @param page
* @param pageSize
* @param webkeywords
* @param userkeywords
* @return
*
* @see com.etc.dao.WebsiteDao#queryByLike(int, int, java.lang.String,
* java.lang.String)
*
*/
@Override
public PageData<Website> queryByLike(int page, int pageSize, String webkeywords, String userkeywords) {
String sql = "SELECT tw.id,tw.name,tw.url,twt.NAME tname,tw.access_num,tw.last_access_date,tw.create_date,t_user.NAME uname FROM t_website tw INNER JOIN t_website_type twt ON tw.type_id=twt.id INNER JOIN t_user ON t_user.id=tw.create_user_id WHERE tw.NAME LIKE ? AND t_user.NAME LIKE ? ORDER BY tw.access_num DESC";
return DBUtil.exQueryByPage(sql, Website.class, page, pageSize, '%' + webkeywords + '%',
'%' + userkeywords + '%');
}
/**
*
*
* <p>
* Title: add
* </p>
*
* <p>
* Description: 增加website
* </p>
*
* @param webs
* @return
*/
public boolean add(Website webs) {
String sql = "INSERT INTO `websitedb`.`t_website`(`name`, `url`, `type_id`, `access_num`, `last_access_date`, `create_date`, `create_user_id`) VALUES (?,?,?,?,?,?,?)";
return DBUtil.exUpdate(sql, webs.getName(), webs.getUrl(), webs.getType_id(), webs.getAccess_num(),
webs.getLast_access_date(), webs.getCreate_date(), webs.getCreate_user_id());
}
/**
* 测试
*
* <p>
* Title: main
* </p>
*
* <p>
* Description:
* </p>
*
* @param args
*/
public static void main(String[] args) {
WebsiteDaoImpl wd = new WebsiteDaoImpl();
Website webs = new Website("aaa", "http:a", 1, 15, "2021-2-2", "2021-2-2", 1);
System.out.println(wd.add(webs));
}
}
com.etc.service和com.etc.service.impl
WebsiteService:
/**
* <p>Title: WebsiteService.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.service;
import com.etc.entity.Website;
import com.etc.util.PageData;
/**
* <p>Title: WebsiteService</p>
* <p>Description: </p>
* @author knowno
* @date 2021年2月22日
*/
public interface WebsiteService {
public PageData<Website> queryByLike(int page, int pageSize, String webkeywords, String userkeywords);
public boolean add(Website webs);
}
WebsiteServiceImpl:
/**
* <p>Title: WebsiteServiceImpl.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月22日
* @version 1.0
*/
package com.etc.service.impl;
import com.etc.dao.WebsiteDao;
import com.etc.dao.impl.WebsiteDaoImpl;
import com.etc.entity.Website;
import com.etc.service.WebsiteService;
import com.etc.util.PageData;
/**
*
* <p>
* Title: WebsiteServiceImpl
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年2月22日
*
*/
public class WebsiteServiceImpl implements WebsiteService {
WebsiteDao dao = new WebsiteDaoImpl();
/**
* (non-Javadoc)
*
* <p>
* Title: queryByLike
* </p>
*
* <p>
* Description:
* </p>
*
* @param page
* @param pageSize
* @param webkeywords
* @param userkeywords
* @return
*
* @see com.etc.service.WebsiteService#queryByLike(int, int, java.lang.String,
* java.lang.String)
*
*/
@Override
public PageData<Website> queryByLike(int page, int pageSize, String webkeywords, String userkeywords) {
if (page < 1) {
page = 1;
} else if (page > pageSize) {
page = pageSize;
}
PageData<Website> pd = dao.queryByLike(page, pageSize, webkeywords, userkeywords);
return pd;
}
public boolean add(Website webs) {
return dao.add(webs);
}
}
com.etc.util
DBUtil:
package com.etc.util;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
/**
*
* <p>
* Title: DBUtil
* </p>
*
* <p>
* Description:数据库访问的通用类,其中,实现了增加删除修改通用操作;实现了查询多行记录的通用操作;
* </p>
*
* @author knowno
*
* @date 2021年1月11日
*
*/
public class DBUtil {
// 数据库连接的url =>url还有一些参数 这里连接的是本地的mysql8 端口3309 ->my.ini中
// ?key=value&key=value
private static final String url = "jdbc:mysql://localhost:3309/javawork2?serverTimezone=Asia/Shanghai";
// 数据库连接的user
private static final String user = "root";
// 数据库连接的密码
private static final String password = "root";
private DBUtil() {
// TODO Auto-generated constructor stub
}
/**
* 自己封装的一个方法,返回一个连接对象
*
* @return Connection对象
*/
public static Connection getConn() {
Connection conn = null;
try {
// 1 加载驱动
// com.mysql.cj.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver");
// 2获取连接
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 封装的增加 删除 和修改通用代码(针对任何表)
*
* @param sql sql语句
* @param params 参数
* @return true 操作成功 false 操作失败
*/
public static boolean exUpdate(String sql, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
int n = 0;
try {
// 2获取连接
conn = getConn();
// 3得到一个PrepardStatement
pstmt = conn.prepareStatement(sql);
// 调用自定义方法,设置参数
setParameters(pstmt, params);
System.out.println("pstmt :"+pstmt);
// 4执行具体操作 增加删除以及修改
n = pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 6释放资源
closeAll(null, pstmt, conn);
}
return n > 0;
}
/**
* 设置参数的方法
*
* @param pstmt PreparedStatement 对象
* @param params Object... params 可变参数
* @throws SQLException SQLException 异常
*/
public static void setParameters(PreparedStatement pstmt, Object... params) throws SQLException {
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
}
/**
* 通用查询方法(返回结果是一个集合)
*
* @param sql 查询语句
* @param cla Class对象
* @param params 参数
* @return List 集合
*/
public static List exQuery(String sql, Class cla, Object... params) {
List list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 2获取连接
conn = getConn();
// 3得到一个PrepardStatement
pstmt = conn.prepareStatement(sql);
// 设置占位符的参数
setParameters(pstmt, params);
System.out.println("pstmt :" + pstmt);
// 4执行具体操作 (ResultSet 结果集)
rs = pstmt.executeQuery();
// 5遍历rs
while (rs.next()) {
Object obj = convert(rs, cla);
// 得到一个obj ,将其加入list
list.add(obj);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeAll(rs, pstmt, conn);
}
return list;// 真
}
/**
* 查询单个记录(记录总数)
*
* @param sql
* @param params
* @return
*/
public static int exCountQuery(String sql, Object... params) {
int totalCount = 0;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 2获取连接
conn = getConn();
// 3得到一个PrepardStatement
pstmt = conn.prepareStatement(sql);
// 设置占位符的参数
setParameters(pstmt, params);
// 4执行具体操作 (ResultSet 结果集)
rs = pstmt.executeQuery();
// 5遍历rs
if (rs.next()) {
//
totalCount = rs.getInt("c");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeAll(rs, pstmt, conn);
}
return totalCount;//
}
/**
* 分页查询
*
* @param sql
* @param cla
* @param pageNo 当前页页码
* @param pageSize 当前页显示的记录数
* @param params
* @return
*/
public static PageData exQueryByPage(String sql, Class cla, int pageNo, int pageSize, Object... params) {
List list = new ArrayList();
// 先查询sql,注意没有拼接limit之前,目的只是得到"总记录数"
// select count(*) from (select * from blog where blogtitle like '%程序%' ) as t
String totalCountSql = " select count(*) as c from ( " + sql + " ) as t";
int totalCount = exCountQuery(totalCountSql, params);
// 起始位置
int start = (pageNo - 1) * pageSize;
// "select * from blog where blogtitle like ? " + " limit 0," +pageSize
sql = sql + " limit " + start + "," + pageSize;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 2获取连接
conn = getConn();
// 3得到一个PrepardStatement
pstmt = conn.prepareStatement(sql);
// 设置占位符的参数
setParameters(pstmt, params);
System.out.println("pstmt :" + pstmt);
// 4执行具体操作 (ResultSet 结果集)
rs = pstmt.executeQuery();
// 5遍历rs
while (rs.next()) {
Object obj = convert(rs, cla);
// 得到一个obj ,将其加入list
list.add(obj);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeAll(rs, pstmt, conn);
}
PageData pd = new PageData();
pd.setPageNo(pageNo);
pd.setPageSize(pageSize);
pd.setList(list);
// 总记录数
pd.setTotalCount(totalCount);
return pd;
}
/**
* 转换方法 将rs读取结果转换对象
*
* @param rs 结果集
* @param cla Class对象
* @return Object
*/
private static Object convert(ResultSet rs, Class cla) {
Object obj = null;
try {
obj = cla.newInstance();
ResultSetMetaData rsmd = rs.getMetaData();
// System.out.println(rsmd);
// System.out.println(rsmd.getColumnCount()); //列数量
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
// getColumnLabel 如果有别名,就是别名 as 后; getColumnName 和表中的列 一致->列名
// System.out.println(rsmd.getColumnLabel(i)+","+rsmd.getColumnName(i));
String name = rsmd.getColumnLabel(i);
Object objvalue = rs.getObject(name);
// XX.set方法(对象,属性,属性的值); 属性 和列名一致
BeanUtils.setProperty(obj, name, objvalue);
}
} catch (InstantiationException | IllegalAccessException | SQLException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
/**
* 释放资源
*
* @param rs ResultSet对象
* @param pstmt PreparedStatement 对象
* @param conn Connection对象
*/
public static void closeAll(ResultSet rs, PreparedStatement pstmt, Connection conn) {
// 6释放资源
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
PageData:
package com.etc.util;
import java.util.List;
/**
* 分页有关的数据
*
* @author Administrator
*
*/
public class PageData<T> {
// 页码
private int pageNo;
// 当前页面的记录数
private int pageSize;
// 总记录数
private int totalCount;
// 总页数
private int totalPage;
// 当前页的数据
private List<T> list;
public int getTotalPage() {
// 总页数和总记录数关系
totalPage = totalCount / pageSize;
if (totalCount % pageSize != 0) {
totalPage = totalPage + 1;
}
return totalPage;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
getTotalPage();//总页数
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
@Override
public String toString() {
return "PageData [pageNo=" + pageNo + ", pageSize=" + pageSize + ", totalCount=" + totalCount + ", totalPage="
+ getTotalPage() + ", list=" + list + "]";
}
}
AjaxResponse:
/**
* <p>Title: AjaxResponse.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年1月12日
* @version 1.0
*/
package com.etc.util;
import java.util.List;
/**
*
* <p>
* Title: AjaxResponse
* </p>
*
* <p>
* Description: 自定义分页数据响应,和layui的table结合使用(x-admin)
* </p>
*
* @author knowno
*
* @date 2021年1月12日
*
*/
public class AjaxResponse<T> {
// 状态码
private int code = 0;
private String msg = "";
// 总记录数
private int count = 0;
// 页面数据
private List<T> data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
@Override
public String toString() {
return "AjaxResponse [code=" + code + ", msg=" + msg + ", count=" + count + ", data=" + data + "]";
}
public AjaxResponse(int code, String msg, int count, List<T> data) {
super();
this.code = code;
this.msg = msg;
this.count = count;
this.data = data;
}
/**
*
*/
public AjaxResponse() {
// TODO Auto-generated constructor stub
}
}
AjaxUploadResponse:
/**
* <p>Title: AjaxUploadResponse.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年1月13日
* @version 1.0
*/
package com.etc.util;
/**
*
* <p>
* Title: AjaxUploadResponse
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年1月13日
*
*/
public class AjaxUploadResponse {
private int code = 0;
private String msg = "";
private String data = "";
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public AjaxUploadResponse(int code, String msg, String data) {
super();
this.code = code;
this.msg = msg;
this.data = data;
}
/**
*
*/
public AjaxUploadResponse() {
// TODO Auto-generated constructor stub
}
}
5. Controller中的写法
/**
* <p>Title: WebSiteController.java</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2021</p>
* <p>Company: www.chinasofti.com</p>
* @author knowno
* @date 2021年2月25日
* @version 1.0
*/
package com.etc.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.etc.entity.Website;
import com.etc.service.WebsiteService;
import com.etc.service.impl.WebsiteServiceImpl;
import com.etc.util.AjaxResponse;
import com.etc.util.PageData;
/**
*
* <p>
* Title: WebSiteController
* </p>
*
* <p>
* Description:
* </p>
*
* @author knowno
*
* @date 2021年2月25日
*
*/
@RestController
public class WebSiteController {
private WebsiteService ws = new WebsiteServiceImpl();
@GetMapping("query.do")
public AjaxResponse<Website> getWebSite(@RequestParam(value="webkeywords",required = true,defaultValue = "") String webkeywords,@RequestParam(value="userkeywords",required = true,defaultValue = "") String userkeywords, int page, int limit) {
// keywords就是传递的查询的关键字
PageData<Website> pd = ws.queryByLike(page, limit, webkeywords, userkeywords);
// pd.getTotalCount(), 总记录数
// pd.getList() 页面的数据
AjaxResponse<Website> ar = new AjaxResponse<Website>(0, "success", pd.getTotalCount(), pd.getList());
return ar;
}
}
6. springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 指定控制器的扫描包 -->
<context:component-scan
base-package="com.etc.controller"></context:component-scan>
<!-- 静态资源处理 -->
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 视图解析器配置 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- viewClass -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
7. web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
<display-name>springmvc01</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
8.网页界面
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!doctype html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>后台登录-X-admin2.2</title>
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="./css/font.css">
<link rel="stylesheet" href="./css/xadmin.css">
<!-- <link rel="stylesheet" href="./css/theme5.css"> -->
<script src="./lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="./js/xadmin.js"></script>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script>
// 是否开启刷新记忆tab功能
// var is_remember = false;
</script>
</head>
<body class="index">
<!-- 顶部开始 -->
<div class="container">
<div class="logo">
<a href="./index.html">X-admin v2.2</a></div>
<div class="left_open">
<a><i title="展开左侧栏" class="iconfont"></i></a>
</div>
<ul class="layui-nav left fast-add" lay-filter="">
<li class="layui-nav-item">
<a href="javascript:;">+新增</a>
<dl class="layui-nav-child">
<!-- 二级菜单 -->
<dd>
<a onclick="xadmin.open('最大化','http://www.baidu.com','','',true)">
<i class="iconfont"></i>弹出最大化</a></dd>
<dd>
<a onclick="xadmin.open('弹出自动宽高','http://www.baidu.com')">
<i class="iconfont"></i>弹出自动宽高</a></dd>
<dd>
<a onclick="xadmin.open('弹出指定宽高','http://www.baidu.com',500,300)">
<i class="iconfont"></i>弹出指定宽高</a></dd>
<dd>
<a onclick="xadmin.add_tab('在tab打开','member-list.html')">
<i class="iconfont"></i>在tab打开</a></dd>
<dd>
<a onclick="xadmin.add_tab('在tab打开刷新','member-del.html',true)">
<i class="iconfont"></i>在tab打开刷新</a></dd>
</dl>
</li>
</ul>
<ul class="layui-nav right" lay-filter="">
<li class="layui-nav-item">
<a href="javascript:;">admin</a>
<dl class="layui-nav-child">
<!-- 二级菜单 -->
<dd>
<a onclick="xadmin.open('个人信息','http://www.baidu.com')">个人信息</a></dd>
<dd>
<a onclick="xadmin.open('切换帐号','http://www.baidu.com')">切换帐号</a></dd>
<dd>
<a href="./login.html">退出</a></dd>
</dl>
</li>
<li class="layui-nav-item to-index">
<a href="/">前台首页</a></li>
</ul>
</div>
<!-- 顶部结束 -->
<!-- 中部开始 -->
<!-- 左侧菜单开始 -->
<div class="left-nav">
<div id="side-nav">
<ul id="nav">
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="会员管理"></i>
<cite>会员管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('统计页面','welcome1.html')">
<i class="iconfont"></i>
<cite>统计页面</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('会员列表(静态表格)','member-list.jsp')">
<i class="iconfont"></i>
<cite>会员列表(静态表格)</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('会员列表(动态表格)','member-list1.jsp',true)">
<i class="iconfont"></i>
<cite>会员列表(动态表格)</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('添加会员','member-add.html')">
<i class="iconfont"></i>
<cite>添加会员</cite></a>
</li>
<li>
<a href="javascript:;">
<i class="iconfont"></i>
<cite>会员管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('会员删除','member-del.html')">
<i class="iconfont"></i>
<cite>会员删除</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('等级管理','member-list1.html')">
<i class="iconfont"></i>
<cite>等级管理</cite></a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="网站管理"></i>
<cite>网站管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('网站列表','website-list.jsp')">
<i class="iconfont"></i>
<cite>网站列表</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('新增商品','goods-add.jsp')">
<i class="iconfont"></i>
<cite>新增网站</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="订单管理"></i>
<cite>订单管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('订单列表','order-list.jsp')">
<i class="iconfont"></i>
<cite>订单列表</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('订单列表1','order-list1.html')">
<i class="iconfont"></i>
<cite>订单列表1</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="分类管理"></i>
<cite>分类管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('多级分类','cate.html')">
<i class="iconfont"></i>
<cite>多级分类</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="城市联动"></i>
<cite>城市联动</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('三级地区联动','city.html')">
<i class="iconfont"></i>
<cite>三级地区联动</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="管理员管理"></i>
<cite>管理员管理</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('管理员列表','admin-list.html')">
<i class="iconfont"></i>
<cite>管理员列表</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('角色管理','admin-role.html')">
<i class="iconfont"></i>
<cite>角色管理</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('权限分类','admin-cate.html')">
<i class="iconfont"></i>
<cite>权限分类</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('权限管理','admin-rule.html')">
<i class="iconfont"></i>
<cite>权限管理</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="系统统计"></i>
<cite>系统统计</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('拆线图','echarts1.html')">
<i class="iconfont"></i>
<cite>拆线图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('拆线图','echarts2.html')">
<i class="iconfont"></i>
<cite>拆线图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('地图','echarts3.html')">
<i class="iconfont"></i>
<cite>地图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('饼图','echarts4.html')">
<i class="iconfont"></i>
<cite>饼图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('雷达图','echarts5.html')">
<i class="iconfont"></i>
<cite>雷达图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('k线图','echarts6.html')">
<i class="iconfont"></i>
<cite>k线图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('热力图','echarts7.html')">
<i class="iconfont"></i>
<cite>热力图</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('仪表图','echarts8.html')">
<i class="iconfont"></i>
<cite>仪表图</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="图标字体"></i>
<cite>图标字体</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('图标对应字体','unicode.html')">
<i class="iconfont"></i>
<cite>图标对应字体</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="其它页面"></i>
<cite>其它页面</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a href="login.html" target="_blank">
<i class="iconfont"></i>
<cite>登录页面</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('错误页面','error.html')">
<i class="iconfont"></i>
<cite>错误页面</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('示例页面','demo.html')">
<i class="iconfont"></i>
<cite>示例页面</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('更新日志','log.html')">
<i class="iconfont"></i>
<cite>更新日志</cite></a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="iconfont left-nav-li" lay-tips="第三方组件"></i>
<cite>layui第三方组件</cite>
<i class="iconfont nav_right"></i></a>
<ul class="sub-menu">
<li>
<a onclick="xadmin.add_tab('滑块验证','https://fly.layui.com/extend/sliderVerify/')" target="">
<i class="iconfont"></i>
<cite>滑块验证</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('富文本编辑器','https://fly.layui.com/extend/layedit/')">
<i class="iconfont"></i>
<cite>富文本编辑器</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('eleTree 树组件','https://fly.layui.com/extend/eleTree/')">
<i class="iconfont"></i>
<cite>eleTree 树组件</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('图片截取','https://fly.layui.com/extend/croppers/')">
<i class="iconfont"></i>
<cite>图片截取</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('formSelects 4.x 多选框','https://fly.layui.com/extend/formSelects/')">
<i class="iconfont"></i>
<cite>formSelects 4.x 多选框</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('Magnifier 放大镜','https://fly.layui.com/extend/Magnifier/')">
<i class="iconfont"></i>
<cite>Magnifier 放大镜</cite></a>
</li>
<li>
<a onclick="xadmin.add_tab('notice 通知控件','https://fly.layui.com/extend/notice/')">
<i class="iconfont"></i>
<cite>notice 通知控件</cite></a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- <div class="x-slide_left"></div> -->
<!-- 左侧菜单结束 -->
<!-- 右侧主体开始 -->
<div class="page-content">
<div class="layui-tab tab" lay-filter="xbs_tab" lay-allowclose="false">
<ul class="layui-tab-title">
<li class="home">
<i class="layui-icon"></i>我的桌面</li></ul>
<div class="layui-unselect layui-form-select layui-form-selected" id="tab_right">
<dl>
<dd data-type="this">关闭当前</dd>
<dd data-type="other">关闭其它</dd>
<dd data-type="all">关闭全部</dd></dl>
</div>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<iframe src='./welcome.html' frameborder="0" scrolling="yes" class="x-iframe"></iframe>
</div>
</div>
<div id="tab_show"></div>
</div>
</div>
<div class="page-content-bg"></div>
<style id="theme_style"></style>
<!-- 右侧主体结束 -->
<!-- 中部结束 -->
<script>//百度统计可去掉
var _hmt = _hmt || []; (function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?b393d153aeb26b46e9431fabaf0f6190";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();</script>
</body>
</html>
website-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>欢迎页面-X-admin2.2</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport"
content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="./css/font.css">
<link rel="stylesheet" href="./css/xadmin.css">
<script src="./lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="./js/xadmin.js"></script>
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="x-nav">
<span class="layui-breadcrumb"> <a href="">首页</a> <a href="">演示</a>
<a> <cite>导航元素</cite></a>
</span> <a class="layui-btn layui-btn-small"
style="line-height: 1.6em; margin-top: 3px; float: right"
onclick="location.reload()" title="刷新"> <i
class="layui-icon layui-icon-refresh" style="line-height: 30px"></i>
</a>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body ">
<form class="layui-form layui-col-space5">
<div class="layui-inline layui-show-xs-block">
<input type="text" name="webkeywords" placeholder="请输入查询关键字"
autocomplete="off" class="layui-input">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="userkeywords" placeholder="请输入查询关键字"
autocomplete="off" class="layui-input">
</div>
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn" lay-submit="" lay-filter="search">
<i class="layui-icon"></i>
</button>
<button class="layui-btn" lay-submit="" lay-filter="add" >
<i class="layui-icon">新增(弹出层)</i>
</button>
</div>
</form>
</div>
<div class="layui-card-body ">
<!-- url:'./user.json' 替换成我们自己的后端接口的地址,返回一个user.json中的内容"格式" -->
<table class="layui-table"
lay-data="{url:'../query.do',page:true,toolbar: '#toolbarDemo',id:'test'}"
lay-filter="test">
<thead>
<tr>
<th lay-data="{type:'checkbox'}">序号</th>
<th lay-data="{field:'id', width:110, sort: true}">网站编号</th>
<th
lay-data="{field:'name', width:150, sort: true, edit: 'text'}">网站名称</th>
<th lay-data="{field:'url', edit: 'text', width: 300}">网站地址</th>
<th lay-data="{field:'wt.name', width:100,templet: function(d){ return d.wt.name;}}">网站类型</th>
<th lay-data="{field:'access_num', edit: 'text', width: 100}">访问次数</th>
<th
lay-data="{field:'last_access_date', width: 150}">最后一次访问</th>
<th
lay-data="{field:'create_date',width:120, sort: true, edit: 'text'}">创建时间</th>
<th
lay-data="{field:'user.name',width:120, sort: true, templet: function(d){ return d.user.name;}}">创建者</th>
<th lay-data="{field:'', width:150,templet: '#opTpl'}">操作</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/html" id="opTpl">
<a
onclick="member_stop(this,'10001')" href="javascript:;"
title="启用"> <i class="layui-icon"></i>
</a> <a title="编辑"
onclick="xadmin.open('编辑','website-add.jsp',600,400)"
href="javascript:;"> <i class="layui-icon"></i>
</a> <a
onclick="xadmin.open('修改密码','member-password.html',600,400)"
title="修改密码" href="javascript:;"> <i class="layui-icon"></i>
</a> <a title="删除" onclick="member_del(this,'要删除的id')"
href="javascript:;"> <i class="layui-icon"></i>
</a>
</script>
<!--
<script type="text/html" id="toolbarDemo">
<div class = "layui-btn-container" >
<button class = "layui-btn layui-btn-sm" lay-event = "getCheckData" > 获取选中行数据 </button>
<button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button >
<button class = "layui-btn layui-btn-sm" lay-event = "isAll" > 验证是否全选</button>
</div >
</script>
-->
<script type="text/html" id="stateTpl">
<!-- 这里的checked的状态只是演示 -->
<input type = "checkbox" name = "goodsstate" value = "{{d.goodsstate}}" lay-skin = "switch" lay-text = "已上架|已下架" lay-filter = "stateDemo" {{ d.goodsstate == 1 ? 'checked': ''}} >
</script>
<script>
layui.use('laydate', function() {
var laydate = layui.laydate;
//执行一个laydate实例
laydate.render({
elem : '#start' //指定元素
});
//执行一个laydate实例
laydate.render({
elem : '#end' //指定元素
});
});
</script>
<script>
layui.use([ 'table', 'form' ], function() {
var table = layui.table;
var form = layui.form;
//search
form.on('submit(search)', function(data) {
//console.log(data.elem) //被执行事件的元素DOM对象,一般为button对象
//console.log(data.form) //被执行提交的form对象,一般在存在form标签时才会返回
console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
//向servlet提交请求,获取数据并展示在layui table中
//1 原始(jquery) ajax -=>响应的数据我们需要自己处理,并展示在table中
//2 layui ->封装好的ajax请求 ,自动填充layui table
table.reload('test', {
url : '../query.do',
where : data.field//设定异步数据接口的额外参数
//,height: 300
});
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//add
form.on('submit(add)', function(data) {
xadmin.open('添加','website-add.jsp',600,400);
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});
//监听单元格编辑
table.on('edit(test)', function(obj) {
var value = obj.value //得到修改后的值
, data = obj.data //得到所在行所有键值
, field = obj.field; //得到字段
layer.msg('[ID: ' + data.id + '] ' + field + ' 字段更改为:' + value);
});
//头工具栏事件
table.on('toolbar(test)', function(obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'getCheckData':
var data = checkStatus.data;
layer.alert(JSON.stringify(data));
break;
case 'getCheckLength':
var data = checkStatus.data;
layer.msg('选中了:' + data.length + ' 个');
break;
case 'isAll':
layer.msg(checkStatus.isAll ? '全选' : '未全选');
break;
}
;
});
});
</script>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?b393d153aeb26b46e9431fabaf0f6190";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</html>