目录

数据库驱动

第一个JDBC程序

statement对象详解

SQL注入问题

PreparedStatement对象

JDBC操作事务

DBCP-C3P0连接池

DBCP

C3P0

C3P0与DBCP区别:


数据库驱动

程序会通过数据库驱动和数据库打交道

JDBC

SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(java操作数据库)的规范,俗称JDBC,这些规范的实现由具体的厂商去做,对开发人员来说,我们只需要掌握JDBC接口的操作即可

java.sql

javax.sql

还需要导入一个数据库驱动包 mysql-connector-java-5.1.47.jar

第一个JDBC程序

1.创建测试数据库

CREATE DATABASE jdbcstudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcstudy;
CREATE TABLE users(
`id` INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
`email` VARCHAR(60),
`birthday` DATE
);
INSERT INTO users(`id`,`name`,`password`,`email`,`birthday`)
VALUES(1,'小美女','5201314','1314520yyl@qq.com','1995-02-22'),
(2,'小可爱','1314520','1314520yyl@qq.com','1995-06-22'),
(3,'小仙女','7718815201314','1314520yyl@qq.com','1995-02-22');

2.导入数据库驱动

mysql-connector-java-8.0.21.jar,复制到lib文件,右击jar文件后点→add as library

3.编写测试代码

添加serverTimezone=GMT%2B8防止报错

public class jdbaFirstDemo {public static void main(String[] args) throws Exception {//1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.连接数据库String url="jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true";String name="root";String pwd="root";Connection connection = DriverManager.getConnection(url, name, pwd);//3.获取传输器statementStatement statement = connection.createStatement();//4.执行sql语句String sql="select * from users";ResultSet resultSet = statement.executeQuery(sql);//5.解析结果集while (resultSet.next()){System.out.println(resultSet.getObject("id"));System.out.println(resultSet.getObject("name"));System.out.println(resultSet.getObject("password"));}//6.释放资源resultSet.close();statement.close();connection.close();}
}

步骤总结:

  1. 加载驱动
  2. 连接数据库DriverManager
  3. 获取传输器statement
  4. 执行sql
  5. 获得返回的结果集
  6. 释放连接

加载驱动

原来是

 DriverManager.registerDriver(new com.mysql.jdbc.Driver());

由于driver底层已经帮忙注册了

public class Driver extends NonRegisteringDriver implements java.sql.Driver {public Driver() throws SQLException {}static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}}
}

所以用

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

URL

"jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true"
"协议://主机地址:端口号/数据库名?参数1&参数2&..."
MySQL默认端口号3306
Oracle默认端口号1521
jdbc:oracle:thin:@localhost:1521:sid

connection代表数据库

//connection 代表数据库
//数据库设置自动提交
//事务提交
//事务回滚

statement/PrepareStatement执行SQL的对象

statement.executeQuery();//查询操作返回ResultSet
statement.executeUpdate();//更新、插入、删除、都是用这个(sql不同),返回一个受影响的行数
statement.execute();//执行任何SQL
ResultSet查询的结果集:封装了所有的查询结果
    resultSet.getObject();//不知道列类型的情况使用//知道列类型的情况使用resultSet.getString();resultSet.getInt();resultSet.getFloat();resultSet.getDate();
ResultSet遍历,指针
        resultSet.next();//移动到下一个数据resultSet.beforeFirst();//移动到最前面resultSet.afterLast();//移动到最后面resultSet.previous();//移动到前一行resultSet.absolute(3);//移动到指定行

释放资源:

        resultSet.close();statement.close();connection.close();

statement对象详解

JDBC中的statement对象用于向数据库发送SQL语句,想完成增删改查,只需要通过这个对象向数据库发送语句即可。

statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果 的ResultSet对象。

statement.executeUpdate方法用域向数据库发送增删改的语句,executeUpdate执行完成后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)

CRUD操作-create

        String sql="insert users(`id`,`name`,`password`) values(4,'小宝贝','大长腿')";int i = statement.executeUpdate(sql);if (i>0){System.out.println("插入成功");}

CRUD操作-delete

        String sql="delete from users where id=4";int i=statement.executeUpdate(sql);if (i>0){System.out.println("删除成功");}

