0


JDBC和XML

JDBC和XML

JDBC是一套操作关系型数据库的规则(接口),数据库厂商需要实现这套接口,并提供数据库驱动jar包。

开发人员使用这套接口,真正执行的是对应的驱动包中的实现类。

1 JDBC环境配置

1.1 MySQL驱动包

mysql-connector-java-5.1.37.zip下载 _

将其中的

mysql-connector-java.5.1.37-bin.jar

复制到自定义的jar仓库,

1.2 新建Java项目并添加驱动包

在IDEA中新建空项目后,CTRLALTSHIFTL打开ProjectStructure对话框,在Project选项卡中添加Java的SDK,在Libraries选项卡中添加jar仓库。

在这里插入图片描述

1.3 注册驱动

在main方法中添加

Class.forName("com.mysql.jdbc.Driver");

2 JDBC基本操作

2.1 JDBC操作流程

2.1.1 获取连接对象

DriverManager.getConnection(url,user,password);//其中url的格式如下:
jdbc:mysql://主机地址:端口号/数据库名?参数名=参数
jdbc:mysql://localhost:3306?characterEncoding=UTF-8

2.1.2 获取语句执行平台对象Statement

Statement类常用方法功能说明int executeUpdate(String sql);执行insert、update、delete语句,返回int类型,表示受影响的行数ResuoltSet executeQuery(String sql);执行select语句,返回ResultSet结果集对象

  1. 获取语句执行平台对象
Statement statement = connection.createStatement();
  1. 创建一张表
String sql_CreateTable ="create table test(id int,name varchar(20),age int)";int i = statement.executeUpdate(sql_CreateTable);
  1. 执行查询操作,获得ResultSet结果集合
String sql_Select ="select * from jdbc_user";ResultSet resultSet = statement.executeQuery(sql_Select);//打印获得的数据while(resultSet.next()){int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");Date birthday = resultSet.getDate("birthday");System.out.println("id:"+ id +"username:"+ username +"password:"+ password +"birthday:"+ birthday);}

2.1.3 释放资源

  1. 需要释放的对象:ResultSet结果集,Statement语句,Connection连接。
  2. 释放原则:类似出入栈规则
  3. 以下代码可以放到try/catch/finally中的finally里
//顺序不能变
resultSet.close();
statement.close();
connection.close();

2.3 JDBC实现增删改查

2.3.1 工具类的创建

可以新建JDBCUtils工具类,存放数据库连接关闭、增删改查语句的静态方法,方便项目中操作数据库。

工具类中包含的内容:

  • 可以把几个字符串定义成常量:用户名,密码,URL,驱动类
  • 得到数据库连接的方法:getConnection()
  • 关闭所有打开的资源方法:close()
//1.定义常量publicstaticfinalString DRIVERNAME ="com.mysql.jdbc.Driver";//2.静态代码块→随类的加载而加载一次static{Class.forName(DRIVERNAME);}//3.获取连接的静态方法publicstaticConnectiongetConnection(){}//4.关闭资源(重载)publicstaticvoidclose(Connection ct,Statement sm){}publicstaticvoidclose(Connection ct,Statement sm,ResultSet rs){}

2.3.2 DML(增删改)操作

  1. 解决插入中文乱码的问题//指定字符的编码、解码格式jdbc:mysql://localhost:3306/db?characterEncoding=UTF-8
  2. 添加注解在自定义成员方法前添加注解后,就可以单独运行该方法。在这里插入图片描述在这里插入图片描述
  3. 增删改//1.获取连接Connection con =JDBCUtils.getConnection();//2.获取Statement对象Statement statement = con.createStatement();//3.sql语句操作statement.executeUpdate("插入数据的语句");注意最后关闭流

2.3.3 DQL(查询)操作

//1.获取连接Connection con =JDBCUtils.getConnection();//2.获取Statement对象Statement statement = con.createStatement();//3.sql语句操作ResultSet rs = statement.executeQuery("查询数据的语句");//4.处理结果集while(rs.next()){int i = rs.getInt(字段名);String str = rs.getString(字段名);...}//5.关闭资源

2.4 预处理

