day36
JDBC链接数据库
Java中万物皆对象,那Java与数据库的关系呢?
数据库中所有的数据都在表中: 列名 类型 多行数据
Java中所有的数据都使用对象: 属性 类型 多个对象
通过上面的观察,我们发现一张表正好对应一个Java类,一行数据对应一个对象,表中列对应于Java类的属性,那么这种跟数据库对应的类我们统称为model(pojo,bean等…) 类。
JDBC(JAVA DATA BASES CONNECTIVITY): Java数据库连接规范,是Java访问数据库的基石,其他所
有访问数据库的技术(mybatis,hibernate,Springjdbc等)都是基于JDBC来实现的。
JDBC到底是什么:
JBDC是一组接口,为了访问不同数据库提供统一的操作,对程序员隐瞒了具体的实现,只是提供了一种执行sql的API,哪一个数据库想让Java使用他,就需要去实现JDBC这一组接口,由于虽然数据库的每个厂商实现方式不同,但是因为他们实现了一组相同的接口,所以对我们Java程序员来说只要学会使用一种,其他的也就都会使用了。
JDBC3.0 对应Java版本1.5
JDBC4.0 对应Java版本1.6
Statement
Statement的问题:
1: 参数只能使用字符串拼接的方式传递,字符串拼接太过复杂,比较麻烦。
2: Statement执行效率略低。
3: 会造成sql注入。
sql注入:用户在输入内容的时候,输入了数据库的关键字,改变了原本sql的行为。
PreparedStatement解决了Statement引出的三个问题。字符串拼接可能用的上
1: 通过调用方法,根据索引向sql中传递参数,避免字符串拼接太过负载。
2:预编译对象,执行效率较高。
3:可以预防sql注入。
相同步骤
public static void method() throws Exception {
// 1: 通过反射加载驱动
// JDBC4.0版本之后,已经是一个成熟的JDBC了,会自己寻找驱动了,所以我们不必加载驱动。
// Class.forName("com.mysql.jdbc.Driver");
// 2: 通过驱动管理器,获取数据库连接
// url: 用来指定,连接的哪台电脑的什么数据库,以及数据库端口,和数据库名称
// 正常写法jdbc:mysql://192.168.218.139:3306/aaa但是,由于我们连接的是本地数据库ip与端口可以省略不写。
Connection con = DriverManager.getConnection("jdbc:mysql:///aaa", "root", "123456");
// 5: 关闭流
con.close();
}
Statement sm = con.createStatement();
sql注入
Statement sm = con.createStatement();
String username="'小a' or 1=1";//(SQL注入,即永远为true,是一个漏洞)
String sql ="select * from u where name="+username;
U u= new U(6,"小马",1000);/*使用此对象需要进行拼接,比较麻烦。所以使用PreparedStatement来弥补这个缺陷,因为他有方法ps.setObject(1, username);*/
String sql="insert into u values("+u.getId()+",'"+u.getName()+"',"+u.getMoney()+")";
String sql = "delete from u where id=6";
// 4: 执行sql,execute有返回值Boolean,可以进行增删改查,增时返回 删改查时返回
sm.execute(sql);//增删改查,通常增删改使用这个
ResultSet set = sm.executeQuery(sql);//查询
U u = new U();
while (set.next()) {//按行查询,行存在则继续查询
u.setId(set.getInt("id"));//按列查询,根据列名称,获取单元格内容
u.setName(set.getString("name"));
//System.out.println(set.getObject(3));
u.setMoney(set.getInt("money"));
System.out.println(set.getObject(1));//根据列序号进行列获取,获取单元格内容
System.out.println(set.getObject(2));
System.out.println(set.getObject(3));
}
// 5: 关闭流,后开先关闭
set.close();
sm.close();
con.close();
PreparedStatement ps = con.prepareStatement(sql);
String username="小a or 1=1";//使用prepareStatement中的setObject可以避免1=1一直为true的bug(SQL注入)
String sql ="select * from u where name=? ";
// 获取预编译对象,因为是预编译对象所以在获取的时候就需要将sql语句传递进去。
PreparedStatement ps = con.prepareStatement(sql);
// 使用预编译对象,将sql中占位符(?号)的位置替换成实际的值。
ps.setObject(1, username);
ResultSet set = ps.executeQuery();
//存储对象
List<U> list = new ArrayList();
while (set.next()) {
U u = new U();
u.setId(set.getInt("id"));
u.setName(set.getString("name"));
//System.out.println(set.getObject(3));
u.setMoney(set.getInt("money"));
list.add(u);
}
DAO: DAO设计模式
DAO组成
DatabaseConnection:专门负责数据库打开与关闭操作的类
VO:主要由属性,setter, getter方法组成,VO类中的属性与表中的字段相对应,每一个VO类的对象都表示表中的
每一条记录;
DAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如增删改查等;
Impl: DAO接口的真实实现类,主要完成具体数据库操作,但不负责数据库的打开和关闭;
Proxy:代理实现类,主要完成数据库的打开和关闭并且调用真实实现类对象的操作;
Factory: 工厂类,通过工厂类取得一个DAO的实例化对象。
DAO的主要目的实际上可以简单理解成将数据库的各种操作封装到一起,与其他业务相关代码隔开,对于目前的Java来讲使用DAO设计模式已经成为了一个规范。
com.ishangu.model 对应数据库表的类
com.ishangu.dao 针对数据库操作的接口,一般每一个model类都有一个接口,里面放所有的CRUD操作。
com.ishangu.dao.impl 放接口的实现类,一个接口可能会有多个实现类。
com.ishangu.utils 存放一些工具类,例如DatabaseConnection或者,加密工具类等。
work:
1:封装一个数据库工具类,功能越强越好,明天早上每组交一个最强者。
2:写5~10个表的 dao层以及实现类,测试。
3:写完题目1与题目word。
不准复制粘贴。
day37
数据库工具类
加载所用类
见YDemo18里面的工具类DBUtil
Class.forName("com.mysql.jdbc.Driver");//加载,有的编译器不需要这一句,会自动加载
Connection con = DriverManager.getConnection("jdbc:mysql:///aaa", "root", "123456");//链接数据库
PreparedStatement ps=con.prepareStatement(sql);//预编译,后面可以使用ps.setObject(1, 123);来填补?
ResultSet rs = ps.executeQuery();//查询后的结果。编译ps获得SQL语句执行后的数据,放入到ResultSet类的对象中
ResultSetMetaData data = rs.getMetaData();//数据放入到ResultSetMetaData类的对象中,可以使用此类的一些方法
int count = data.getColumnCount();//如方法:获取ResultSetMetaData类对象data中列的数量
String[] str = new String[count];//根据列的数量创建一个字符串数组
for (int i = 0; i < str.length; i++) {
//将ResultSetMetaData类对象data中所有的列名称都存入到字符串数组之内,方便后面反射,根据列名称获取属性并编译
str[i] = data.getColumnLabel(i+1);
}
Class<E> c//反射,c为class类,使用泛型可以传入不同的类,c可为(Emp.class值为class com.ishangu.model.Emp)
public static void method(Class<E> c){
E e = null;
e=c.newInstance();//通过反射,将e实例化成对象。
Field field = c.getDeclaredField(str[i]);//通过反射对象,获取属性
field.setAccessible(true);//公开访问权限
field.set(e, rs.getObject(str[i]));//给属性设置值,一般都是使用rs.getInt/String/Date/BigDecimal()等
//那为什么平常都不使用rs.getObject()呢?是因为:如
e.setEmpno(set.getInt("empno"));
e.setEmpno((Integer)set.getObject("empno"));//效果相同但是需要强制转换。比较麻烦
}
method(Emp.class);
day38
util中的工具类
jdbc插入,修改
jdbc中向数据库中插入数据的通用方法
jdbc中通过第一个属性id修改数据库的数据的通用方法
lombok
注解相关的架构,需要先安装,后引用
作用是放在类前面可以使类自动生成setter,getter,tostring等方法
jdbc分页查询
在util中创建一个新的类,PageInfo,里面是关于分页后的一些数据,比如所有的数据对象,总页数,开始页码等
这样可以使工具类DBUtil返回一个PageInfo对象,方便后期数据库与Java与前端的数据传输。
day39
xml
可扩展表级语言,主要目的是用来传递数据,和HTML不同的是,里面的标签都是我们自定义的。xml的格式与HTML有点类似,里面全部是由标签组成,只是标签变成了我们自定义的标签,我们定义标签的时候,需要以树形结构来定义,每棵树只有一个根部,所以每个xml都需要有一个跟标签,其余标签都在跟标签之内
Java解析xml的主要四种方式
1:DOM解析
2:SAX解析
3:JDOM解析
4:DOM4J解析(目前最常使用的方式)
xml文件:book.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book myID="1">
<number>666</number>
<name>红楼梦</name>
</book>
<book myID="2">
<number>777</number>
<name>西游记</name>
</book>
<book myID="3">
<number>888</number>
<name>水浒传</name>
</book>
<book myID="4">
<number>999</number>
<name>三国演义</name>
</book>
</books>
Java类,创建对象用于存储xml的内容
@Data//lombok架包,自动生成setter,getter等方法
public class Book {
private int id;
private int number;
private String name;
}
读取xml文件内容并存储为book类的对象
需要先导入xml解析的架包:
1.dom4j-1.6.1.jar 2.jaxen-1.1-beta-7.jar 3.sitemesh-2.2.1.jar
public class Dom4jTest {
public static void main(String[] args) throws Exception {
//1.创建一个reader对象,用于等下读取文件
SAXReader reader = new SAXReader();
//2:通过读取文件获得一个document文档对象
Document document = reader.read(new File("C:\\Users\\Administrator\\workspace\\YDemo19\\src\\com\\isahngu\\dom4j\\book.xml"));
//3:先找到文档的根节点
Element rootElement = document.getRootElement();
//4:获得头节点的迭代器,去遍历里面的子节点
Iterator<Element> iterator = rootElement.elementIterator();
List<Book> list = new ArrayList<>();
while (iterator.hasNext()) {
//获取根节点的直接子节点(book标签)
Element book = iterator.next();
//获取book标签的属性
//List list = book.attributes();
Attribute bookAttribute = book.attribute("myID");
Book bo = new Book();
bo.setId(Integer.valueOf(bookAttribute.getValue()));
//遍历book的子节点
Iterator<Element> it = book.elementIterator();
while (it.hasNext()) {
Element next = it.next();
if (next.getName().equals("number")) {//当前标签名字是number的时候
bo.setNumber(Integer.valueOf(next.getStringValue()));//将number标签里的值存入到对象中
} else if (next.getName().equals("name")) {
bo.setName(next.getStringValue());
}
}
list.add(bo);
}
System.out.println(list);
}
}
Dynamic Web project项目创建
创建步骤 右键—>Dynamic Web module version为2.5—>finish
web的发展史:
1: 原始年代
1990年HTML标记性语言的出现代表开启了web时代,从web时代开始B/S架构就不断的蚕食C/S架构,但是这个时期的浏览器页面非常差,只有简单的静态页面。
B/S: 浏览器/服务器
我们所有通过浏览器访问到的内容都是B/S架构。
特点:所有的一切内容都是基于浏览器完成的访问,所有的业务逻辑都有服务器来完成,浏览器负责页面的渲染和数据的交互。
优点: 对客户端的配置要求较低,所有的升级以及更新都是有服务器来完成客户端不需要任何处理,不同的操作系统没有任何影响。
缺点:安全性较低,用户体验较差,网络占用率较高。
C/S: 客户端/服务器
特点:当我们下载软件之后,一般都会有一个本地数据库,所有的页面渲染和业务逻辑的处理都由客户端来完成(由于所有的内容几乎都下载到本地了,所以大部分功能都是由本地客户端完成,只需要网络交换极少数重要数据即可。)
优点:网络占用较少,较为安全,用户体验度较高,功能丰富。
缺点:对客户端要求较高,并且每次更新的时候要客户端进行手动更新,不同的操作系统无法兼容,可移植性较差。其实,BS架构是基于CS架构的(因为浏览器就相当于客户端)
1993~1996
NCSA推出了CGI1.0草案,web从静态发展成了动态,迎来了一个较大的飞跃(CIG带来了动态处理能力,能让服务器与浏览器进行交互)。
1997
1997年sun公司推出了Servlet规范,98年推出了jsp由于jsp技术的诞生 javabean+jsp+Servlet实现了让Java拥有与CGI一样的能力,从此Java迎来了历史性的飞跃
Servlaet是什么?
Servlet是指小服务程序,我们的代码需要与浏览器进行沟通,与浏览器进行沟通的话肯定是需要一定的规范,而这个规范就是Servlet规范,实际上Servlet就是一组接口,里面定义了与浏览器进行沟通的各种规范,所以只要我们的代码实现了这个接口就能通过服务器与浏览器进行交互,所以只要我们写的类只要实现了Servlet接口都叫做Servlet。
Tomcat服务器:
Tomcat是一个Servlet容器,主要用来给我们的Servlet提供运行环境,也就是说只有当我们的Servlet加载到Tomcat中才能实现与浏览器进行交互。
浏览器 Tomcat Servlet 代码
浏览器 房客
Tomcat 中介
Servlet 房主
Tomcat的目录结构
bin 命令
conf 配置文件
lib 运行需要的依赖(jar包)
logs 存放运行时候的日志文件
temp 用来存放临时文件
webapps 部署项目的地方
work 运行项目的过程中编译的一些文件
apache-tomcat-8.0.53-src.zip Tomcat的源码
web项目结构
Java resource
src 存放我们Java代码的地方
bulid 存放的是.class文件(在eclipse中看不见)
webcontent 与web相关的一切都存放在这里(HTML,css,js,jsp,img…)
META-INF 存放一些配置信息
WEB-INF
lib 以后所有的依赖都放入到lib里面,并且不需要build path。
web.xml 里面主要配置我们项目的各种信息(例如配置Servlet等…),而Tomcat在启动的时候会先加载我们的web.xml,并且只会在启动的时候加载一次
启动项目:
选中项目,右键点击 Run As 选择 Run On Server,然后选择需要启动的项目即可,当项目启动后会自动跳转到web.xml中配置的欢迎页面。注意项目启动时先加载的就是web.xml文件,所以后面需要配置这个文件来调用其他的代运行
web.xml文件内容详解
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5">
<display-name>WDemo01</display-name>
<!-- 当项目启动后,自动跳转的页面 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file><!-- 当项目启动后首先跳转到index.html文件,之后通过操控浏览器页面与服务器交互(比如提交时会转到<url-pattern>/my1</url-pattern>对应的地方并转到<servlet-name>myServlet1</servlet-name> 中的myServlet1中,myServlet1为一个类,它最终实现了Servlet这个接口,在myServlet1中有个方法可以接收并处理从前端提交过来的数据。) -->
<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>
<!-- 配置Servlet的名字,以及对应的类是哪一个 -->
<servlet>
<servlet-name>myServlet1</servlet-name> <!-- key -->
<servlet-class>com.ishangu.servlet.MyServlet1</servlet-class> <!-- value -->
</servlet>
<!-- 配置Servlet的名字,以及处理的请求路径是哪个(浏览器请求什么路径能访问到Servlet) -->
<servlet-mapping>
<servlet-name>myServlet1</servlet-name><!-- 指定Servlet名字 -->
<url-pattern>/my1</url-pattern><!-- 给com.ishangu.servlet.MyServlet1建一个别名 -->
</servlet-mapping>
<servlet>
<servlet-name>myServlet2</servlet-name>
<servlet-class>com.ishangu.servlet.MyServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet2</servlet-name>
<url-pattern>/my2</url-pattern>
</servlet-mapping>
</web-app>
在一个应用之中,请求是非常多的,而每个请求的处理方式肯定是不同的,那就代表在一个应用中我们可能会有很多个Servlet来处理请求,所以我们需要在web.xml中去配置Servlet,指定每个Servlet处理的请求路径是什么。
实现Servlet的三种方式:
可以定义一个类,然后实现Servlet 接口或者继承GenericServlet抽象类或者继承HTTPServlet抽象类
1: 实现Servlet接口 init(ServletConfig arg0);初始化方法 service(ServletRequest arg0, ServletResponse arg1);请求处理方法
2: 继承GenericServlet抽象类 service(ServletRequest req, ServletResponse res);请求处理方法
3: 继承HTTPServlet抽象类 doGet(HttpServletRequest req, HttpServletResponse resp);不安全的方法 doPost(HttpServletRequest req, HttpServletResponse resp);安全的方法
浏览器发送请求的方式一般分为get请求与post请求,所以HTTPServlet推荐我们使用doGet 和doPost方法来分开处理请求。
http:超文本传输协议
特点 无状态 默认的端口是80(端口80在浏览器默认可以省略)
实际上http就是指定了服务器与浏览器在交互中需要遵守的一些协议
约束的内容如下:
1.约束了浏览器用什么格式向服务器发送数据。
2.约束了服务器需要用什么方式接收浏览器发送的数据
3.约束了服务器需要使用什么格式向浏览器发送数据
4.约束了浏览器要用什么格式接收服务器发送的数据。
实际上就是浏览器与服务器在一问一答之间,需要遵守的一个规章制度(如果没有这个协议,浏览器发送给我们的数据我们有可能不认识,或者可能接收不到)。
服务器 Java
浏览器 百度等
浏览器向服务器发送数据,我们统称为一次请求,我们向浏览器回应数据统称为一次回应(相应)。
TCP:传输控制协议
依靠字节流实现的传输协议
三次握手
服务器与浏览器建立链接的过程(三次过程)
1:浏览器向服务器发送了一个连接请求。
2:服务器接收到浏览器发送的请求后,服务器向浏览器发送一个连接请求。
3:浏览器接收到了服务器发送的链接请求,建立起来了链接,双方开始沟通。
三次握手主要防止的就是只有一方能单独接收数据,只有当双方都能互相接收到对方链接的时候才算链接建立成功
四次握手
服务器与浏览器断开连接的时候(四次握手)
1.浏览器与服务器说,我准备关闭连接了,可以吗?
2.服务器与浏览器说,行,你管吧。
3.服务器与浏览器说,我也准备关闭连接了可以吗?
4.浏览器与服务器说,好的,关闭吧。