JDBC

JDBC小结

JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯次数

Util.java(获取连接器)

public Connection getConnection(){
    Connection connection=null;
    try {
        //加载数据库连接驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url="jdbc:mysql://localhost:3306/数据库名?useSSL=false&serverTimezone=Hongkong&characterEncoding=utf-8&autoReconnect=true";
        String user="root";
        String password="HengTian0.0";
        connection= DriverManager.getConnection(url,user,password);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return connection;
}

Statement与PreparedStatement

  • 关系:PreparedStatement继承Statement接口,且它们都是接口

  • 区别:

    • Statement用来执行静态sql语句,同时同一时间一个Statement只能打开一个ResultSet对象,当只执行一次性sql语句的时候,开销比PreparedStatement小

    • PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程

    • 传递给PreparedStatement对象的参数可以被强制进行类型转换,使开发人员可以确保在插入或查询数据时与底层的数据库格式匹配。

    • 无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。

    • PrepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。   Statement不会初始化,没有预处理,没次都是从0开始执行SQL

    • PrepareStatement可以使用占位符"?",如:insert into table demo(name,id) values(?,?);

    • PrepareStatement可以用addBatch()方法将将要处理的语句预存起来

      例一:

      PreparedStatement ps = conn.prepareStatement(
              "INSERT into employees values (?, ?, ?)");
      for (n = 0; n < 100; n++) {
          ps.setString(name[n]);
          ps.setLong(id[n]);
          ps.setInt(salary[n]);
          ps.executeUpdate();
      }
      

      例二:

      PreparedStatement ps = conn.prepareStatement(
              "INSERT into employees values (?, ?, ?)");
      for (n = 0; n < 100; n++) {
          ps.setString(name[n]);
          ps.setLong(id[n]);
          ps.setInt(salary[n]);
          ps.addBatch();
      }
      ps.executeBatch();
      

      ​ 在例 1中, PreparedStatement被用来多次执行INSERT语句. 在这里, 执行了100次INSERT操作, 共有101次网络往返.

      ​ 其中,1次往返是预储PreparedStatement, 另外100次往返执行每个迭代.

      ​ 在例2中, 当在100次INSERT操作中使用addBatch()方法时, 只有两次网络往返.

      ​ 1次往返是预储PreparedStatement, 另一次是执行batch命令. 虽然Batch命令会用到更多的数据库的CPU周期, 但是通过减少网络往返,性能得到提高.记住, JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯.次数

      ​ !使用批处理时要在url后面加rewriteBatchedStatements=true表示批量插入,如果不添加的话即使使用addbatch() ,executeBatch() 在后台入库的地方还是不会一次请求入库而是多次请求入库

      //批量处理时最好取消自动提交,进行手动提交
      connection.setAutoCommit(false);   
      

      批量添加的实例

      public static void insertData(List<Map<String,String>> list,Logger log){
      	//获取的数据
      	List <Map<String,String>> nlist= list;
      	String upsql="update   hrd_staff  set position =?  where id=?";
      	Iterator<Map<String,String>> iter= nlist.iterator();
      	Connection con= Utils.getCon();
      	int count=0;
      	try {
      		//在批量添加的时候注意事务提交方式
      		con.setAutoCommit(false);
      		//PreparedStatement方法的使用
      		PreparedStatement pstm = con.prepareStatement(upsql);
      		while(iter.hasNext()){
      			count++;
      			Map<String,String> map= iter.next();
      			String jon_name= map.get("job_name");
      			String uid= map.get("uid");
      			pstm.setString(1,jon_name);
      			pstm.setString(2,uid);
      			//添加到缓存中
      			pstm.addBatch();
      			// 如果数据量很大,不能一次性批量添加所以我们要分批次添加,这里就是300条一次
      			if(count%300==0){
      				//持久化
      				int []res=pstm.executeBatch();
      				//提交事务,持久化数据
      				con.commit();
      				pstm.clearBatch();
      				log.info("300整除插入结果: "+res.length);
      			}
      		}
      		//小于300条的在这里持久化
      		int []ress= pstm.executeBatch();
      		//事务提交持久化
      		con.commit();
      		pstm.clearBatch();
      		log.info("插入数据结果:"+ress.length);
      	} catch (SQLException e) {
      		try {
      			con.rollback();
      		} catch (SQLException e1) {
      			// TODO Auto-generated catch block
      			e1.printStackTrace();
      		}
      		e.printStackTrace();
      	}finally{
      		try {
      			if(null!=con){
      			con.close();
      			con.setAutoCommit(true);
      			}
      		} catch (SQLException e) {
      			// TODO Auto-generated catch block
      			e.printStackTrace();
      		}
      	}
      }
      
      

      批量添加步骤最后总结:

      1. url中添加rewriteBatchedStatements=true,如:

        String url="jdbc:mysql://localhost:3306/MyTestBase?rewriteBatchedStatements=true;
        
        1. 将connection的自动提交关闭
        con=JdbcUtil.getConnection();//自己实现的工具类,获取connection对象
        con.setAutoCommit(false);
        

        主要参考:https://blog.csdn.net/QH_JAVA/article/details/48245945

ResultSet

  1. Statement和PreparedStatement中都可以传入两个参数:ResultSetType和ResultSetConcurrency(名字自己取的,意思差不多,type在前,concurrency在后,但是都可单独传入)
ResultSet方法作用
public boolean next()顺序获取查询记录
public void beforeFrist()将游标移动到第一行之前
public void afterLast()将游标移到最后一行之后
public void first()将游标移动到结果集的第一行
public void last()将游标移动到结果集的最后一行
public boolean isAfterLast()判断游标是否在最后一行之后
public boolean isBeforefirst()判断游标是否在最后一行之前
public boolean isFirst()判断游标是否在结果集的第一行
public boolean isLast()判断游标是否在结果集的最后一行
public int getRow()得到当前游标所指行的行号,行号从1开始。如果结果集没有行,返回0
public boolean absolute(int row)将游标移动到参数row所指的行号
public boolean previous()将游标向上移动,该方法返回boolean型数据,当移动到结果集第一行的前面返回false
type取值作用
ResultSet.TYPE_FORWARD_ONLY结果集的游标只能向下滚动
ResultSet.TYPE_SCROLL_INSENSITIVE结果集的游标可以上下移动,当数据库变化时,当前结果集不变
ResultSet.TYPE_SCROLL_SENSITIVE返回可滚动的结果集,当数据库变化时,结果集同步变化
Concurrency取值作用
ResultSet.CONCUR_READ_ONLY不能用结果集更新数据库中的表
ResultSet.CONCUR_UPDATABLE能用结果集更新数据库中的表
  1. ResultSetMetaData

    ResultSet rs=ps.executeQuery();
    ResultSetMetaData metaData=rs.getMetaData();
    

    ResultSetMetaData中保存的结果集的列,如:姓名,班级等

  2. CachedRowSetImpl

    CachedRowSetImpl可以保存ResultSet对象中的数据,并且CachedRowSetImpl不依赖connection对象,因此,查询CachedRowSetImpl时可以关闭和数据库的连接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值