在程序中如果用户输入可以直接于编写的SQL进行拼接,则会产生SQL注入漏洞。

在此使用预处理对象PrepareStatement

作为Statement接口的子接口,有预编译的功能,通过占位符的方式设置参数,可以有效防止SQL注入。

2.4.1 预处理对象执行原理

只编译一次SQL语句,并将SQL缓存,用户输入的只是用作参数来被调用。

2.4.2 预处理对象使用(重要)

//1.获取连接Connection con =JDBCUtils.getConnection();//2.获取预处理对象,通过占位符?设置参数String sql ="select * from table_user where username = ? and password = ?";PreparedStatement ps = con.prepareStatement(sql);//3.获取用户输入Scanner sc =newScanner.(System.in);String name = sc.nextLine();String password = sc.nextLine();//4.设置参数使用setXXX方法
ps.setString(1,name);
ps.setString(2,password);//5.执行查询ResultSet rs = ps.executeQuery();//6.处理结果集//7.关闭流

2.4.3 Statement与PreparedStatement的区别

  • Statement用于执行静态SQL语句,在执行时,必须指定一个实现准备好的SQL语句。
  • PrepareStatement是预编译的SQL语句对象,语句中可以包含动态参数“?”,在执行时可以动态设置参数值。
  • PrepareStatement可以减少编译次数提高数据库的性能。

2.5 JDBC控制事务

//1.获取连接Connection con =JDBCUtils.getConnection();//2.开启事务
con.setAutoCommit(false);//手动提交事务//3.获取预处理对象并执行String sql ="";PreparedStatement ps = con.prepareStatement(sql);
ps.executeUpdate();//4.提交事务
con.commit();//--------------------------------------------------////5.如果提交失败,则回滚操作
con.rollback();//6.释放资源

3 数据库连接池

用于管理数据库连接,可以重复使用连接。

关闭连接不代表销毁connection,只是将连接进行了归还。

3.1 数据库连接池介绍

Java中提供了公共接口:

javax.sql.DataSource接口

,与JDBC类似,数据库厂商需要实现该接口。

常见的数据库连接池有DBCP连接池,C3P0连接池,Druid连接池。

3.2 DBCP连接池

DBCP是一个开源的连接池,是Apache成员之一,Tomcat中内置。

3.2.1 配置

将commons-dbcp-1.4.jar和commons-pool-1.5.6.jar两个包 _复制到上文中提到的

myjar

路径下,在IDEA中新建项目后,CTRLALTSHIFTL打开ProjectStructure对话框,在Modules选项卡按照下图所示操作,添加myjar。

在这里插入图片描述

3.2.2 自定义工具类DBCPUtils

//1.自定义常量,保存数据库连接的驱动、地址等信息publicstaticfinalString DRIVERNAME ="com.mysql.jdbc.Driver";//2.创建连接池对象publicstaticBasicDataSource dataSource =newBasicDataSource();//3.使用静态代码块设置参数static{
    dataSource.setDriverClassName(DRIVERNAME);
    dataSource.setUrl();
    dataSource.setUsername(USERNAME);
    dataSource.setPassword(PASSWORD);}//4。获取连接对象publicstaticConnectiongetConnection(){Connection con = dataSource.getConnection();return connection;}//5.释放资源(归还连接)(重载)publicstaticvoidclose(Connection con,Statement sm){/*先判断非空*/}publicstaticvoidclose(Connetion con,Statement sm,ResultSet rs){/*先判断非空*/}

3.2.3 常见的配置项

在DBCPUtils中可以定义以下参数
属性含义driverClassName数据库驱动名称url数据库地址username用户名password密码maxActive最大连接数量(默认为8)maxIdle最大空闲连接(默认为8)minIdle最小空闲连接(默认为0)initialSize初始化连接

3.2.4 连接池测试

//1.获取连接Connection con =DBCPUtils.getConnection();//2.获取预处理对象String sql ="select * from table where name = ?";PreparedStatement ps = con.prepareStatement(sql);//3.设置占位符的值
ps.setString(1,"...");ResultSet rs = ps.executeQuery();//4.处理结果集while(rs.next()){int id = rs.getInt("id");System.out.println(id);}//5.释放资源DBCPUtils.close(rs,ps,con);

