从零开始学Java-10 数据库开发

目录

一、JDBC

1、核心API

1.1 注册驱动:

 1.2 连接数据库并获得连接对象

1.3 JDBC之数据库工具类(JDBCUtil)

二、数据库连接池

1、C3P0 

1.1 纯代码方式

1.2 配置文件方式

2、DBCP   

2.1 纯代码方式

2.2 配置文件方式

2.3 DBCP连接池工具类

2.4 DbUtils

三、ResultSetHandler 接口常用实现类

1、ArrayHandler

2、ArrayListHandler

3、BeanHandler

4、BeanListHandler

5、MapHandler

6、MapListHandler

7、ColumnListHandler

8、KeyedHandler

9、ScalarHandler

四、事务

1、MySQL 事务处理方式

2、事务的特性

2.1 ACID

2.2 隔离级别


一、JDBC

数据库连接技术(通过Java代码操作数据库)Java DataBase Connectify 

1、核心API

Driver :接口,数据库驱动。

Connection:接口,数据库连接对象。

Statement:接口,对数据库进行增删改查的对象。

ResultSet:接口,用来封装满足查询条件的结果集。

DriverManger:类,用来注册和管理数据库驱动的类。

1.1 注册驱动:

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

注册驱动

* 从JDK1.6之后,JDBC的版本已经是4.0,可以不用手动注册驱动了。 

* Class.forName("com.mysql.jdbc.Driver");该行代码可以省略了,  

 * 但是一般为了兼容以前的代码,一般还会保留注册驱动的代码。

 1.2 连接数据库并获得连接对象

Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.100.54:3306/test","root","root");

/* 通过DriverManager类提供的方法获得,方法如下:

         * static Connection getConnection(String url, String user, String password) 

         * 与数据库建立连接,获得连接对象。 

         * url:数据库连接URL字符串

         * user:用户名,比如:root

         * password:密码,比如:root

数据库连接URL字符串格式:

       * JDBC协议:子协议://数据库服务器地址:数据库端口号/数据库名;

      * JDBC协议是一个固定的协议:jdbc

      * 子协议:数据库厂商的名称,比如Mysql数据库子协议:mysql

      * MySQL数据库的URL字符串格式

      * jdbc:mysql://localhost:3306/day24

 * 简化格式:

      * jdbc:mysql:///数据名;

      * 前提条件:服务器必须是本机,端口号默认是3306
*/

//获得statement声明对象

Statement stmt = conn.createStatement

String sql = "------------";

//执行SQL语句

int row = stmt.excuteUpdate(sql)//对数据库进行增删改操作,返回被影响的行数

Resultset rs = stmt.excuteQuery(sql)//对数据库进行查询操作,返回一个结果

rs.next();//指针下移一行,且判定当前是否有记录,返回一个boolean值

rs.get(列名)

1.3 JDBC之数据库工具类(JDBCUtil)

/**
 * JDBC的工具类
 */
public class JDBCUtil {
private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3308/test";
private static final String USER = "root";
private static final String PASSWORD = "root";
// 在类加载的时候会执行一次
static {
        try {
// 注册驱动
Class.forName(DRIVER_CLASS);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
        }
    }
/**
* 获得连接对象
*/
public static Connection getConnection(){
try {
// 获得连接对象
    return DriverManager.getConnection(URL, USER, PASSWORD);
            } catch (Exception e) {
            e.printStackTrace();
        return null;
        }
}
/**
* 关闭资源
* @param conn 连接对象
* @param stmt SQL执行对象
*/
public static void close(Connection conn,Statement stmt){
    close(conn,stmt,null);
}
/**
* 关闭资源
* @param conn 连接对象
* @param stmt SQL执行对象
* @param rs  结果集对象
*/
public static void close(Connection conn,Statement stmt,ResultSet rs){
    try {
        if (rs != null)
            rs.close(); // 关闭资源
        } catch (SQLException e) {
            e.printStackTrace();
        }
    try {
        if (stmt != null)
            stmt.close(); // 关闭资源
        } catch (SQLException e) {
            e.printStackTrace();
        }
    try {
        if (conn != null)
            conn.close(); // 关闭连接
        } catch (SQLException e) {
            e.printStackTrace();}}}

二、数据库连接池

