mvc-servlet优化1
之前的:
优化后:
index.html
<html xmlns:th="http://www.thymeleaf.org" xmlns:width="http://www.w3.org/1999/xhtml" xmlns:>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/index.css">
<script language="JavaScript" src="js/index.js"></script>
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center f30">欢迎使用水果库存后台管理系统</p>
<div style="border: 0px solid red;width:60%; margin-left: 20%; text-align: right">
<form th:action="@{/fruit.do}" method="post" style="float: left;width:60%;margin-left: 20%">
<input type="hidden" name="oper" value="search"/>
请输入关键字:<input type="text" name="keyword" th:value="${session.keyword}"/>
<input type="submit" value="查询" class="btn">
</form>
<a th:href="@{/add.html}" style="border: 0px solid blue;margin-bottom: 4px;">添加新库存记录</a>
</div>
<table id="tbl_fruit">
<tr>
<th class="w20">名称</th>
<th class="w20">单价</th>
<th class="w20">库存</th>
<th>操作</th>
</tr>
<tr th:if="${#lists.isEmpty(session.fruitList)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
<tr th:unless="${#lists.isEmpty(session.fruitList)}" th:each="fruit : ${session.fruitList}">
<!--<td><a th:text="${fruit.fname}" th:href="@{'/edit.do?fid='+${fruit.fid}}">苹果</a></td>-->
<td><a th:text="${fruit.fname}" th:href="@{/fruit.do(fid=${fruit.fid},operate='edit')}">苹果</a></td>
<td th:text="${fruit.price}">5</td>
<td th:text="${fruit.fcount}">20</td>
<!--<td><img src="imgs/del.jpg" class="delImg" th:onclick="'delFruit('+${fruit.fid}+')'"/></td>-->
<td><img src="imgs/del.jpg" class="delImg" th:onclick="|delFruit(${fruit.fid})|"/></td>
</tr>
</table>
<div style="width:60%; margin-left: 20%;border: 0px solid red;padding-top: 4px;" class="center">
<input type="button" value="首 页" class="btn" th:onclick="page(1)" th:disabled="${session.pageNo==1}"/>
<input type="button" value="上一页" class="btn" th:onclick="|page(${session.pageNo-1})|"
th:disabled="${session.pageNo==1}"/>
<input type="button" value="下一页" class="btn" th:onclick="|page(${session.pageNo+1})|"
th:disabled="${session.pageNo==session.pageCount}"/>
<input type="button" value="尾 页" class="btn" th:onclick="|page(${session.pageCount})|"
th:disabled="${session.pageNo==session.pageCount}"/>
</div>
</div>
</div>
</body>
</html>
edit.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/edit.css">
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center f30">编辑库存信息</p>
<form th:action="@{/fruit.do}" method="post" th:object="${fruit}">
<input type="hidden" name="operate" value="update">
<!--隐藏域:功能类似于文本框,它的值会随着表单的发送也会发送给服务器,但是界面上用户看不到-->
<input type="hidden" name="fid" th:value="*{fid}">
<table id="tbl_fruit">
<tr>
<th class="w20">名称:</th>
<!--<td><input type="text" name="fname"th:value="${fruit.fname}"></td>-->
<td><input type="text" name="fname" th:value="*{fname}"></td>
<tr>
<tr>
<th class="w20">单价:</th>
<td><input type="text" name="price" th:value="*{price}"></td>
</tr>
<tr>
<th class="w20">库存:</th>
<td><input type="text" name="fcount" th:value="*{fcount}"></td>
</tr>
<tr>
<th class="w20">备注:</th>
<td><input type="text" name="remark" th:value="*{remark}"></td>
</tr>
<tr>
<th colspan="2">
<input type="submit" value="修改">
</th>
</tr>
<tr th:if="${#lists.isEmpty(session.fruitList)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
add.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/add.css">
</head>
<body>
<div id="div_container">
<div id="div_fruit_list">
<p class="center f30">新增库存信息</p>
<!--add页面没有经过thymeleaf引擎渲染,不能使用th:(thymeleaf表达式)-->
<!--<form th:action="@{/fruit.do}" method="post">-->
<form action="fruit.do" method="post">
<input type="hidden" name="operate" value="add">
<table id="tbl_fruit">
<tr>
<th class="w20">名称:</th>
<!--<td><input type="text" name="fname"th:value="${fruit.fname}"></td>-->
<td><input type="text" name="fname"></td>
<tr>
<tr>
<th class="w20">单价:</th>
<td><input type="text" name="price"></td>
</tr>
<tr>
<th class="w20">库存:</th>
<td><input type="text" name="fcount"></td>
</tr>
<tr>
<th class="w20">备注:</th>
<td><input type="text" name="remark"></td>
</tr>
<tr>
<th colspan="2">
<input type="submit" value="添加">
</th>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
index.css
*{
color: threeddarkshadow;
}
a{
text-decoration-line: none;
}
body{
margin:0;
padding:0;
background-color:#808080;
}
div{
position:relative;
float:left;
}
#div_container{
width:80%;
height:100%;
border:0px solid blue;
margin-left:10%;
float:left;
background-color: honeydew;
border-radius:8px;
}
#div_fruit_list{
width:100%;
border:0px solid red;
}
#tbl_fruit{
width:60%;
line-height:28px;
margin-top:16px;
margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
border:1px solid gray;
border-collapse:collapse;
text-align:center;
font-size:16px;
font-family:"黑体";
font-weight:lighter;
}
.w20{
width:20%;
}
.delImg{
width:24px;
height:24px;
}
.btn{
border:1px solid lightgray;
width:80px;
height:24px;
}
.center{
text-align: center;
}
.f30{
font-size: 30px;
}
edit.css
*{
color: threeddarkshadow;
}
body{
margin:0;
padding:0;
background-color:#808080;
}
div{
position:relative;
float:left;
}
#div_container{
width:80%;
height:100%;
border:0px solid blue;
margin-left:10%;
float:left;
background-color: honeydew;
border-radius:8px;
}
#div_fruit_list{
width:100%;
border:0px solid red;
}
#tbl_fruit{
width:60%;
line-height:28px;
margin-top:16px;
margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
border:1px solid gray;
border-collapse:collapse;
text-align:center;
font-size:16px;
font-family:"黑体";
font-weight:lighter;
}
.w20{
width:20%;
}
.delImg{
width:24px;
height:24px;
}
.btn{
border:1px solid lightgray;
width:80px;
height:24px;
}
.center{
text-align: center;
}
.f30{
font-size: 30px;
}
add.css
*{
color: threeddarkshadow;
}
body{
margin:0;
padding:0;
background-color:#808080;
}
div{
position:relative;
float:left;
}
#div_container{
width:80%;
height:100%;
border:0px solid blue;
margin-left:10%;
float:left;
background-color: honeydew;
border-radius:8px;
}
#div_fruit_list{
width:100%;
border:0px solid red;
}
#tbl_fruit{
width:60%;
line-height:28px;
margin-top:16px;
margin-left:20%;
}
#tbl_fruit , #tbl_fruit tr , #tbl_fruit th , #tbl_fruit td{
border:1px solid gray;
border-collapse:collapse;
text-align:center;
font-size:16px;
font-family:"黑体";
font-weight:lighter;
}
.w20{
width:20%;
}
.delImg{
width:24px;
height:24px;
}
.btn{
border:1px solid lightgray;
width:80px;
height:24px;
}
.center{
text-align: center;
}
.f30{
font-size: 30px;
}
index.js
function delFruit(fid) {
if (confirm('是否确认删除?')) {
window.location.href='fruit.do?fid='+fid+'&operate=del';
}
}
function page(pageNo) {
window.location.href="fruit.do?pageNo="+pageNo;
}
ViewBaseServlet 类
public class ViewBaseServlet extends HttpServlet {
private TemplateEngine templateEngine;
@Override
public void init() throws ServletException {
// 1.获取ServletContext对象
ServletContext servletContext = this.getServletContext();
// 2.创建Thymeleaf解析器对象
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
// 3.给解析器对象设置参数
// ①HTML是默认模式,明确设置是为了代码更容易理解
templateResolver.setTemplateMode(TemplateMode.HTML);
// ②设置前缀
String viewPrefix = servletContext.getInitParameter("view-prefix");
templateResolver.setPrefix(viewPrefix);
// ③设置后缀
String viewSuffix = servletContext.getInitParameter("view-suffix");
templateResolver.setSuffix(viewSuffix);
// ④设置缓存过期时间(毫秒)
templateResolver.setCacheTTLMs(60000L);
// ⑤设置是否缓存
templateResolver.setCacheable(true);
// ⑥设置服务器端编码方式
templateResolver.setCharacterEncoding("utf-8");
// 4.创建模板引擎对象
templateEngine = new TemplateEngine();
// 5.给模板引擎对象设置模板解析器
templateEngine.setTemplateResolver(templateResolver);
}
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException, IOException {
// 1.设置响应体内容类型和字符集
resp.setContentType("text/html;charset=UTF-8");
// 2.创建WebContext对象
WebContext webContext = new WebContext(req, resp, getServletContext());
// 3.处理模板数据
templateEngine.process(templateName, webContext, resp.getWriter());
}
}
FruitServlet 类
@WebServlet("/fruit.do")
public class FruitServlet extends ViewBaseServlet {
private FruitDAO fruitDAO = new FruitDaoImpl();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("utf-8");
String operate = request.getParameter("operate");
if (StringUtil.isEmpty(operate)){
operate = "index";
}
switch (operate){
case "index":
index(request,response);
break;
case "add":
add(request,response);
break;
case "del":
del(request,response);
break;
case "edit":
edit(request,response);
break;
case "update":
update(request,response);
break;
default:
throw new RuntimeException("operate的值非法!");
}
}
private void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取参数
String fidStr = request.getParameter("fid");
int fid = Integer.parseInt(fidStr);
String fname = request.getParameter("fname");
String priceStr = request.getParameter("price");
int price = Integer.parseInt(priceStr);
String fcountStr = request.getParameter("fcount");
int fcount = Integer.parseInt(fcountStr);
String remark = request.getParameter("remark");
//3.执行更新
fruitDAO.updateFruit(new Fruit(fid,fname,price,fcount,remark));
//4.资源跳转
//super.processTemplate("index",request,response);
//request.getRequestDispatcher(index.html).forward(request,response);
//此处需要重定向,目的是重新给IndexServlet发请求,重新获取fruitList,然后覆盖到session
//这样index.html页面上显示的session中的数据才是最新的
response.sendRedirect("fruit.do");
}
private void edit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fidStr = request.getParameter("fid");
if (StringUtil.isNotEmpty(fidStr)){
int fid = Integer.parseInt(fidStr);
Fruit fruit = fruitDAO.getFruitByFid(fid);
request.setAttribute("fruit",fruit);
super.processTemplate("edit",request,response);
}
}
private void del(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fidStr = request.getParameter("fid");
if (StringUtil.isNotEmpty(fidStr)){
int fid = Integer.parseInt(fidStr);
fruitDAO.delFruit(fid);
response.sendRedirect("fruit.do");
}
}
private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String fname = request.getParameter("fname");
int price = Integer.parseInt(request.getParameter("price"));
int fcount = Integer.parseInt(request.getParameter("fcount"));
String remark = request.getParameter("remark");
Fruit fruit = new Fruit(0, fname, price, fcount, remark);
fruitDAO.addFruit(fruit);
response.sendRedirect("fruit.do");
}
private void index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
//设置当前页,默认值是1
Integer pageNo = 1;
String oper = request.getParameter("oper");
//如果oper != null 说明是通过表单的查询按钮点击过来的
//如果oper是空的,说明不是通过表单的查询按钮点击过来的
String keyword = null;
if (StringUtil.isNotEmpty(oper) && "search".equals(oper)){
//说明是点击表单查询发送过来的请求
//此时,pageNo应该还原为1,keyword应该从请求参数获取
pageNo = 1;
keyword = request.getParameter("keyword");
//如果keyword为null,需要设置为空字符串"",否则查询时会拼接成 %null%
//我们期望的是 %%,就是查询所有的数据
if (StringUtil.isEmpty(keyword)){
keyword = "";
}
//将 keyword 保存(覆盖)到session中
session.setAttribute("keyword",keyword);
}else {
//说明此处不是点击表单查询发送过来的请求(比如点击下面的上一页下一页或者直接在地址栏输入网址)
//此时keyword应该从session作用域获取
String pageNoStr = request.getParameter("pageNo");
if (StringUtil.isNotEmpty(pageNoStr)){
pageNo = Integer.parseInt(pageNoStr);
}
//如果不是点击的查询按钮,那么查询是基于session中保存的现有的keyword进行查询
Object keywordobj = session.getAttribute("keyword");
if (keywordobj != null){
keyword = (String)keywordobj;
}else {
keyword = "";
}
}
//重新更新当前页的值
session.setAttribute("pageNo",pageNo);
FruitDAO fruitDAO = new FruitDaoImpl();
List<Fruit> fruitList = fruitDAO.getFruitList(keyword,pageNo);
session.setAttribute("fruitList",fruitList);
//总记录条数
int fruitCount = fruitDAO.getFruitCount(keyword);
//总页数
int pageCount = (fruitCount+5-1)/5;
/*
总记录条数 总页数
1 1
5 1
6 2
10 2
11 3
fruitCount (fruitCount+5-1)/5
*/
session.setAttribute("pageCount",pageCount);
//此处的视图名称是index
//那么thymeleaf会将这个 逻辑视图 名称对应到 物理视图 名称上去
// //逻辑视图名称:index
//物理视图名称: viw-prefix + 逻辑视图名称 +view-suffix
//所以真实的视图名称是: / index .html
super.processTemplate("index",request,response);
}
}
StringUtil 工具类
public class StringUtil {
public static boolean isEmpty(String str){
return str==null || "".equals(str);
}
public static boolean isNotEmpty(String str){
return !isEmpty(str);
}
}
BaseDAO 类
public abstract class BaseDAO<T> {
public final String DRIVER = "com.mysql.jdbc.Driver" ;
public final String URL = "jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&characterEncoding=utf-8&useSSL=false";
public final String USER = "root";
public final String PWD = "123456";
protected Connection conn ;
protected PreparedStatement psmt ;
protected ResultSet rs ;
//T的Class对象
private Class entityClass ;
public BaseDAO(){
//getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
//那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
//因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
//所以getGenericSuperclass()获取到的是BaseDAO的Class
Type genericType = getClass().getGenericSuperclass();
//ParameterizedType 参数化类型
Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
//获取到的<T>中的T的真实的类型
Type actualType = actualTypeArguments[0];
try {
entityClass = Class.forName(actualType.getTypeName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
protected Connection getConn(){
try {
//1.加载驱动
Class.forName(DRIVER);
//2.通过驱动管理器获取连接对象
return DriverManager.getConnection(URL, USER, PWD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null ;
}
protected void close(ResultSet rs , PreparedStatement psmt , Connection conn){
try {
if (rs != null) {
rs.close();
}
if(psmt!=null){
psmt.close();
}
if(conn!=null && !conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//给sql语句中的占位符传值
private void setParams(PreparedStatement psmt , Object... params) throws SQLException {
if(params!=null && params.length>0){
for (int i = 0; i < params.length; i++) {
psmt.setObject(i+1,params[i]);
}
}
}
//执行更新,返回影响行数
protected int executeUpdate(String sql , Object... params){
boolean insertFlag = false ;
insertFlag = sql.trim().toUpperCase().startsWith("INSERT");
try {
conn = getConn();
if(insertFlag){
psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
}else {
psmt = conn.prepareStatement(sql);
}
setParams(psmt,params);
int count = psmt.executeUpdate() ;
if(insertFlag){
rs = psmt.getGeneratedKeys();
if(rs.next()){
return ((Long)rs.getLong(1)).intValue();
}
}
return count ;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rs,psmt,conn);
}
return 0;
}
//通过反射技术给obj对象的property属性赋propertyValue值
private void setValue(Object obj , String property , Object propertyValue){
Class clazz = obj.getClass();
try {
//获取property这个字符串对应的属性名 , 比如 "fid" 去找 obj对象中的 fid 属性
Field field = clazz.getDeclaredField(property);
if(field!=null){
field.setAccessible(true);
field.set(obj,propertyValue);
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
//执行复杂查询,返回例如统计结果
protected Object[] executeComplexQuery(String sql , Object... params){
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
Object[] columnValueArr = new Object[columnCount];
//6.解析rs
if(rs.next()){
for(int i = 0 ; i<columnCount;i++){
Object columnValue = rs.getObject(i+1); //33 苹果 5
columnValueArr[i]=columnValue;
}
return columnValueArr ;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
//执行查询,返回单个实体对象
protected T load(String sql , Object... params){
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
//6.解析rs
if(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1); //fid fname price
Object columnValue = rs.getObject(i+1); //33 苹果 5
setValue(entity,columnName,columnValue);
}
return entity ;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
//执行查询,返回List
protected List<T> executeQuery(String sql , Object... params){
List<T> list = new ArrayList<>();
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
//6.解析rs
while(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1); //fid fname price
Object columnValue = rs.getObject(i+1); //33 苹果 5
setValue(entity,columnName,columnValue);
}
list.add(entity);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return list ;
}
}
Fruit 类
public class Fruit {
private Integer fid ;
private String fname ;
private Integer price ;
private Integer fcount ;
private String remark ;
public Fruit(){}
public Fruit(Integer fid, String fname, Integer price, Integer fcount, String remark) {
this.fid = fid;
this.fname = fname;
this.price = price;
this.fcount = fcount;
this.remark = remark;
}
public Integer getFid() {
return fid;
}
public void setFid(Integer fid) {
this.fid = fid;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getFcount() {
return fcount;
}
public void setFcount(Integer fcount) {
this.fcount = fcount;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return fid + "\t\t" + fname + "\t\t" + price +"\t\t" + fcount +"\t\t" + remark ;
}
}
FruitDAO 接口
public interface FruitDAO {
//获取指定页码上的库存列表信息,每页显示5条
List<Fruit> getFruitList(String keyword,Integer pageNo);
//根据fid获取特定的水果库存信息
Fruit getFruitByFid(Integer fid);
//修改指定的库存记录
void updateFruit(Fruit fruit);
//根据fid删除指定的库存记录
void delFruit(Integer fid);
//添加新库存记录
void addFruit(Fruit fruit);
//查询库存总记录条数
int getFruitCount(String keyword);
}
FruitDaoImpl 类
public class FruitDaoImpl extends BaseDAO<Fruit> implements FruitDAO {
@Override
public List<Fruit> getFruitList(String keyword,Integer pageNo) {
return super.executeQuery("select * from t_fruit where fname like ? or remark like ? limit ?,5","%"+keyword+"%","%"+keyword+"%",(pageNo-1)*5);
}
@Override
public Fruit getFruitByFid(Integer fid) {
return super.load("select * from t_fruit where fid = ?",fid);
}
@Override
public void updateFruit(Fruit fruit) {
String sql = "update t_fruit set fname = ?,price = ?,fcount = ?,remark = ? where fid = ?";
super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark(),fruit.getFid());
}
@Override
public void delFruit(Integer fid) {
super.executeUpdate("delete from t_fruit where fid = ?",fid);
}
@Override
public void addFruit(Fruit fruit) {
String sql = "insert into t_fruit values(0,?,?,?,?)";
super.executeUpdate(sql, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());
}
@Override
public int getFruitCount(String keyword) {
//count()方法返回的是Long类型
return ((Long) super.executeComplexQuery("select count(*) from t_fruit where fname like ? or remark like ?","%"+keyword+"%","%"+keyword+"%")[0]).intValue();
}
}