3.3 C3P0连接池

C3P0是一个开源的JDBC连接池,支持JDBC3规范和JDBC2的标准扩展,目前使用它的开源项目有Hibernate,Spring等。

3.3.1 导入配置文件

将c3p0-0.9.5.2.jar和mchange-commons-java-0.2.12.jar _导入上文提到的

myjar

路径下。

导入配置文件

c3p0-config.xml

,将该文件直接放到src或资源文件夹中。资源文件夹是指在项目下新建目录,然后右击→Mark Directory as→Surces Root。

3.3.2 修改配置参数

c3p0-config.xml

文件中添加以下内容:

<!--配置连接池mysql--><named-configname="mysql"><propertyname="driverClass">com.mysql.jdbc.Driver</property><propertyname="jdbcUrl">jdbc:mysql://IP地址/数据库名?characterEncoding=UTF-8</property><propertyname="user">用户名</property><propertyname="password">连接密码</property><propertyname="initialPoolSize">初始化连接数量10</property><propertyname="maxIdleTime">最大空闲时间30</property><propertyname="maxPoolSize">最大线程池大小100</property><propertyname="minPoolSize">最小连接池大小10</property></named-config><!--配置连接池2,可以配置多个-->

分类属性描述必须项user用户名password密码driverClass驱动jdbcUrl路径基本配置initialPoolSize连接池初始化时创建的连接数,默认3maxPoolSize连接池中拥有的最大连接数,默认15minPoolSize连接池保持的最小连接数,默认10maxIdleTime连接的最大空闲时间,如果超过此时间某个数据库还没有被使用,则会断开这个连接;如果为0,则永远不断开连接。默认0

3.3.3 自定义C3P0Utils工具类

//1.创建连接池对象C3P0对DATa Source接口的实现类//使用的是默认文件中的配置publicstaticComboPooledDataSource dataSource =newComboPooledDataSource();//如果要使用指定的配置,比如上文中自定义的连接池mysqlpublicstaticComboPooledDataSource dataSource =newComboPooledDataSource("mysql");//获取连接的方法publicstaticConnectiongetConnection(){return dataSource.getConnection();}//释放资源(方法重载)publicstaticvoidclose(Connection con,Statement sm,ResultSet rs){/*先判断非空*/}

3.3.4 测试

(同上,此处不赘述)

3.4 Druid连接池

由阿里巴巴开发,加入了日志监控。

3.4.1 导入jar包及配置文件

将druid-1.0.9.jar _复制到上文提到的

myjar

路径下。

将druid.properties _复制到src或自定义资源文件夹下。

3.4.2 修改配置参数(注意编码UTF-8)

3.4.3 自定义DruidUtils类

此处需要通过工厂类DruidDataSourceFactory类的CreateDataSource()方法来获取对象,并使用Properties对象的load方法来读取配置信息。

publicstaticDataSource dataSource;static{//1.创建属性集对象Properties p =newProperties();//2.指定加载的配置文件InputStream ins =DruidUtils.class.getClassloader().getResourceAsStream("druid.properties");//3.调用Properties对象的load方法从字节流中读取配置信息
    p.load(ins);//4.通过工厂类获取连接池对象
    dataSource =DruidDataSourceFactory.createDataSource(p);}//5.获取连接的方法publicstaticConnectiongetConnection(){};//6.释放资源的方法publicstaticvoidclose(Connection con,Statement st,ResultSet rs){/*先判断非空*/}

4 DBUtils工具类

Commons DBUils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,能够在保证性能的同时简化程序开发。

4.1 配置

导入配置文件,将commons-dbutils-1.6.jar _复制到上文提到的

myjar

路径下。

4.2 QueryRunner类

4.2.1 增删改操作

//1.创建QueryRunner对象QueryRunner qr1 =newQueryRunner();//手动模式QueryRunner qr2 =newQueryRunner(DruidUtils.getDataSource());//自动模式,传入的是连接池//2.编写占位符方式的SQL语句String sql ="insert into table_name values(?,?,?)";//3.设置占位符的参数Object[] param ={null,"张san",20};//4.执行update方法Connetion con1 =DruidUtils.getConnection();int i = qr.update(con,sql,param);//手动模式int ii = qr.update(sql,param);//自动模式不需要传入Connection对象//5.释放资源DBUtils.closeQuery(con);