Java官方为数据库连接池提供了一个接口:javax.sql.DataSource;

只要实现了该接口的类就是连接池,创建该实现类的对象就是连接池对象。

常见的连接池有 C3P0和DBCP

1、C3P0 

jar包:c3p0-0.9.2-pre5.jar和mchange-commons-java-0.2.3.jar

1.1 纯代码方式

ComboPooledDataSource ds = new ComboPooledDataSource();// 创建连接池对象 
ds.setDriverClass("com.mysql.jdbc.Driver");// 设置数据库参数设置驱动类
ds.setJdbcUrl("jdbc:mysql://10.211.55.3:3306/test");// 设置数据库连接URL字符串
ds.setUser("root");// 设置用户名
ds.setPassword("root");// 设置密码
// 设置连接池参数
ds.setInitialPoolSize(5);// 设置初始连接数 
ds.setMaxPoolSize(10);// 设置最大连接数
ds.setCheckoutTimeout(3000);// 设置最大等待时间:毫秒
ds.setMaxIdleTime(2000);// 设置最大空闲时间
for (int i = 0; i < 11; i++) {
    Connection conn = ds.getConnection();// 从连接池中获得连接对象 
    System.out.println(conn);
    if(i == 5) {
        conn.close();
        }}}// 不是真正关闭,而是放回连接池中。

1.2 配置文件方式

文件要求  :  命名为 c3p0-config.xml         直接存储在src目录下

文件内容

<c3p0-config>
    <!-- 命名的配置 -->
    <named-config name="demo">
        <!-- 连接数据库的4项基本参数 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/db</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 如果池中数据连接不够时一次增长多少个 -->
        <property name="acquireIncrement">5</property>
        <!-- 初始化连接数 -->
        <property name="initialPoolSize">20</property>
        <!-- 最小连接受 -->
        <property name="minPoolSize">10</property>
        <!-- 最大连接数 -->
        <property name="maxPoolSize">40</property>
        <!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
        <property name="maxStatements">0</property>
        <!-- 连接池内单个连接所拥有的最大缓存statements数 -->
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<!--
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/db</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>
        <user-overrides user="test-user">
            <property name="maxPoolSize">10</property>
            <property name="minPoolSize">1</property>
            <property name="maxStatements">0</property>
        </user-overrides>
</default-config>
-->

* 使用配置文件使用c3p0:

ComboPooledDataSource ds = new ComboPooledDataSource("demo");// 创建连接池对象:命名配置
    for (int i = 0; i < 11; i++) {
        Connection conn = ds.getConnection();//从连接池中获得连接对象
        System.out.println(conn);
        }
 // 使用配置文件使用c3p0:默认配置
public static void test02() throws Exception{    
    ComboPooledDataSource ds = new ComboPooledDataSource();//创建连接池对象:默认配置  
    for (int i = 0; i < 10; i++) {
        Connection conn = ds.getConnection();//从连接池中获得连接对象   
        System.out.println(conn); if(i == 5) {
        conn.close();}}//不是真正关闭,而是放回连接池中。  

C3P0连接池工具类

* C3P0连接池工具类

public class C3P0Util {
private static DataSource ds = new ComboPooledDataSource();// 创建数据源     
public static DataSource getDataSource(){return ds;}// 返回数据源对象:连接池对象
public static Connection getConnection(){//返回连接对象
    try {
        return ds.getConnection();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }}}

2、DBCP   

 jar包:commons-dbcp-1.4.jar:连接池的核心包和commons-pool-1.6.jar:支持包

2.1 纯代码方式

BasicDataSource ds = new BasicDataSource();// 创建连接池对象
ds.setDriverClass("com.mysql.jdbc.Driver");// 设置数据库参数设置驱动类
ds.setUrl("jdbc:mysql://10.211.55.3:3306/test");// 设置数据库连接URL字符串 
ds.setUser("root");// 设置用户名
ds.setPassword("root");// 设置密码
// 设置连接池参数
ds.setInitialPoolSize(5);// 设置初始连接数
ds.setMaxActive(10);// 设置最大连接数
ds.setMaxIdle(8);// 最大空闲连接数
ds.setMaxWait(2000);// 最大等待时间
for (int i = 0; i < 11; i++) {
    Connection conn = ds.getConnection();// 获得连接对象(重写toString方法) 
    System.out.println(conn.hashCode());
    if(i == 5) {
        conn.close();
       }} // 将连接对象放回连接池中,等待下一次复用     

2.2 配置文件方式

文件要求  :  命名为 xxxx.properties      放在src文件夹下

文件内容

# database connectivity configuration
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.43.47:3308/test
username=root
password=root
# connectivity pool configuration
initialSize=5
maxActive=8
maxIdle=8
maxWait=2000
Properties info = new Properties();// 创建属性集合
info.load(DBCPDemo01.class.getResourceAsStream("/dbcp.properties"));
DataSource ds = BasicDataSourceFactory.createDataSource(info);// 创建连接池对象
for (int i = 0; i < 9; i++) {
    Connection conn = ds.getConnection();// 获得连接对象(重写toString方法)
    System.out.println(conn.hashCode());
    if(i == 5) {
        conn.close();
    }}}// 将连接对象放回连接池中,等待下一次复用

