本文共 18391 字,大约阅读时间需要 61 分钟。
java操作数据库.jdbc是oracle公司指定的一套规范(一套接口)驱动:jdbc的实现类.由数据库厂商提供.我们就可以通过一套规范操作不同的数据库了(多态)jdbc作用: 连接数据库 发送sql语句 处理结果
1.数据库和表2.创建一个项目3.导入驱动jar包4.编码: 注册驱动 获取连接 编写sql 创建预编译的语句执行者 设置参数 执行sql 处理结果 释放资源初始化数据库和表:
CREATE DATABASE day07;USE day07; create table category( cid varchar(20) primary key, cname varchar(20));insert into category values('c001','电器');insert into category values('c002','服饰');insert into category values('c003','化妆品');insert into category values('c004','书籍');
IDE打开之后 1.修改字符集 utf-8 2.新建 java项目 3.使用的jdk为自己的jdk 不用使用内置使用junit单元测试 要求: 1.方法是public void xxx(){} 2.在方法上添加 @Test 3.在@Test 按下 ctrl+1(快速锁定错误) 4.在方法上右键 run as -->junit 就可以执行方法了.
所有的包 都是 java.sql 或者 javax.sqlDriverManager:管理了一组jdbc的操作 类 常用方法: 了解:注册驱动 static void registerDriver(Driver driver) : 通过查看 com.mysql.jdbc.Driver的源码 有如下代码
static { try { java.sql.DriverManager.registerDriver(new Driver());//这段代码我们已经写过 } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); }}
驱动注册了两次.我们只需要将静态代码块执行一次,类被加载到内存中会执行静态代码块,并且只执行一次. 现在只需要将类加载到内存中即可: 方式1: ★Class.forName("全限定名");//包名+类名 com.mysql.jdbc.Driver 方式2: 类名.class; 方式3: 对象.getClass(); 掌握:获取连接 static Connection getConnection(String url, String user, String password) 参数1:告诉我们连接什么类型的数据库及连接那个数据库 协议:数据库类型:子协议 参数 mysql: jdbc:mysql://localhost:3306/数据库名称 oracle: jdbc:oracle:thin@localhost:1521@实例 参数2:账户名 root 参数3:密码(了解)Driver:java.sql 接口 驱动Connection:连接 接口 常用方法: 获取语句执行者: (了解)Statement createStatement() :获取普通的语句执行者 会出现sql注入问题 ★PreparedStatement prepareStatement(String sql) :获取预编译语句执行者 (了解)CallableStatement prepareCall(String sql):获取调用存储过程的语句执行者 了解: setAutoCommit(false) :手动开启事务 commit():提交事务 rollback():事务回滚Statement:语句执行者 接口PreparedStatement:预编译语句执行者 接口 常用方法: 设置参数: setXxx(int 第几个问号,Object 实际参数); 常见的方法: setInt setString setObject 执行sql: ResultSet executeQuery() :执行 r 语句 返回值:结果集 int executeUpdate() :执行cud 语句 返回值:影响的行数ResultSet:结果集 接口 执行查询语句之后返回的结果 常用方法: boolean next():判断是否有下一条记录,若有返回true且将光标移到下一行,若没有呢则返回false 光标一开始处于第一条记录的上面 获取具体内容 getXxx(int|string) 若参数为int :第几列 若参数为string:列名(字段名) 例如: 获取cname的内容可以通过 getString(2) getString("cname") 常用方法: getInt getString 也可以获取int值 getObject 可以获取任意
1.properties 里面内容的格式 key=value2.xml若我们的配置文件为properties,并且放在src目录下.我们可以通过 ResourceBundle工具快速获取里面的配置信息 使用步骤: 1.获取ResourceBundle 对象: static ResourceBundle getBundle("文件名称不带后缀名") 2.通过ResourceBundle 对象获取配置信息 String getString(String key) :通过执行key获取指定的value
@Testpublic void test2() throws Exception { //注册驱动 //DriverManager.registerDriver(new Driver()); //为什么不用DriverManager.registerDriver(new Driver());?因为Driver内部又注册了一次。 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day07", "root", "123456"); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) { String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test2---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps rs.close(); ps.close(); conn.close();}
封装 注册驱动+获取连接 和释放资源的操作:
@Testpublic void test3() throws Exception { //注册驱动 +获取连接 Connection conn = Jdbc1Utils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) { String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test3---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps Jdbc1Utils.closeResource(rs, ps, conn);}
public class Jdbc1Utils { public static Connection getConnection() throws Exception { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day07", "root", "123456"); return conn; } public static void closeResource(ResultSet rs,Statement st,Connection conn) { closeResultSet(rs); closeStatement(st); closeConnection(conn); } public static void closeResultSet(ResultSet rs) { if(null!=rs) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } rs=null; } } public static void closeStatement(Statement st) { if(null!=st) { try { st.close(); } catch (Exception e) { e.printStackTrace(); } st=null; } } public static void closeConnection(Connection conn) { if(null!=conn) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } conn=null; } }}
优化: 数据库的信息我们应该写到配置文件里面,这样改的话比较方便
@Testpublic void test4() throws Exception { Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) { String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test4---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps JdbcUtils.closeResource(rs, ps, conn);}
public class JdbcUtils { public static final String DRIVERCLASS; public static final String URL; public static final String USER; public static final String PASSWORD; //jdbc// static { // ResourceBundle bundle = ResourceBundle.getBundle("jdbc");// DRIVERCLASS = bundle.getString("driverClass");// URL = bundle.getString("url");// USER = bundle.getString("user");// PASSWORD = bundle.getString("password");// } //c3p0 // static { // ResourceBundle bundle = ResourceBundle.getBundle("c3p0");// DRIVERCLASS = bundle.getString("c3p0.driverClass");// URL = bundle.getString("c3p0.jdbcUrl");// USER = bundle.getString("c3p0.user");// PASSWORD = bundle.getString("c3p0.password");// } //dbcp static { ResourceBundle bundle = ResourceBundle.getBundle("dbcp"); DRIVERCLASS = bundle.getString("driverClassName"); URL = bundle.getString("url"); USER = bundle.getString("username"); PASSWORD = bundle.getString("password"); } static { //注册驱动 try { Class.forName(DRIVERCLASS); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws Exception { //获取连接 Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); return conn; } public static void closeResource(ResultSet rs,Statement st,Connection conn) { closeResultSet(rs); closeStatement(st); closeConnection(conn); } public static void closeResultSet(ResultSet rs) { if(null!=rs) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } rs=null; } } public static void closeStatement(Statement st) { if(null!=st) { try { st.close(); } catch (Exception e) { e.printStackTrace(); } st=null; } } public static void closeConnection(Connection conn) { if(null!=conn) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } conn=null; } }}
增:
@Testpublic void test5() throws Exception { Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); //设置参数 ps.setObject(1, "c007"); ps.setString(2, "小米手机"); int executeUpdate = ps.executeUpdate(); System.out.println("test5---executeUpdate="+executeUpdate); //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}
改:
@Testpublic void test6() throws Exception { Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("update category set cname=? where cid=?"); //设置参数 ps.setObject(1, "小米9"); ps.setString(2, "c008"); int executeUpdate = ps.executeUpdate(); System.out.println("test6---executeUpdate="+executeUpdate); //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}
删:
@Testpublic void f7() throws Exception { //获取连接 Connection conn = JdbcUtils.getConnection(); //语句执行者 PreparedStatement ps = conn.prepareStatement("delete from category where cid=?"); //执行 ps.setString(1, "c007"); int executeUpdate = ps.executeUpdate(); System.out.println("test7---executeUpdate="+executeUpdate); //释放资源 //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}
使用jdbc的时候,没操作一次都需要获取连接(创建)用完之后把连接释放掉了(销毁),通过连接池来优化curd操作.
连接池
管理数据库的连接,作用: 提高项目的性能.就是在连接池初始化的时候存入一定数量的连接,用的时候通过方法获取,不用的时候归还连接即可.所有的连接池必须实现一个接口 javax.sql.DataSource接口获取连接方法: Connection getConnection() 归还连接的方法就是以前的释放资源的方法.调用connection.close();自定义一个连接池(理解思想)
常用连接池:
DBCPC3P0
1.继承2.装饰者模式(静态代理)3.动态代理
使用步骤: 1.装饰者和被装饰者实现同一个接口或者继承同一个类 2.装饰者中要有被装饰者的引用 3.对需要增强的方法进行加强 4.对不需要加强的方法调用原来方法
apache组织 使用步骤: 1.导入jar包(commons-dbcp-1.4.jar和commons-pool-1.5.6.jar) 2.使用api a.硬编码 //创建连接池 BasicDataSource ds = new BasicDataSource(); //配置信息 ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql:///day07"); ds.setUsername("root"); ds.setPassword("1234"); b.配置文件 实现编写一个properties文件 //存放配置文件 Properties prop = new Properties(); prop.load(new FileInputStream("src/dbcp.properties")); //设置 //prop.setProperty("driverClassName", "com.mysql.jdbc.Driver"); //创建连接池 DataSource ds = new BasicDataSourceFactory().createDataSource(prop);
hibernate和spring使用 有自动回收空闲连接的功能. 使用步骤: 1.导入jar包(c3p0-0.9.1.2.jar) 2.使用api a.硬编码(不推荐) new ComboPooledDataSource() b.配置文件 配置文件的名称:c3p0.properties 或者 c3p0-config.xml 配置文件的路径:src下 编码只需要一句话 new ComboPooledDataSource()//使用默认的配置 new ComboPooledDataSource(String configName)//使用命名的配置 若配置的名字找不到,使用默认的配置
public static void main(String[] args) { MyDateSource ds = new MyDateSource(); Connection conn = ds.getConnection();// Connection conn = MyDateSource.getConnection(); System.out.println(conn); MyDateSource.addBack(conn);}
public class MyDateSource { public static LinkedListpooList=new LinkedList (); //创建3个连接,并放入集合中 static { for (int i = 0; i < 3; i++) { try { Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) { e.printStackTrace(); } } } //取任意一个连接 public static Connection getConnection() { //取之前判断连接池是否为空,为空则新增3个 if(pooList.isEmpty()) { for (int i = 0; i < 3; i++) { try { Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) { e.printStackTrace(); } } } return pooList.removeFirst(); } //归还连接 public static void addBack(Connection conn) { pooList.addLast(conn); }}
Connection 装饰者模式:
public class ConnectionWrap implements Connection { private Connection conn; private LinkedListlist; public ConnectionWrap(Connection conn,LinkedList list) { this.conn=conn; this.list=list; } @Override public T unwrap(Class iface) throws SQLException { return conn.unwrap(iface); } @Override public boolean isWrapperFor(Class iface) throws SQLException { // TODO Auto-generated method stub return false; } @Override public Statement createStatement() throws SQLException { return conn.createStatement(); } @Override public PreparedStatement prepareStatement(String sql) throws SQLException { return conn.prepareStatement(sql); } @Override public void close() throws SQLException { System.out.println("close前---"+list.size()); list.addLast(this); System.out.println("close后---"+list.size()); } ...}
自定义简易连接池:
public class MyDateSource { public static LinkedListpooList=new LinkedList (); //创建3个连接,并放入集合中 static { for (int i = 0; i < 3; i++) { try { Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) { e.printStackTrace(); } } } //取任意一个连接 public static Connection getConnection() { //取之前判断连接池是否为空,为空则新增3个 if(pooList.isEmpty()) { for (int i = 0; i < 3; i++) { try { Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) { e.printStackTrace(); } } } Connection conn = pooList.removeFirst(); ConnectionWrap wrap = new ConnectionWrap(conn, pooList); return wrap; } //归还连接 public static void addBack(Connection conn) { pooList.addLast(conn); }}
测试:
public static void main(String[] args) throws SQLException { MyDateSource ds = new MyDateSource(); Connection conn = ds.getConnection(); System.out.println(conn); conn.close();}
@Testpublic void f1() throws SQLException { //创建数据源 BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql:///day07"); ds.setUsername("root"); ds.setPassword("123456"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c008"); ps.setString(2, "苹果12"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}@Testpublic void f2() throws Exception { Properties properties=new Properties(); properties.load(new FileInputStream("src/dbcp.properties")); //创建数据源 DataSource ds = BasicDataSourceFactory.createDataSource(properties); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c009"); ps.setString(2, "苹果13"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}
dbcp.properties:
driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql:///day07username=rootpassword=123456
c3p0-0.9.1.2.jar
@Testpublic void f1() throws Exception { ComboPooledDataSource ds=new ComboPooledDataSource(); //如果默认是c3p0.properties,下面的4行可以省略 ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql:///day07"); ds.setUser("root"); ds.setPassword("123456"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c010"); ps.setString(2, "苹果10"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}
封装数据库参数:
@Testpublic void f2() throws Exception { ComboPooledDataSource ds=new ComboPooledDataSource("c3p0.properties"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c011"); ps.setString(2, "苹果11"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}
是apache组织的一个工具类,jdbc的框架,更方便我们使用使用步骤: 1.导入jar包(commons-dbutils-1.4.jar) 2.创建一个queryrunner类 queryrunner作用:操作sql语句 构造方法: new QueryRunner(Datasource ds); 3.编写sql 4.执行sql query(..):执行r操作 update(...):执行cud操作
QueryRunner:类名 作用:操作sql语句 构造器: new QueryRunner(Datasource ds); 注意: 底层帮我们创建连接,创建语句执行者 ,释放资源. 常用方法: query(..): update(..):DbUtils:释放资源,控制事务 类 closeQuietly(conn):内部处理了异常 commitAndClose(Connection conn):提交事务并释放连接 ....ResultSetHandler:封装结果集 接口 ArrayHandler, ArrayListHandler, BeanHandler, BeanListHandler, ColumnListHandler, KeyedHandler, MapHandler, MapListHandler, ScalarHandler
带有List表示结果是集合,不带list表示结果是对象(相等于取集合的第一条数据)
(了解)ArrayHandler, 将查询结果的第一条记录封装成数组,返回 (了解)ArrayListHandler, 将查询结果的每一条记录封装成数组,将每一个数组放入list中返回 ★★BeanHandler, 将查询结果的第一条记录封装成指定的bean对象,返回 ★★BeanListHandler, 将查询结果的每一条记录封装成指定的bean对象,将每一个bean对象放入list中 返回. (了解)ColumnListHandler, 将查询结果的指定一列放入list中返回 (了解)MapHandler, 将查询结果的第一条记录封装成map,字段名作为key,值为value 返回 ★MapListHandler, 将查询结果的每一条记录封装map集合,将每一个map集合放入list中返回 ★ScalarHandler,针对于聚合函数 例如:count(*) 返回的是一个Long值
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Category category = qr.query(sql, new BeanHandler<>(Category.class));System.out.println(category);
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Listlist = qr.query(sql, new BeanListHandler<>(Category.class));for (Category category : list) { System.out.println(category);}
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select count(cid) from category";Object Object = qr.query(sql, new ScalarHandler());System.out.println(Object.getClass().getName());System.out.println(Object);Long count = (Long) qr.query(sql, new ScalarHandler());System.out.println(count);
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Object[] result = qr.query(sql, new ArrayHandler());System.out.println(Arrays.toString(result))
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";List
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Mapmap = qr.query(sql, new MapHandler());System.out.println(map);
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";List
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";//无参默认第一列的值List
QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";//无参默认第一列的值Map
转载地址:http://rcdvi.baihongyu.com/