4.2.2 查询操作

需要用到ResultSetHandler实现类

查询方法为

query(String sql,handler,Object[] param)

query(Connection con,String sql,hadler,Object[] param)

ResultSetHandler实现类说明ArrayHandler将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值ArrayListHandler将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组再封装到List集合中BeanHandler将结果集中第一条记录封装到指定的javaBean中BeanListHandler将结果集中每一条记录封装到指定的javaBean中,再将这些javaBean封装到List集合中ColumnListHandler将结果集中指定的列的字段值,封装到一个List集合中KeyedHandler将结果集中每一条记录封装到Map<String,Object>,再将这个Map集合作为另一个Map的value,另一个Map集合的key是指定的字段的值MapHandler将结果集中第一条记录封装到了Map<String,Object>集合中,key是字段名称,value是字段值MapListHandler将结果集中每一条记录封装到了Map<String,Object>集合中,key是字段名,value是字段值,再将这些Map封装到List集合中ScalarHandler用于封装单个数据,例如

select count(*) from table_name

操作

//举例说明//1.创建QueryRunnerQueryRunner qr =newQueryRunner(DruidUtils.getDataSource());//2.编写SQLString sql ="select * from table_name";//3.执行查询,封装到ArrayList集合中,封装到其他集合亦类似List<Object[]> query = qr.query(sql,newArrayListHandler());//4.打印for(Object[] objects:query){System.out.println(Arrays.toString(objects));}

4.3 封装到javaBean

QueryRunner qr =newQueryRunner(DruidUtils.getDataSource());String sql ="select * from table_name where id=?";Employee employee = qr.query(sql,newBeanHandler<Employee>(Employee.class),3);

5 批处理

5.1 方法简介

方法说明void addBatch()将给定的SQL命令添加到此Statement对象的当前命令列表中,通过调用方法executeBatch可以批量执行此列表中的命令int executeBatch()每次提交一批命令到数据库中执行,如果所有的命令都成功执行了,那么返回一个数组,这个数组是说明每条命令所影响的行数

5.2 开启批处理

MySQL默认是关闭批处理的,开启需要在Druid的properties文件中的url后添加如下语句:

url=jdbc:mysql://IP地址:3306/数据库名?characterEncoding=UTF-8&rewriteBatchedStatements=true

5.3 操作介绍

//1.获取连接Connection con =DruidUtils.getConnection();//2.获取预处理对象PreparedStatement ps = connection.prepareStatement(sql语句);//3.执行批量插入操作for(int i=0;i<1000;i++){
    ps.setString(1,"张三");//将SQL添加到批处理列表
    ps.addBatch();}//4.统一执行
ps.executeBatch();//5.关闭连接DruidUtils.close(connection,ps);

6 元数据

包含查询结果信息:UPDATE或DELETE语句受影响的记录数。

数据库和数据表的信息:结构信息。

MySql服务器信息:当前状态、版本号等。

6.1 JDBC获取

获取元数据对象的方法为getMetaData()

  • 如果是Connection对象调用该方法,则获取的是DatabaseMetaData数据库元数据对象。
  • 如果是PrepareStatement预处理对象调用该方法,则获取的是ResultSetMetaData结果集元数据对象。

6.2 方法介绍

获取元数据方法

元数据对象具体方法方法说明DatabaseMetaDatagetURL()获取数据库的URLgetUser()获取当前数据库的用户名getDatabaseProductName()获取数据库的产品名称(数据库类型)getDatabaseProductVersion()获取数据库的版本号getDriverName()返回驱动程序名称isReadOnly()判断数据库是否只允许读,true表示只读

6.3 方法运用

1.获取数据库相关的元数据信息,使用DatabaseMetaData

//1.获取数据库连接对象Connection con =DruidUtils.getConnection();//2.获取代表数据库的元数据对象DatabaseMetaData metaData = con.getMetaData();//3.获取数据库相关的元数据信息String url = metaData.getURL();String userName = metaData.getUserName();//4.释放资源
con.close();