2.3 DBCP连接池工具类

// DBCP连接池工具类
public class DBCPUtil {
private static DataSource ds;//数据源对象 
static {// 静态代码块中创建数据源对象          
    try {
        Properties info = new Properties();// 创建属性集合 
        info.load(DBCPDemo01.class.getResourceAsStream("/dbcp.properties"));
        ds = BasicDataSourceFactory.createDataSource(info);// 创建连接池对象 
        } catch (Exception e) {  e.printStackTrace();}}
public static DataSource getDataSource(){return ds;}//返回数据源方法
public static Connection getConnection(){//返回连接对象
try {
    return ds.getConnection();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }}}

2.4 DbUtils

可以简化JDBC复杂的代码操作

jar包:commons-dbutils-1.6.jar和commons-logging-1.1.3.jar

Query Runner:类,可以简化对数据库的增删改查操作的代码;

ResultSetHandler:接口, 提供了封装结果集的策略;

DBUtils:工具,提供了与关闭资源和事务处理相关的方法.

DbUtils.closeQuietly(conn);// 安静的关闭连接对象:不抛出异常
QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());// 创建查询器对象
int row = qr.update("delete from user where id = ?;",3);// 执行插入操作
QueryRunner qr = new QueryRunner();// 创建查询器对象
conn = DBCPUtil.getConnection();// 获得连接对象
int row = qr.update(conn,"delete from user where id = ?;",4);// 执行插入操作
(sql,ResultSetHandler.rsh)//查询query

三、ResultSetHandler 接口常用实现类

1、ArrayHandler

将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值。常用于只有一条记录的情况。

// 创建查询器对象                        
QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
// 根据id查询用户信息               
Object[] objs = qr.query("select * from user where id = ?;", new ArrayHandler(),1);                     
System.out.println(Arrays.toString(objs));

2、ArrayListHandler

将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。

// 根据所有用户信息            
List<Object[]> list = qr.query("select * from user;", new ArrayListHandler());
// 遍历集合                            
for (Object[] objs : list) {
    System.out.println(Arrays.toString(objs));
}

3、BeanHandler

将结果集中第一条记录封装到一个指定的JavaBean中。前提:表的列名与JavaBean属性名要相同。常用于只有一条记录的情况。

// 根据所有用户信息                
User user = qr.query("select * from user;", new BeanHandler<User>(User.class));                         
System.out.println(user);

4、BeanListHandler

将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中

// 根据所有用户信息        
List<User> users = qr.query("select * from user;", new BeanListHandler<User>(User.class));                          
for (User user : users) {                          
    System.out.println(user);
}

5、MapHandler

将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值

// 查询用户信息                
Map<String,Object> map = qr.query("select * from user where id = 2;", new MapHandler());                            
System.out.println(map);

6、MapListHandler

将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,再将这些Map封装到List集合中。

// 查询用户信息  
List<Map<String,Object> > list = qr.query("select * from user;", new MapListHandler());
for (Map<String, Object> map : list) {
    System.out.println(map);
}

7、ColumnListHandler

将结果集中指定的列的字段值封装到一个List集合中。通常用于多行单列的查询结果集.集合中的元素类型与列的类型要相同。

// 查询所有用户姓名            
List<String> list = qr.query("select * from user;", new ColumnListHandler<String>("username"));
System.out.println(list);

