java操作数据库以及使用c3p0

java操作mysql数据库

环境

jdbc驱动下载
下载与平台无关的Platform Independent,下载zip格式(注意版本问题,点Looking for previous GA versions?是以前版本)

jdbc操作

jdbc编程五个步骤:1,加载驱动;2,打开链接;3,执行查询;4,处理结果;5,清理环境

  • 链接并查询:
    包都引用自java.sql.*
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String sql = "SELECT * FROM tbl_user";
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/temp","root","6");
    Statement st = conn.createStatement();
    ResultSet rs = st.executeQuery(sql);
    while(rs.next()) {
    System.out.println(rs.getInt("id"));
    System.out.println(rs.getString("name"));
    System.out.println(rs.getString("password"));
    System.out.println(rs.getString("email"));
    System.out.println();
    }

弄完了把rs,st,conn按顺序关闭

  • 插入语句:

    1
    2
    3
    4
    5
    6
    String sql = "insert into tbl_user(name,password,email) values('tom','tom123','tom@qq.com'),('jack','jack123','jack@qq.com')" ;
    Class.forName("com.mysql.jdbc.Driver");
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/temp","root","6");
    st = conn.createStatement();
    int count = st.executeUpdate(sql);
    System.out.println(count);
  • count是更新记录的条数

  • 更新语句:
    和插入一样,sql语句变一下

    1
    sql="update tbl_user SET email='tom@qq.com' where name='jack'"
  • 删除语句:
    和上面一样,sql语句变一下

    1
    sql="delete from tbl_user where name='tom'";

事务:

  1. 执行多个语句,都要用同一个Connection链接
  2. conn.setAutoCommit(false)禁止事务自动提交
  3. 然后最后执行一下conn.commit()就行了
  4. 在catch语句中调用conn.rollback()回滚事务

java读取properties

java有properties类专门读取.properties文件

1
2
3
4
5
6
7
8
9
InputStream in = this.getClassLoader().getResourctAsStream(filename)
Properties prop = new Properties()
prop.load(in);
//获取数据:
prop.getproperty(name)
//静态变量可以在静态代码块中赋值,只会在加载类的时候执行一次
static{
//静态变量的赋值语句
}

优化:

  • 单例模式创建链接管理类
  • 可以使用PrepareStatement类管理修改信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //插入:
    PreparedStatement ps = conn.prepareCall("INSERT INTO tbl_name(name,password,email) values(?,?,?)")
    ps.setString(1,"username")
    ps.setString(2,"password")
    ps.setString(3,"email")
    ps.execute();
    //修改:
    String updateSql = "UPDATE tbl_name SET name=? ,password=?,email=? where id=?"
    PrepareStatement ps = conn.prepareStatement(updateSql)
    ps.setString(1,"name")
    ps.setString(2,"password")
    ps.setLong(4,1)
    ps.execute()
    //删除和修改一样,修改相应的sql语句即可
    注意编号是从1开始,填补上面语句中的问号

java使用c3p0操作数据库