2.获取结果集中的元数据信息

//1.获取数据库连接Connection con =DruidUtils.getConnection();//2.获取预处理对象PreparedStatement ps = con.prepareStatement(SQL语句);ResultSet rusultSet = ps.executeQuery();//3.获取结果集元数据对象ResultSetMetData metaData = ps.getMetaData();//4.获取结果集信息int count = metaData.getColumnCount();System.out.println(count);//5.释放资源DruidUtils.close(con,ps,resultSet);

7 XML

XML即可扩展性标记语言,与HTML相比标签为自定义、语法严格。可用于:

  • 存储数据,与properties文件类似。
  • 作为配置文件。
  • 在网络中传递数据。

7.1 语法格式

<!-- 1.XML中必须进行文档声明,且必须在第一行
    version版本信息
    encoding 编码
--><?xml version="1.0" encoding="UTF-8" ?><!-- 2.XML的注释 --><!-- 3.标签区分大小写;定义不能有空格或者冒号;属性必须在标签开头--><user><nameid="1"></name><nameid="2"></name><age><labelcommon>内容为文本的标签</labelcommon><insidelabel></insidelabel></age><emptylabel/></user><!-- 4.XML中有且只有一个根元素,就是最外面包裹的那个标签,比如上文中的user标签--><!-- 5.XML中元素可以是文本或标签,支持标签嵌套--><!-- 6.空标签,如上文中的emptylabel标签-->

7.2 XML约束**

约束文档是由框架提供的,指导XML编写。

约束文件开头需要指定xml版本号等信息:**

<?xml version="1.0" encoding="UTF-8" ?>

**

7.2.1 DTD约束

DTD(Document Type Definition),文档类型定义,用来约束XML文档,规定XML文档中元素的名称,子元素的名称及顺序,元素的属性等。

