给大家介绍一个servlet、jsp和mysql之间简单的相互转换(就是使用页面访问数据库),以数据库中table表格为例。
1、建立一个servlet,命名为Check,把数据库中数据掉取出来
Connection con = Connect.get();//之前分装好类(上个博客说过)
try {
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from dvd1");//存放数据库中的数据
ResultSetMetaData rm = rs.getMetaData();//获取数据库中字段的名称、字段的值和属性
List> list = new ArrayList>();//存放数据库中的数据
while (rs.next()) {//一个遍历数据中的数据,直到字段对应的值为null为止
Map m = new HashMap();//使用Map的键值对,来对数据库中的字段和字段对应的值进行存储
for (int i = 1; i <= rm.getColumnCount(); i++) {//rm.getColumnCount()是字段的个数
m.put(rm.getColumnName(i), rs.getObject(i));//rm.getColumnName(i)遍历的是字段的名称,rs.getObject(i)遍历是字段对应的值
}
list.add(m);//把Map集合的键值存放到List集合中
}
rs.close();//对用的完的资源进行关闭
st.close();
con.close();
request.setAttribute("lists", list);//把List集合中数据放到request的域中
request.getRequestDispatcher("/check.jsp").forward(request,response);//把上面的request域的输送到check.jsp中
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
这是把数据库中数据读取出来,注意点:1、request.setAttribute("lists", list);中list是是存放到request域中的变量(List集合中的变量),而lists是要传送的变量,用在jsp中接受;2、request.getRequestDispatcher("/check.jsp")中getRequestDispatcher中存放是相对地址,“/”表示当前Web项目,"/check.jsp"也就是在当前的Web项目中的check.jsp。(在jsp和servlet之间的跳转就是靠这些地址,把这个理清楚,基本就是没有问题了)
2、建立一个jsp,命名为check,接受Check.java中发送过来的数据
List> list = (List>) request.getAttribute("lists");//对servlet中的数据的接收
if (list == null || list.size() < 1) {//判断数据库中有没有数据
out.print("数据库中没有数据");
} else {
%>
选择IDDVD名称状态日期次数
for (int i = 0; i < list.size(); i++) {//对接收的数据进行遍历打印
%>
">//第二get是字段,第一get是第二get对应的值}
%>
这个是之前写个一个列子,注意点:1、request.getAttribute("lists")这就是接收servlet发送过来数据的语句,lists是对应request.setAttribute("lists", list)中的第一个参数;2、if (list == null || list.size() < 1),这里的两个条件为了避免“”、“ ”,有不是空时,但是它没有长度;3、这是在页面显示的语句,而是jsp中的写java代码
这样就可以把数据库中的数据再页面上显示了。
越往后面的学习中可以发现的servlet中java是可以优化的,当然就一个功能优化了也不是能明显;同样的功能实现,代码越简洁越来了,给人的感觉也好。
List> list=Mysql.mysql( "select * from teachers");
request.setAttribute("lists", list);
request.getRequestDispatcher("/teacherCheck.jsp").forward(request, response);
这就是servlet中代码优化之后的代码,但是上面的代码都放到了Mysql.mysql方法中,如果有其他的功能需要也就可以直接调用了;这样就减少了代码量。
代码的封装
static Connection con =null;
static Statement st = null;
static ResultSet rs = null;
public static List> mysql(String sql) {
con = get();//数据库的连接
List> list = new ArrayList>();
try {
st = con.createStatement();
rs = st.executeQuery(sql);
ResultSetMetaData rsd = rs.getMetaData();//获取数据库中字段的名称和其值
while (rs.next()) {
Map map = new HashMap();
for (int i = 1; i <= rsd.getColumnCount(); i++) {
map.put(rsd.getColumnName(i), rs.getObject(i));
}
list.add(map);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
return null;
} finally {
close(rs, st, null, con);
}
}
这代码和之前的代码也是不一样的,就是对资源用完之后的关闭
public static void close(ResultSet rs, Statement st, PreparedStatement ps,Connection con) {
try {
if (rs != null)
rs.close();
if (st != null)
st.close();
if (ps != null)
ps.close();
if (con != null)
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
定义了四个常用的接口,要进行关闭时直接调用就可以了,注意点:当需要关闭的资源没有四个的时候,把没有用的输入null就可以了,在这个方法中有对其的判断,而这个判断主要的判断就是有这个接口的代码,而没有执行的情况,进行的判断:比如说st = con.createStatement();rs = st.executeQuery(sql);如果st这行代码出现了错误,下面st这行代码就不执行了,抛出了异常,1)封装的代码中如果没有if的判断就会出现空指针的错误,因为rs没有执行,rs的值为null;2)没有封装的代码,st资源会一直开着,等待java垃圾回收,这样效率低。
其实这样也是不合适,这里出现线程安全的问题,下次再给大家分享。