目录
一、数据库语法基础
二、JDBC基础
JDBC是Java DataBase Connectivity(Java 数据库连接)技术的简称。
是一种可用于执行SQL语句的Java API。
它由一些Java语言编写的类和接口组成。
JDBC有两个程序包:
java.sql:核心包,这个包中的类主要完成数据库的基本操作,如生成连接、执行SQL语句、预处理SQL语句等;
javax.sql:扩展包,主要为数据库方面的高级操作提供了接口和类。
三、JDBC常用类和接口
Driver 接口:在内部创建连接
DriverManager类:加载驱动,创建连接
Connection接口:编程时使用该类对象创建Statement或PreparedStatement对象等
Statement接口:编程时使用该类对象执行SQL语句,查询操作可得到ResultSet对象 PreparedStatement接口:预处理SQL语句接口 ResultSet接口:结果集接口
ResultSetMetaData接口:结果集的元数据接口
DatabaseMetaData接口:数据库的元数据接口
四、数据库连接的主要步骤
1、注册、加载特定的驱动程序;
2、创建链接Connection对象;
3、利用Connection对象生成Statement对象或PrepareStatement对象;
4、利用Statement对象或预处理命令对象执行SQL语句,如查询、更新、插入、删除等;
5、若是执行查询语句,还要从ResultSet读取数据;
6、关闭ResultSet、Statement(或P热怕热Statement)、Connection等;
核心代码:
<%
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2.建立与数据库的连接
String url = "jdbc:mysql://172.16.26.19:3306/computer_dept";
Connection conn = DriverManager.getConnection(url, "root", "sise");
//3.创建命令对象
Statement st=conn.createStatement();
//4.执行SQL语句
String sql = "SELECT * FROM STUDENTS";
ResultSet rs=st.executeQuery(sql);
//5.获取并输出查询结果
out.println("<table border='1'>");
out.println("<tr><td>学号</td><td>姓名</td><td>性别</td><td>专业</td></tr>");
while (rs.next()){
out.println("<tr>");
out.println("<td>"+rs.getString("num")+"</td>");
out.println("<td>"+rs.getString("name")+"</td>");
out.println("<td>"+rs.getString("gender")+"</td>");
out.println("<td>"+rs.getString("major")+"</td>");
out.println("</tr>");
}
out.println("</table>");
//6.释放资源
rs.close(); st.close(); conn.close();
%>
五、预处理语句
1、问题提出
当向数据库发送一个SQL语句,比如“Select * from students”,数据库中的SQL解释器将负责把SQL语句生成底层的内部命令,然后执行该命令,完成有关的数据操作;
如果不断地向数据库提交SQL语句势必增加数据库中SQL解释器的负担,影响执行的速度;
如果应用程序能针对连接的数据库,事先就将SQL语句解释为数据库底层的内部命令,然后直接让数据库去执行这个命令,显然不仅减轻了数据库的负担,而且也提高了访问数据库的速度。
2、问题解决
对于JDBC,建立与数据库的连接后,就可以利用连接对象调用 prepareStatement(String sql)方法对SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象中,该对象调用相应的方法都可以使得该底层的内部命令被数据库执行;
在创建PreparedStatement 对象时,SQL 语句是作为参数提供的;由于只有这些值的位置是已知的,故使用? 符号来表示。运行SQL语句时,将设置实际值。
最后,调用PreparedStatement对象的execute()[或executeQuery()、executeUpdate()]方法执行有关操作。
使用PreparedStatement还能有效的防止SQL注入
六、例题:用表单添加学生记录
关键代码:
<%
request.setCharacterEncoding("utf-8");//解决提交乱码的问题 %>
添加学生信息<br>
<form method="post">
输入学号:<input type="text" name="stuno"><br>
输入姓名:<input type="text" name="stuname"><br>
选择性别:<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女">女
<input type="submit" value="添加">
</form>
<%
String stuno = request.getParameter("stuno");
String stuname= request.getParameter("stuname");
String stusex = request.getParameter("sex");
if (stuno!=null){
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/computer_dept","root","12345678");
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "select stuno from students where num=?";
ps=conn.prepareStatement(sql);
ps.setString(1,stuno);
rs = ps.executeQuery();
if(rs.next()){
out.println("对不起,该学校学号已存在!");
}
else{
sql = "insert into students(num,name,gender) values (?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1,stuno);
ps.setString(2,stuname);
ps.setString(3,stusex);
ps.executeUpdate();
out.println("添加成功!");
}
}
%>
七、什么是JavaBean
(1)问题的提出:
在JSP中允许html标记与Java语言混合在一起编程,这样会引发一些问题:
结构不清晰:业务逻辑与显示混合在一起
程序不可重用:只能采用复制代码方式来重用程序 引入JavaBean后可以解决上述两个问题
(2)什么是JavaBean?
JavaBean就是一个可重复使用的、基于Java的软件组件,可以在软件开发工具中被直观地操作。
JavaBean是一种Java类,通过封装属性和方法成为具有某种功能或者处理某个业务的对象,简称Bean。由此可见,只要符合JavaBean规范的Java公共类,都可称为JavaBean。
八、JavaBean规范
1、必须是一个public权限的Java类
2、必须有一个无参数的构造方法;
3、其属性都应该限定为private或protected;
4、针对名为XXX的属性,读取该属性的方法名为getXxx()(布尔值型为isXxx()),设置属性值为setXxx(参数);
5、实现Serialable接口,这样组件可以序列化。
使用JavaBean的优点:
代码可重用,缩短开发时间;
易编写,易维护、易使用;
可以在不同平台上使用,而不需要重新编译,为JSP的应用带来了更多的可扩展性。
九、JavaBean的创建
1、JavaBean的结构
2、JavaBean的创建步骤
在src目录创建一个包,名字自定,如:beans;
创建一个公共类;
设置属性的getter/setter方法。
public boolean isMale() {
return male;
}
public void setMale(boolean male) {
this.male = male;
}
public String getEducation() {
return education;
}
public void setEducation(String education) {
this.education = education;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
问题:
(1)UserBean定义了几个属性?
(2)怎样设置、获取属性值?
(3)isMale()实现什么功能?
(4)有无默认构造方法?
3、JavaBean属性
根据是否可读写,可分为:只读、只写,可读写;
根据属性的复杂性,可分为:简单属性、索引属性:
简单属性:非数组属性。前面介绍的属性(如:name、male、email等)都是这种类型,一个属性只能取一个值。
格式:
public Type getPropertyName()或isPropertyName()
public void setPropertyName(Type newValue)
索引属性:数组属性。一个属性可以取多个值,如:兴趣、特长、购物等。
格式:
public Type getPropertyName(int index)
public void setPropertyName(int index,Type value)
public Type[] getPropertyName()
public void setPropertyName(Type[])
十、在JSP中使用JavaBean
在JSP页面中使用bean时,首先使用page指令的import属性导入创建bean类
例如:
<%@ page import="com.bean.*"%>
1、说明:
应创建在某一包中,不支持在默认包中创建、使用;
编译后形成的class文件通常位于WEB-INF/classes对应包的子目录中。
2、使用:有两种方式
代码法:与一般Java程序类似,在脚本中创建JavaBean对象,并调用相应的方法。这种方法通俗易懂,但代码较长;
标签法:JSP中规定了三个标签来操作JavaBean,即:
<jsp:useBean>:创建或查找Bean对象
<jsp:setProperty>:设置Bean对象的属性值
<jsp:getProperty>:得到Bean对象的属性值
3、<jsp: useBean>标签
功能:创建或查找JavaBean实例
当含有 useBean动作标记的JSP 页面被 Web容器加载执行时,Web 容器首先根据id的名字在 pageContext 内置对象中查看是否含有名字为 id 和作用域为 scope 的对象。如果该对象存在,Web 容器就将这个对象的副本(bean)分配给JSP 页面使用:如果没有找到就根据class指定的类创建一个名字是id的bean,并添加到pageContext 对象中,同时将这个bean分配给JSP页面使用。useBean动作标记的执行流程如图所示
4、各项参数含义:
id——对象实例名称
scope——Bean的作用范围,默认为page,在某一个页面有效,它有4个可取值:page、request、session、application
class——Bean类名称其余属性较少使用,不一一说明。(MyFriend (属性:name、mobile))
<jsp:useBean id="zhang" scope="page" class="sise.MyFriend" />
<jsp:setProperty name="zhang" property="name" value="老张" />
5、Scope各项参数的意义
page——仅涵盖使用JavaBean的页面。
request——有效范围仅限于使用JavaBean的请求。
session——有效范围在用户整个连接过程中(整个会话阶段均有效)
application——有效范围涵盖整个应用程序。也就是对整个网站均有效。
说明 :page、request、session、application具有容器的功能,即可向它们存放对象,也可取出指定对象的内容: 存放对象格式:容器对象.setAttribute(对象名,对象); 取出对象内容格式:容器对象.getAttribute(对象名)。
useBean例题
编写一个JSP页面example5 2jsp,在JSP页面中使用useBean标记获得一个bean,负责创建 bean 的类是例 5-1 中的 Rectangle 类,bean 的名字是 rectangle,rectangle的scope 取值为 page。JSP页面的运行效果如图所示。
Rectangle类(在com.bean包中)
package com.bean;
public class Rectangle {
private double length;
private double width;
public Rectangle(){
length=20;
width=10;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double computerArea(){
return length*width;
}
public double computerLength(){
return (length+width)*2;
}
}
JSP页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:useBean id="rectangle" class="com.bean.Rectangle" scope="page"/>
<p>矩形的长是:<%=rectangle.getLength()%></p>
<p>矩形的宽是:<%=rectangle.getWidth()%></p>
<p>矩形的面积是:<%=rectangle.computerArea()%></p>
<p>矩形的周长是:<%=rectangle.computerLength()%></p>
</body>
</html>
6、<jsp: setProperty>标签
格式:
1、用表达式设置bean的属性:
<jsp:setProperty name="bean的名字" property= "bean的属性” value= "<%=expression%>"/>
2、用字符串设置 bean的属性:
<jsp:setProperty name="bean的名字" property="bean的属性” value="字符串”/>
在用表达式修改 bean 属性值时,表达式值的类型必须与 bean 的属性类型一致。在用字符串修改 bean 属性值时,字符串会被转换为 bean 的属性类型,不能成功转换的可能会抛出NumberFormatException异常。
通过HTTP表单参数值设置 bean 的属性
<jsp:setProperty name="bean 的名字” property="*">
任意指定请求参数设置 bean的属性
<jsp;setProperty name="bean的名字" property="属性名" param="参数名"/>
功能:设置JavaBean实例的属性值,相当于:<% 实例名.set方法名(实参表);%>
例题:
用表达式或字符串修改bean的属性。具体要求如下
(1)创建bean的源文件 Car.java,该bean 的作用是描述小汽车的一些属性。
(2)编写JSP页面carjsp,在该JSP 页面中使用useBean标记创建一个名字是 smallCar的bean,其有效范围是page,并使用动作标记修改、获取该bean的属性值,负责创建smallCar的类是Car。JSP页面的运行效果如图所示。
Car.java
package com.bean;
public class Car {
String tradeMark;
String number;
public String getTradeMark() {
return tradeMark;
}
public void setTradeMark(String tradeMark) {
this.tradeMark = tradeMark;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
car.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:useBean id="smallCar" class="com.bean.Car" scope="page"/>
<%
String carNo="京A8888";
%>
<%--使用setProperty标记设置smallCar的tradeMark属性值为“宝马X6”--%>
<jsp:setProperty name="smallCar" property="tradeMark" value="宝马X6"/>
<%--使用setProperty标记设置smallCar的number属性值为carNo--%>
<jsp:setProperty name="smallCar" property="number" value="<%=carNo%>"/>
汽车品牌是:<jsp:getProperty name="smallCar" property="tradeMark"/>
<br>汽车牌号是:<jsp:getProperty name="smallCar" property="number"/>
</body>
</html>
通过HTTP表单参数值设置bean的属性。具体要求如下
(1)编写JSP页面inputCar.jsp 和 showCar.jsp
(2)在inputCar.jsp 页面中输入信息后提交给showCar.jsp 页面显示信息。
(3)JSP页面中用到的 bean 是例5-4 中的Car 类创建的。JSP 页面的运行效果如图
inputCar.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="showCar.jsp" method="post">
请输入汽车品牌:
<input type="text" name="tradeMark"/>
<br>
请输入汽车牌号:
<input type="text" name="number"/>
<br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
showCar.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="smallCar" class="com.bean.Car" scope="page"/>
<%--通过HTTP表单参数设置bean属性(表单参数与属性自动匹配--%>
<jsp:setProperty name="smallCar" property="*"/>
汽车的品牌是:<jsp:getProperty name="smallCar" property="tradeMark"/>
<br>汽车的牌号是:<jsp:getProperty name="smallCar" property="number"/>
</body>
</html>
<jsp:useBean id="zhang" scope="page" class="sise.MyFriend" />
<jsp:setProperty name="zhang" property="name" value="老张" />
<% zhang.setMobile("1392345678"); %>
7、 <jsp: getProperty>标签
格式:
<jsp:getProperty name=“beanName” property=“bean的属性”/>
功能:得到JavaBean实例指定属性的值,相当于beanName.getPropertyName()方法调用(getXxx()方法)
例题:
创建 bean 的源文件NewRectangle,java,该 bean 的作用是计算矩形的面积和周长。编写一个JSP页面useGetProperty.jsp,在该JSP 页面中使用useBean标记创建一个名字是pig的bean,并使用getProperty动作标记获得pig的每个属性值,负责创建pig的类是NewRectangle。JSP页面的运行效果如图所示。
NewRectangle类
package com.bean;
public class NewRectangle {
double length;
double width;
double rectangleArea;
double rectangLength;
public NewRectangle(){
length=20;
width=10;
}
public double getLength() {
return length;
}
public void setWidth(double width) {
this.width = width;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public double getRectangleArea(){
return length*width;
}
public double getRectangLength(){
return 2*(width+length);
}
}
useGetProperty.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:useBean id="pig" class="com.bean.NewRectangle" scope="page"/>
<% pig.setLength(30);%>
<%pig.setWidth(20);%>
<p>矩形的长是:<jsp:getProperty name="pig" property="length"/></p>
<p>矩形的宽是:<jsp:getProperty name="pig" property="width"/></p>
<p>矩形的面积是:<jsp:getProperty name="pig" property="rectangleArea"/></p>
<p>矩形的周长是:<jsp:getProperty name="pig" property="rectangLength"/></p>
</body>
</html>
<% 实例名.get方法名( );%>
姓 名:
<font color=blue>
<jsp:getProperty name="zhang" property="name"/>
</font><br>
手机号码:
<font color=blue> <%=zhang.getMobile()%> </font>
十一、DAO和VO
利用JDBC访问数据库是我们经常进行的操作,由于操作的步骤较多,很容易出错。为此,可利用JavaBean进行封装,并可反复使用。
1、为什么需要DAO和VO?
JSP是表示层,最好不要在JSP中连接数据库、操作数据,而是将这些操作交给专门的类来完成;
DAO(Data Access Object)类,专门负责对数据库的访问、操作。DAO将查询到的每一条记录封装成VO对象,再将所有实例化的VO存放到集合中(如:ArrayList对象)返回给JSP;
VO(Value Object):配合DAO来使用。在DAO中,将查询得到的每一条记录封装成VO,如Student对象就是VO。
2、编写DAO和VO
VO就是一个JavaBean对象
public class Student {
private String stuno;
private String stuname;
private String stusex;
public String getStuno() {
return stuno;
}
public void setStuno(String stuno) {
this.stuno = stuno;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public String getStusex() {
return stusex;
}
public void setStusex(String stusex) {
this.stusex = stusex;
}
}
DAO将数据库连接、操作包含其中,将查询结果封装成VO,放到ArrayList中返回。
package dao;
import java.sql.*;
import java.util.ArrayList;
import bean.Student;
public class StudentDao {
private Connection conn = null;
public void initConnection() throws Exception {
// 连接MySQL
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/goodedu","scott", "tiger");
}
// 返回所有学生
public ArrayList<Student> getAllStudents() throws Exception {
ArrayList <Student> al = new ArrayList<Student>();
initConnection();
String sql = "SELECT STUNO,STUNAME,STUSEX FROM T_STUDENT";
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery(sql);
while (rs.next()) {
Student stu = new Student();
stu.setStuno(rs.getString("STUNO"));
stu.setStuname(rs.getString("STUNAME"));
stu.setStusex(rs.getString("STUSEX"));
al.add(stu);
}
closeConnection();
return al;
}
public void closeConnection() throws Exception {
conn.close();
}
}
ArrayList <Student> al = new ArrayList<Student>();
3、在JSP中使用DAO和VO
使用步骤:
在page指令中导入DAO类和VO类;
通过DAO访问数据库,将查询结果放在ArrayList中;
显示ArrayList中的各VO对象内容。
使用DAO和VO的优点:
将JDBC有关代码封装到DAO中,用户可以不了解数据库操作细节,大大减少了程序代码,开发时便于分工。
如何设计、命名DAO、VO?
DAO通常命名为XXXDao,XXX与系统中的实体对应,如:StudentDao;
VO的名称与系统中的实体对应 ,如:Student类。
=================================================================
注意
1、数据库在项目中加载驱动错误
Class.forName("com.mysql.cj.jdbc.Driver");//mysql8和mysql5区别:8有cj
2、配置pom.xml(maven文件)
选8版本和5版本都行,5版本不行就选8版本
复制在pom.xml里
成功!