<!ELEMENT students(student+)>
    <!ELEMENT student(name,age,sex)>
    <!ELEMENT name(#PCDATA)>
    <!ELEMENT age(#PCDATA)>
    <!ELEMENT sex(#PCDATA)>
    <!ATTLIST student number ID #REQUIRED>
<!-- 各部分解释
    ELEMENT:定义元素
    students:表示根元素
    student+:根标签中至少有一个student子元素
    student(name,age,sex):student标签中可以包含的子元素,必须按顺序出现
    #PCDATA:普通的文本内容
    ATTLIST:用来定义属性
    student number ID:student标签中,有一个ID属性,叫做number
    #REQUIRED:number的属性必须填写,ID唯一,值只能是字母或下划线开头。
  • 引用

将.dtd文件放到项目package中,而后在.xml文件中添加引用。

//语法格式<!DOCTYPE 根元素名 SYSTEM ".dtd文件路径">

7.2.2 Schema约束

本身是XML文档,但Schema文档的扩展名为xsd

内置多种简单和复杂的数据类型

支持命名空间,一个XML中可以引入多个约束文档

  • 引用
<?xml version="1.0" encoding="UTF-8" ?><studentsxmlns="http://wwww.gfcq.com/xml"<!--表示使用的命名空间-->
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!--引入W3C的标准命名空间,指定数据类型 -->
          xsi:schemaLocation="http://www.gfcq.com/xml student.xsd" <!--指定.xsd文档的路径 -->
>
          <!-- 具体的内容--></students>

7.3 XML解析

7.3.1 解析方式

  1. DOM方式> 将整个XML读取到内存,生成一个document对象。- 元素之间由结构关系,可以进行CRUD- 占用的内存多,容易内存溢出
  2. SAX方式> 边扫描边解析,速度更快。- 占用内存少,速度快- 只能进行解析操作

7.3.2 解析器DOM4jAPI

  1. 配置复制dmo4j-1.6.1.jar _到上文提到的myjar路径下。
  2. 解析//1.获取解析对象SAXReader reader =newSAXReader();//2.解析XML获取文档对象Document doc = reader.read("E:\\jdbc_work\\..\\user.xml");//3.获取根元素Element rootElement = doc.getRootElement();//4.获取子节点List<Element> elements = rootElement.elements();//5.获取集合中的第一个子节点Element user = elements.get(0);//6.获取属性String id = user.attributeValue("id");//获取属性id的值String name = user.elementText("name");

7.4 XPath

基本的XPath语法类似于在一个文件系统中定位问渐渐,如果路径以斜线/开始,那么该路径就表示到一个元素的绝对路径

7.4.1 导入配置文件

复制jaxen-1.1-beta-6.jar _到上文提到的

myjar

路径下。

7.4.2 使用XPath解析XML文件

比如给定这样一个XML文件

book.xml

<?xml version="1.0" encoding="UTF-8" ?><bookstore><bookid="book1"><name>水浒传</name><author>施耐庵</author><price>99</price></book><bookid="book2"><name>西游记</name><author>吴承恩</author><price>99</price></book></bookstore>
  1. 使用selectSingleNode()方法查询自定的节点信息//1.创建XML解析对象SAXReader reader =newSAXReader();//2.解析XML获取文档对象Document doc = reader.read(文件全路径"H:\\jdbc_work\\xmltask\\src\\com\\...\\book.xml);//3.获取name节点Node node1 = doc.selectSingleNode("/bookstore/book/name");//4.获取第二本书的书名Node node2 = doc.selectSingleNode("/bookstore/book[2]/name");String bookname2 = node2.getText();
  2. 使用selectSingleNode()方法获取属性值或者通过属性值获取节点信息SAXReader reader =newSAXReader();Document doc = reader.read(路径);//1.获取第一个book节点中的id属性值Node node1 = doc.selectSingleNode("/bookstore/book/attribute::id");//2.获取最后一个book节点的id属性值Node node2 = doc.selectSingleNode("bookstore/book[last()]/attribute::id");String bookid = node2.getText()://3.通过id的值获取book2节点中的书名Node node3 = doc.selectSingleNode("/bookstore/book[@id='book2']");
  3. 使用selecNode()方法获取所有指定名称的节点SAXReader reader =newSAXReader();Document doc = reader.read(路径);//1.查询所有节点List<Node> list1 = doc.selectNodes("//");//2.获取所有书名List<Node> list2 = doc.selectNodes("//name");//3.获取id属性为book1的节点中所有的内容List<Node> list3 = doc.selectNodes("bookstore/book[@id='book1']//*")

7.5 JDBC自定义XML

7.5.1 创建配置文件

jdbc-config.xml
<?xml version="1.0" encoding="UTF-8" ?><jdbc><propertyname="driverClass">com.mysql.jdbc.Driver</property><propertyname="jdbcUrl">jdbc:mysql:localhost:3306/db?characterEncoding=UTF-8</property><propertyname="user">root</property><p-rotertyname="password">123456</p-roterty></jdbc>

7.5.2 创建工具类

//1.定义字符串变量,保存连接信息publicstaticString DRIVERNAME;publicstaticString URL;publicstaticString USER;publicstaticString PASSWORD;//2.静态代码块static{//使用XPath语法对xml中的数据进行读取SAXReader reader =newSAXXReader();Document doc = reader.read(xml文件路径);//1.获取驱动名称Node driver = document.selectSingleNode("/jdbc/property[@name='driverClass']");
    DRIVERNAME = driver.getText();//2.获取URLNode url = doc.selectSingleNode("/jdbc/property[@name='jdbcUrl']");
    URL = url.getText();//3.获取用户名NodeUser= doc.selectSingleNode("/jdbc/property[@name='user']");
    USER = user.getText();//4.获取密码Node password = doc.selectSingleNode("/jdbc/property[@name='password']");
    PASSWORD = password.getText();//5.注册驱动Class.forNmae(DRIVERNAME);}//获取连接publicstaticConnectiongetConnection(){Connection con =DriverManager.getConnection(URL,USER,PASSWORD);return con;}
标签: java xml

本文转载自: https://blog.csdn.net/FisrtBqy/article/details/123699667
版权归原作者 FisrtBqy 所有, 如有侵权,请联系我们删除。

“JDBC和XML”的评论:

还没有评论