java的数据库池管理工具百度百科
下载地址
使用lib目录下的jar

  1. 首先在src目录创建一个c3p0-config.xml(不能错),所有的参数请点这里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
    <named-config name = "mysql">
    <!-- 配置数据库用户名 -->
    <property name="user">root</property>
    <!-- 配置数据库密码 -->
    <property name="password">password</property>
    <!-- 配置数据库链接地址 -->
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/temp?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=true</property>
    <!-- 数据库驱动 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <!-- 连接池在无空闲连接可用时一次性创建的新数据库连接数,default : 3 -->
    <property name="acquireIncrement">5</property>
    <!-- 初始化连接数 -->
    <property name="initialPoolSize">10</property>
    <!-- 最小连接数 -->
    <property name="minPoolSize">5</property>
    <!-- 连接池中保留的最大连接数.default: 15 -->
    <property name="maxPoolSize">30</property>
    <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
    <property name="maxStatements">100</property>
    <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
    <property name="maxStatementsPerConnection">10</property>
    <!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default: 3-->
    <property name="numHelperThreads">3</property>
    <!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->
    <property name="propertyCycle">10</property>
    <!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出 SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
    <property name="checkoutTimeout">2000</property>
    <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
    <property name="idleConnectionTestPeriod">10</property>
    <!--最大空闲时间,20秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
    <property name="maxIdleTime">20</property>
    <!-- 配置链接的生存时间,超过这个时间的链接将由连接池自动断开丢弃掉,当然正在使用的链接不会马上断开,而是等待他close再断开 -->
    <property name="maxIdleTimeExcessConnections">5</property>
    <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
    <property name="acquireRetryDelay">1000</property>
    <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。Default: null-->
    <property name="automaticTestTable">Test</property>
    <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->
    <property name="testConnectionOnCheckin">true</property>
    </named-config>
    </c3p0-config>
  2. 创建一个链接管理类
    ConnectionManager.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    package cn.xwmdream.db;

    import java.sql.Connection;
    import java.sql.SQLException;

    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import com.mchange.v2.c3p0.DataSources;

    public class ConnectionManager {

    private static ConnectionManager instance;
    private ComboPooledDataSource ds;
    private ConnectionManager() throws Exception{
    ds = new ComboPooledDataSource("mysql");
    }
    /**
    * 单例模式获取数据库管理连接对象
    * */
    public static final ConnectionManager getInstance() {
    if(instance==null) {
    try {
    instance = new ConnectionManager();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return instance;
    }

    /**
    * 为了线程安全,同步
    * */
    public synchronized final Connection getConnection() {
    try {
    return ds.getConnection();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return null;
    }


    @Override
    protected void finalize() throws Throwable {
    DataSources.destroy(ds);//关闭datasource
    super.finalize();
    }
    }
  3. 使用代理模式创建一个结果集处理接口
    IResultSetUtil.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package cn.xwmdream.db;

    import java.sql.ResultSet;
    import java.sql.SQLException;
    /**
    * 处理ResultSet的接口
    */
    public interface IResultSetUtil {
    public Object doHandler(ResultSet rs)throws SQLException;
    }
  4. 创建一个数据库操作类
    DBUtil.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    package cn.xwmdream.db;

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    public class DBUtil {
    /**
    * 从c3p0连接池中获取数据库连接对象
    */
    public static Connection getConnection() {
    Connection conn = null;
    conn = ConnectionManager.getInstance().getConnection();
    return conn;
    }

    /**
    * 释放资源
    */
    public static void close(Connection conn, PreparedStatement psmtStatement, ResultSet resultSet) {
    if (resultSet != null) {
    try {
    resultSet.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if (psmtStatement != null) {
    try {
    psmtStatement.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if (conn != null) {
    try {
    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }

    /**
    * 增删改的通用方法
    */
    public static int executeUpdate(String sql,Object...objects) {
    int result = 0;
    Connection conn = null;
    PreparedStatement psmt = null;
    try {
    conn = getConnection();
    psmt = conn.prepareStatement(sql);
    if(objects!=null) {
    for(int i=0;i<objects.length;i++) {
    psmt.setObject(i+1, objects[i]);//下标从1开始
    }
    }
    result = psmt.executeUpdate();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    finally {
    close(conn,psmt,null);
    }
    return result;
    }
    /**
    * 查询通用方法
    */
    public static Object executeQuery(String sql,IResultSetUtil rsHandler,Object...objects) {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
    connection = getConnection();
    preparedStatement = connection.prepareStatement(sql);
    if (objects != null) {
    for(int i=0;i<objects.length;i++) {
    preparedStatement.setObject(i+1, objects[i]);
    }
    }
    resultSet = preparedStatement.executeQuery();
    return rsHandler.doHandler(resultSet);
    } catch (SQLException e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }
    return null;
    }

    /**
    * 查询单个字段值的通用的方法
    * */
    public static Object executeQuery(String sql,Object...objects) {
    return executeQuery(sql,new IResultSetUtil() {

    @Override
    public Object doHandler(ResultSet rs) throws SQLException {
    Object object = null;
    if(rs.next()) {
    object = rs.getObject(1);//第一列的值就是1,第二列的值,就是2
    }
    return object;
    }

    },objects);
    }
    }
  5. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //获得一个链接对象
    System.out.println(DBUtil.getConnection());
    //获取user表id等于1的第一个值的name字段
    System.out.println(DBUtil.executeQuery("select name from user where id=?", 1));

    //获取user表id等于1的结果集
    System.out.println(DBUtil.executeQuery("select * from user where id=?", new IResultSetUtil() {
    @Override
    public Object doHandler(ResultSet rs) throws SQLException {
    return rs;
    }
    }, 1));

    //插入一个id等于2,name为haha的值
    System.out.println(DBUtil.executeUpdate("insert into user (id,name)values(?,?)",2, "haha"));