CRUD操作-update

        String sql="update users set `name`='我妹是小可爱' where id=1";int i=statement.executeUpdate(sql);if (i>0) {System.out.println("修改成功");}

CRUD操作-read

        String sql="select * from users";ResultSet resultSet = statement.executeQuery(sql);while (resultSet.next()){System.out.println(resultSet.getObject("id"));System.out.println(resultSet.getObject("name"));System.out.println(resultSet.getObject("password"));}

简化代码:

1.提取工具类:

src下创建db.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=root

创建jdbcUtils

public class jdbcUtils {private static String driver=null;private static String url=null;private static String username=null;private static String password=null;static{try {InputStream in = jdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");Properties properties = new Properties();properties.load(in);driver = properties.getProperty("driver");url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");//1.驱动只用加载一次Class.forName(driver);} catch (Exception e) {e.printStackTrace();}}//获取连接public static Connection  getConnection() throws SQLException {return DriverManager.getConnection(url, username, password);}//释放资源public static void release(Connection connection, ResultSet resultset, Statement statement){if (connection!=null) {try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (statement!=null) {try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (resultset!=null) {try {resultset.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}
}
返回值类型 方法 方法描述
ClassLoader getClassLoader() 返回该类的类加载器
InputStream getResourceAsStream(String name) 查找具体给定名称的资源
void properties.load(InputStream inStream) 从输入流中读取属性列表(键和元素对)
String getProperty(String key) 用指定的列在此属性列表中搜索属性

2.编写增删改查的方法

create

public class TestInsert {public static void main(String[] args) {Connection cn=null;Statement st=null;ResultSet rs=null;int num=0;try {cn=jdbcUtils.getConnection();st=cn.createStatement();String sql="insert users(`id`,`name`,`password`) values(5,'小美眉','大长腿')";num=st.executeUpdate(sql);if (num>0){System.out.println("插入成功");}} catch (SQLException throwables) {throwables.printStackTrace();} finally {jdbcUtils.release(cn, rs, st);}}
}

delete

public class deleteTest {public static void main(String[] args) {Connection cn=null;Statement sm=null;ResultSet rs=null;int num=0;try {cn=jdbcUtils.getConnection();sm=cn.createStatement();String sql="delete from users where id=5";num=sm.executeUpdate(sql);if (num>0) {System.out.println("删除成功");}} catch (SQLException throwables) {throwables.printStackTrace();} finally {jdbcUtils.release(cn, rs, sm);}}
}

update

public class updateTest {public static void main(String[] args) {Connection cn=null;Statement st=null;ResultSet rs=null;int num=0;try {cn=jdbcUtils.getConnection();st=cn.createStatement();String sql="update users set `name`='我的妹最漂亮' where id=4";num=st.executeUpdate(sql);if (num>0) {System.out.println("修改成功");}} catch (SQLException throwables) {throwables.printStackTrace();} finally {jdbcUtils.release(cn,rs,st);}}
}

read

public class selectTest {public static void main(String[] args) {Connection cn=null;Statement st=null;ResultSet rs=null;try {cn=jdbcUtils.getConnection();st=cn.createStatement();String sql="select * from users where id>0";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"));}} catch (SQLException throwables) {throwables.printStackTrace();} finally {jdbcUtils.release(cn,rs,st);}}
}

SQL注入问题

SQL存在漏洞,会被攻击,导致数据泄露,SQL会被拼接

public class sqlInjection {public static void main(String[] args) throws Exception {String username="'or '1=1";String pwd="'or '1=1";login(username,pwd);}private static void login(String username,String pwd) throws Exception {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&CharacterEncoding=utf8&useSSL=true";String name="root";String password="root";Connection cn = DriverManager.getConnection(url, name, password);Statement st = cn.createStatement();String sql="select * from users where `name` ='"+username+"' and `password`='"+pwd+"'";ResultSet rs = st.executeQuery(sql);while (rs.next()) {System.out.println(rs.getObject("name"));System.out.println(rs.getObject("password"));}rs.close();st.close();cn.close();}
}

PreparedStatement对象

PreparedStatement可以防止SQL注入,效率更好!

create

public class preparedStatementTest {public static void main(String[] args) {Connection cn=null;PreparedStatement ps=null;ResultSet rs=null;try {cn=jdbcUtils.getConnection();String sql= "insert users(`id`,`name`,`password`,`birthday`) values(?,?,?,?)";ps=cn.prepareStatement(sql);//预编译SQL//手动给参数赋值ps.setInt(1, 6);ps.setString(2,"小棉袄");ps.setString(3,"7718811314521");//setDate(数据库) java.sql//util.Date  java    new Date().getTime()获取时间戳ps.setDate(4,new java.sql.Date(new Date().getTime()));int num=ps.executeUpdate();if (num>0) {System.out.println("插入成功");}} catch (SQLException throwables) {throwables.printStackTrace();}finally {jdbcUtils.release(cn,rs,ps);}}
}

delete

public class psTestDelete {public static void main(String[] args) throws Exception {Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true";String name="root";String password="root";Connection cn = DriverManager.getConnection(url, name, password);String sql="delete from users where id=?";PreparedStatement ps=cn.prepareStatement(sql);ps.setInt(1,6);int i = ps.executeUpdate();if (i>0) {System.out.println("删除成功");}ps.close();cn.close();}
}

update

public class psTestUpdate {public static void main(String[] args) throws Exception {Class.forName("com.mysql.jdbc.Driver");Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true","root", "root");String sql="update users set `name`='我妹最可爱' where id=?";PreparedStatement ps = cn.prepareStatement(sql);ps.setInt(1,5);int i = ps.executeUpdate();if (i>0) {System.out.println("修改成功");}ps.close();cn.close();}
}

read

public class psTestRead {public static void main(String[] args) throws Exception {Class.forName("com.mysql.jdbc.Driver");Connection cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true","root", "root");String sql="select * from users where `id`=? and `name`=?";PreparedStatement ps = cn.prepareStatement(sql);ps.setInt(1,1);ps.setString(2, "我妹是小可爱");ResultSet rs = ps.executeQuery();while (rs.next()){System.out.println(rs.getObject("password"));System.out.println(rs.getObject("name"));}rs.close();ps.close();cn.close();}
}

JDBC操作事务

public class TestTransaction {public static void main(String[] args) {Connection cn=null;PreparedStatement ps=null;ResultSet rs=null;try {cn=jdbcUtils.getConnection();//关闭数据库的自动提交,自动会开启事务cn.setAutoCommit(false);//开启事务String sql1="update users set `money`=`money`-222 where id=?";String sql2="update users set `money`=`money`+222 where id=?";ps=cn.prepareStatement(sql1);ps.setInt(1,1);ps.executeUpdate();ps=cn.prepareStatement(sql2);ps.setInt(1,2);ps.executeUpdate();cn.commit();//业务完毕提交事务System.out.println("交易成功");} catch (SQLException throwables) {try {cn.rollback();//如果失败回滚事务} catch (SQLException e) {System.out.println("交易失败");e.printStackTrace();}throwables.printStackTrace();} finally {jdbcUtils.release(cn,rs,ps);}}
}

DBCP-C3P0连接池

数据库连接--执行完毕--释放,连接释放十分浪费系统资源

池化技术:准备一些预先的资源,过来就连接预先准备好的

最小连接数:10

最大连接数15

等待超时:100ms

编写连接池,实现一个接口DataSource

开源数据源实现:

DBCP

C3P0

Druid:阿里巴巴

使用了数据库连接池之后,在项目开发中就不需要编写连接数据库的代码了

DBCP

DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。

1.需要导入用到的两个jar包commons-dbcp-1.4(https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi

commons-pool-1.6(https://commons.apache.org/proper/commons-pool/download_pool.cgi)

到lib目录下

右键lib选择add as library把lib加入

2.src下创建文件dbcpconfig.properties

#连接设置 这里的名字是DBCP数据源中定义好的
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=root
#初始化连接
initialSize=10
#最大连接数
maxActive=50
#最大空闲连接
maxIdle=20
#最小空闲连接
minIdle=5
#超时等待时间以毫秒为单位   60000毫秒/1000等于60秒
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:“user”与“password”连个属性会被明确地传递,因此这里不需要包含他们
connectionProperties=useUnicode=true;characterEncoding=UTF8
#指定由连接池所创建的连接的只读(read-only)状态
defaultReadOnly=
#driver default 指定由连接池索所创建的连接的事务级别(TransationIsolation)
#可用值为下列之一:(详情可键javadoc)NONE,READ_UNCOMMITTED,REPEATABLE_READ,SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

3.编写程序insert为例

public class testDBCPinsert {public static void main(String[] args) {Connection cn=null;PreparedStatement ps=null;ResultSet rs=null;try {cn=jdbcutils_DBCP.getConnection();String sql="insert users (`id`,`name`,`password`) values (?,?,?)";ps=cn.prepareStatement(sql);ps.setInt(1,6);ps.setString(2, "我妹大长腿");ps.setString(3,"我妹白富美");int i = ps.executeUpdate();if (i>0){System.out.println("插入成功");}} catch (SQLException throwables) {throwables.printStackTrace();}}
}

C3P0

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。

需要导入用到的jar包

c3p0-0.9.5.5.jar、mchange-commons-java-0.2.19.jar到lib(https://sourceforge.net/,进入后搜索c3p0)

点进去download

先删除libraries中的lib然后apply再把lib文件加进去

src下配置c3p0-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config><named-config name="MySQL"><!-- 配置数据库用户名 --><property name="user">root</property><!-- 配置数据库密码 --><property name="password">root</property><!-- 配置数据库链接地址 --><property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=true</property><!-- 配置数据库驱动 --><property name="driverClass">com.mysql.jdbc.Driver</property><!-- 数据库连接池一次性向数据库要多少个连接对象 --><property name="acquireIncrement">20</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">0</property><!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 --><property name="maxStatementsPerConnection">0</property><!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default:3 --><property name="numHelperThreads">3</property><!--用户修改系统配置参数执行前最多等待300秒。Default: 300 --><property name="propertyCycle">3</property><!-- 获取连接超时设置 默认是一直等待单位毫秒 --><property name="checkoutTimeout">1000</property><!--每多少秒检查所有连接池中的空闲连接。Default: 0 --><property name="idleConnectionTestPeriod">3</property><!--最大空闲时间,多少秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --><property name="maxIdleTime">10</property><!--配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待它close再断开。配置为0的时候则不会对连接的生存时间进行限制。 --><property name="maxIdleTimeExcessConnections">5</property><!--两次连接中间隔时间,单位毫秒。Default: 1000 --><property name="acquireRetryDelay">1000</property><!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。Default: null --><property name="automaticTestTable">Test</property><!-- 获取connnection时测试是否有效 --><property name="testConnectionOnCheckin">true</property></named-config>
</c3p0-config>

编写程序insert为例

public class jdbcUtils_C3P0 {private  static ComboPooledDataSource dataSource=null;static {try {//代码版配置
//            dataSource=new ComboPooledDataSource();
//            dataSource.setDriverClass();
//            dataSource.setUser();
//            dataSource.setPassword();
//            dataSource.setJdbcUrl();
//            dataSource.setMaxPoolSize();
//            dataSource.setMinPoolSize();//配置文件写法dataSource=new ComboPooledDataSource("MySQL");} catch (Exception exception) {exception.printStackTrace();}}//        获取连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//释放资源public static void release(Connection connection, Statement statement, ResultSet resultSet){if (connection!=null) {try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (statement!=null) {try {statement .close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (resultSet !=null) {try {resultSet.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}
}

C3P0与DBCP区别:

C3P0有自动回收空闲连接的功能,DBCP没有

结论:

无论使用什么数据源,本质还是一样的,DataSource接口不会变,方法就不会变

数据库驱动和JDBC、DBCP-C3P0连接池相关推荐

  1. c3p0连接池与dbcp连接池的区别

    c3p0连接池与dbcp连接池的区别: c3p0有自动回收空闲连接的功能: dbcp没有自动回收空闲连接的功能: c3p0提供最大空闲时间,超时则断开当前连接: dbcp提供最大连接数,超过最大连接数 ...

  2. MyBatis配置C3P0连接池

    这两天学到Mybatis感觉就要疯了,第一次接触,我是不是应该写点笔记,下面呢,记录一下连接池的配置,防止忘了. 第一步,二话不说,先导入所需jar包(如图所示三个) 第二步,继承UnpooledDa ...

  3. hibernate访问mysql没有响应_Struts2+hibernate + mysql C3P0连接池 导致写数据库无反应(死机)...

    我学hibernate刚学不久,最近用s2h+mysql做了个网站,买了个jsp的空间,发布到空间去了之后,第二天访问却访问不了,一查才知道,hiberante默认的连接数据库的时间有个限度,如果在这 ...

  4. JDBC——c3p0连接池的使用

    本文主要讲解jdbc连接mySQL. 一.在idea上新建maven工程 二.添加依赖包 <!-- 连接mysql工具包--> <dependency><groupId& ...

  5. 数据库MySQL基础---事务相关特性--连接池DBCP--C3P0--JavaBean--DBUtils工具

    事务相关特性–连接池DBCP–C3P0–JavaBean–DBUtils工具 事务的概念 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项 ...

  6. JDBC:使用连接池管理连接

    2019独角兽企业重金招聘Python工程师标准>>> 一.数据库连接池 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显 ...

  7. (十二)C3P0连接池使用教程

    一般我们在项目中操作数据库时,都是每次需要操作数据库就建立一个连接,操作完成后释放连接.因为jdbc没有保持连接的能力,一旦超过一定时间没有使用(大约几百毫秒),连接就会被自动释放掉.而每次新建连接都 ...

  8. 【知了堂学习笔记】数据库连接池简介,以及Eclipse中C3p0连接池的简单运用

    1.普通的JDBC连接数据库的弊端 普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0 ...

  9. 数据库驱动和JDBC

    文章目录 一.概述 1.2 JDBC 1.2 数据库驱动 1.3 快速入门 1.3.1 创建数据库 1.3.2 导入数据库驱动 1.3.2.1 方式一:创建lib导入 1.3.2.2 方式二:mave ...

最新文章

  1. 附录7:SciPy实例记录
  2. php实战第二十一天
  3. 计算机教案制作电子表格,人教版七年级信息技术上册《制作电子表格》教案
  4. Java获取yahoo天气预报
  5. LAMP介绍,Apache安装细节过程
  6. Processing绘制四边形
  7. (HDU4324)判断一个图中是否存在两点的出度相同
  8. oracle调试死掉,oracle自动死掉了
  9. 【Blog】Start My Journey In Cnblogs!
  10. window.btoa()方法;使字符编码成base64的形式
  11. XPath 轴 Axes
  12. 第三百零九节,Django框架,models.py模块,数据库操作——F和Q()运算符:|或者、并且——queryset对象序列化...
  13. [Step By Step]SAP HANA PAL多元线性回归预测分析Linear Regression实例FORECASTWITHLR(预测)...
  14. Python3 实现来宾抽签
  15. 【图像重建】基于matlab卷积神经网络的图像超分辨率重建【含Matlab源码 1816期】
  16. 服务器的硬盘内存型号大小怎么查看,怎么查服务器硬盘和内存大小
  17. java operator overload_c++下的 overload operator
  18. DTM、DEM与DSM的区别及其他
  19. Day25 - Event Capture, Propagation, Bubbling and Once
  20. 联想c245如何使用html,Windows 8的驱动是否能给Windows 8.1用

热门文章

  1. revit2018注册表删除_Revit卸载专用软件推荐及卸载方法
  2. Unity中如何跟随某个物体运动浅谈
  3. 亚商投资顾问 早餐FM/0928 养老金抵扣个税优惠来了
  4. 期货居间人一年能赚多少?期货居间人开户手续费有什么优势?
  5. 10款堪称神器的免费电脑软件推荐
  6. 上亿海量数据处理方法
  7. WM_INITDIALOG与WM_CREATE消息的区别
  8. (转)Android屏幕适配全攻略
  9. 匈牙利命名法鼻祖---查尔斯·西蒙尼
  10. 图片Base64编码 图片Base64在线转换