8、KeyedHandler

将多条记录封装成一个Map,取其中的一列做为键,记录本身做为值,这个值是Map集合,封装这一条记录。即:Map<某列类型,Map<字段名,字段值>>,其中KeyedHandler指定为<某列的类型>(列名)。

// 查询所有用户信息
Map<String,Map<String,Object>> map = qr.query("select * from user;", new KeyedHandler<String>("username"));
Set<Entry<String, Map<String,Object>>> entrySet = map.entrySet();
for (Entry<String, Map<String, Object>> entry : entrySet) {
// 1= {id=1,username=jack,gender=男,address=广州}
// 2= {id=2,username=rose,gender=男,address=深圳}
System.out.println(entry.getKey()+"="+entry.getValue());
}

9、ScalarHandler

把结果集的第一行第一列取出。通常用于只有单行单列的聚合函数查询查询结果集。例如select count(*) from 表操作。

// 查询记录数 
long count = qr.query("select count(*) from user;", new ScalarHandler<Long>())

四、事务

  -- 将一个业务操作涉及到的多条SQL语句看成一个整体,着多条语句要么全部执行成功,要么全部执行失败,只要有一条语句执行失败,之前已经执行成功的SQL语句撤销执行.

1、MySQL 事务处理方式

自动提交方式:默认值

默认每一天SQL语句执行完之后就会自动提交事务    

set autocommit = 0 ----禁止自动提交模式(false)
set autocommit = 1 ----开启自动提交模式(true)....默认模式

手动提交模式

start transaction;  -- 开启事务
rollback;               -- 回滚事务,撤销当前执行成功的SQL语句;
commit;                --提交事务,不能再回滚

事务结束条件

commit

rollback

执行一条DDL语句,如创建一张表,事务会自动提交

开启一个新的事务,之前的事务会自动提交

connection接口中与事务相关的方法

void setAutoCommit(boolean autoCommit)=> conn.setAutoCommit(false) =>事务开启,手动提交

设置是否自动提交事务

false:手动提交,开启事务,等价于再控制台执行: tart transaction;

true:自动提交事务,默认值

void commit(); 提交事务

void rollback();回滚事务

DBUtils

//回滚事务并关闭连接对象(不会有异常)

DbUtils.rollbackAndCloseQuietly(conn);

//提交事务并关闭连接对象(不会有异常)

DbUtils.commitAndCloseQuietly(conn);

分层开发:

不同的层使用不同的包

数据访问层:

业务逻辑层

表现层

工具类

实体类

测试类

ThreadLocal类(提供了一个可以在线程内共享的局部变量)

结构:底层是一个Map集合,(key = 线程对象, value = 共享的数据)

创建ThreadLocal对象      
static ThreadLocal<T> local =  new ThreadLocal<T>();
存储数据到local中             
local.set(xxx)                            
system.out.println(local.get());
创建一个子线程对象         
new Thread(){//匿名内部类
        //重写run方法       
        public void run(){
        //存数据到子线程的local中
                    local.set(YYY)
            };
}.start();

2、事务的特性

2.1 ACID

原子性 :事务的操作是一个不可分割的单元

一致性:事务前后的数据要保存一致

隔离性:事务之间的操作互补影响

持久性:事务一旦提交,则对数据库的影响是永久的,不可逆的

2.2 隔离级别

脏读:一个事务读取到另一个事务未提交的数据一个事务在

不可重复读:一个事务多次读取的数据不一致

幻读:一个事务在查收数据记录时,前后查询不一致.一般由insert/delete引起

隔离级别

read uncommitted:最低隔离级别,存在的问题:脏读,不可重复读,幻读

read committed: 一个事务读取到了另一个事务提交了的数据,存在的问题:不可重复读,幻读    Oracle默认的隔离级别

repeatable read:一个事务多次读取的同一条数据结果一样的,存在的问题:幻读    MySQL默认的隔离级别

serializable:最高隔离级别, 串行化,同一时间只有一个事务在操作

查询全局事务隔离级别:

select @@global.tx_isolation;

设置全局事务隔离级别:

set global transaction isolation level +级别


以上为个人学习总结,如有错漏,希望能得到沟通以及指正,非常感谢!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值