博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java/jdbc数据库操作、事务处理、批处理、分页查询、元数据、
阅读量:4289 次
发布时间:2019-05-27

本文共 11696 字,大约阅读时间需要 38 分钟。

 

脏读,不可重复读,幻读是由于数据库事务的隔离性导致的问题。

脏读:一个事务读取到了其它未提交事务操作的记录。

不可重复读:一个事务A内,首次查询到一条相同记录,然后事务B修改该条记录并提交,事务A再次执行相同查询,得到了事务B更新后的结果,事务A两次相同的查询,却得到了不同的结果,这个叫做不可重复读。是由于已提交事务B对事务A造成了影响(对于查询操作)。

幻读:一个事务A内,先查询某条不存在的记录,然后插入这条记录。在事务A结束之前,有个事务B抢先把这条记录插入并提交,导致事务A插入失败。这种情况叫做幻读。是由于已提交事务B对事务A造成了影响(对于插入操作)。

JDBC:是一套标准,用java取链接数据库,是由一些接口和类组成;JDBC通过不同的驱动去操作不同的数据库。

主要有2个包:java.sql.*   DriveManager类   Statement  PrepareStatement   ResultSet  CallableStatement(用于调用存储过程)
 javax.sql.*  DataSource接口

1。注册驱动

 DriverManager.registerDriver(new Driver);//这个会加载两次驱动,依赖驱动的jar包,
Class,forName("com.mysql.jdbc.Driver");//反射实现加载驱动,只加载一次,降低耦合,不依赖驱动jar包。
2.获取链接对象,这时就通过url确定了链接的是mysql数据库,而不是其他的数据库
Connectopn conn=DriveManger.getConnection("jdbc:mysql://localhost:3306/first","root","abc");
3.获取操作sql语句的Statement
Statement st=conn.createStatement();
4.操作的sql
String sql="select *from user";
5.执行sql得到结果集,DML语句(insert update delete)用excuteUpdate(),仅用返回值非0来判断语句是否执行成功; 
 DQL(select)用executeQuery(sql),excute()可以执行任何语句。
Result rs=st.executeQuery(sql);
6.遍历结果集
boolean flag=rs.next();//向下移动,如果为true代表有吓一条记录。

while(rs.next()){

int id=rs.getInt("id");或者rs.getInt(1);1表示第一个字段。

}
7.释放资源
rs.close();
st.close();
conn.close();

***DriverManager
管理一组JDBC的驱动程序的基本服务;

********批处理操作:
addBatch(sql);//sql添加到批处理
excuteBatch();//批量执行
clearBatch();//清空批处理

****ResultSet结果集

getObject()可以获取任意类型;
getInt()
getString();可以获取任何类型的数据类型,结果会变成String;
getDate()
getDouble();
参数是字段名或者列号

当结果集只有一条或者没有数据时,用if  不要用while遍历

*****资源的释放,为保证资源释放一定能执行,要放在finally中;

****获取abc.properties中的内容:

String username=ResourceBundle.getBundle("abc").getString("username");

*****JDBCUTIL的抽取:把获取注册驱动放到static静态块,把参数放到properties中,也放到static静态块中获取。

****滚动结构集:默认得到的rs.next结果集是只能向下遍历,滚动结果集是滚动到指定的行号;

定位rs.absolute(3)结果集定位某一行

********获取数据库的元数据:

//获取数据库的元数据	public void getData(String tablename)throws Exception{		String sql="select *from " + tablename;		Connection conn = DBUtil.getConnection();		Statement stmt = conn.createStatement();		ResultSet rs = stmt.executeQuery(sql);		try {			//获取数据库的元数据			 DatabaseMetaData dmd=(DatabaseMetaData) conn.getMetaData();			 //数据库名			 String dbname=dmd.getDatabaseProductName();			 //数据库的版本号			 int version=dmd.getDatabaseMajorVersion();			 //数据库的连接地址			 String url=dmd.getURL();			//数据库用户名			 dmd.getUserName();			 			 //获取结果集元数据			 ResultSetMetaData rsmd=(ResultSetMetaData) rs.getMetaData();			 //获取列数			 int colCount=rsmd.getColumnCount();			 //获取第i列的字段名,jdbc中字段的序号从1开始;			String colname= rsmd.getColumnName(1);						 		} catch (Exception e) {			// TODO: handle exception		}	}

 

********jdbc操作数据库的常用操作:

 

连接数据库的工具类:

package util;import java.io.File;import java.io.FileInputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;/** * @author HaokeMaster 数据连接和关闭的工具类 * commmand +shift+o 自动导包 */public class DBUtil {	private static String url;	private static String dbUser;	private static String dbPassword;	//获取属性文件中的内容	public static  void getPropertiesParam(String filename) {//		//***方法1。在classpath的目录下(即在src的目录下)用getclassload方法获取//		Properties propes=new Properties();//		try {//			InputStream fis = DBUtil.class.getClassLoader().getResourceAsStream(filename);  //			//加载输入流指定的文件//			propes.load(fis);//			//获取文件中对应的键的值//			url=propes.getProperty("url");//			dbUser=propes.getProperty("dbUser");//			dbPassword=propes.getProperty("dbPassword");//			//			System.out.println(url);//		}catch (Exception e) {////		}				//*****方法2.不在classpath的目录下(即不在src的目录下),必须使用完整路径		Properties propes=new Properties();		File file=new File(filename);		try {			FileInputStream fis=new FileInputStream(file);			//加载输入流指定的文件			propes.load(fis);			//获取文件中对应的键的值			url=propes.getProperty("url");			dbUser=propes.getProperty("dbUser");			dbPassword=propes.getProperty("dbPassword");						System.out.println(url);		}catch (Exception e) {					}	}		// 建立数据库连接	public static Connection getConnection() throws Exception {				DBUtil.getPropertiesParam("/Users/HaokeMaster/Desktop/javatest01/First/src/mysqlUse.properties");//对应上面的方法2;不在classpath的目录下(即在src的目录下),这个必须是完整路径//		DBUtil.getPropertiesParam("mysqlUse.properties");//对应上面的方法1;在classpath的目录下(即在src的目录下),直接写文件名加后缀		Connection conn = null;		try {			Class.forName("com.mysql.cj.jdbc.Driver");// 加载MYSQL JDBC驱动程序//			 conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/firstDB", "root",//					"1234567890");// 连接URL为 jdbc:mysql//服务器地址:端口号/数据库名 ,后面的2个参数分别是登陆用户名和密码			conn = DriverManager.getConnection(url, dbUser,					dbPassword);		} catch (Exception e) {			e.printStackTrace();			throw e;		}		return conn;	}	// 关闭数据库连接	public static void close(Connection conn){		if(conn!=null){		    try {		    conn.close();		   } catch (SQLException e) { 			e.printStackTrace();		   } 		}			}	}

数据库操作接口:

package dao;import java.util.List;import entity.User;/** * @author HaokeMaster *操作数据库接口 */public interface UserDAO {    public List
findAll()throws Exception;//查询所用用户的信息 public void delete(int id)throws Exception;//删除用户信息 public void save(User e)throws Exception;//增加保存用户信息 public void update(User e)throws Exception;//更新一个用户的信息 public User findById(int id)throws Exception;//一条记录public void getData(String tablename)throws Exception;//获取数据库的源数据}

数据库操作接口实现类:

package dao.impls;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.Statement;import java.util.ArrayList;import java.util.List;import com.mysql.cj.jdbc.DatabaseMetaData;import com.mysql.cj.jdbc.result.ResultSetMetaData;import com.mysql.cj.protocol.x.ResultMessageListener;import dao.UserDAO;import entity.User;import util.DBUtil;public class UserDAOone implements UserDAO {	// 添加	@Override	public void save(User e) throws Exception {		Connection conn = DBUtil.getConnection();		//使用Statement,sql语句在执行的时候传递;使用PreparedStatement,sql语句在生成语句对象的时候传递		PreparedStatement prep = conn				.prepareStatement("insert into " + "PEOPLE(id,name,age,phoneNum) " + "values(null,?,?,?)");		prep.setString(1, e.getName());//1,2,3表示的是第一第二第三个参数		prep.setInt(2, e.getAge());		prep.setString(3, e.getPhoneNum());		prep.executeUpdate();		DBUtil.close(conn);	}	// 根据id删除	@Override	public void delete(int id) throws Exception {		Connection conn = DBUtil.getConnection();		PreparedStatement prep = conn.prepareStatement("delete from PEOPLE where id=?");//预编译语句对象		prep.setLong(1, id);		prep.executeUpdate();		DBUtil.close(conn);	}	// 更新	@Override	public void update(User e) throws Exception {		Connection conn = DBUtil.getConnection();		PreparedStatement prep = conn				.prepareStatement("update PEOPLE " + "set name=?,age=?,phoneNum=? " + "where id=?");		prep.setString(1, e.getName());		prep.setInt(2, e.getAge());		prep.setString(3, e.getPhoneNum());		prep.setInt(4, e.getId());		prep.executeUpdate();		DBUtil.close(conn);	}//根据id查询一条记录	@Override	public User findById(int id) throws Exception {		Connection conn = DBUtil.getConnection();		PreparedStatement prep = conn.prepareStatement("select * " + "from PEOPLE where id=?");		prep.setInt(1, id);		ResultSet rs = prep.executeQuery();		User e = null;		if (rs.next()) {			e = new User();			e.setName(rs.getString("name"));			e.setId(rs.getInt("id"));			e.setAge(rs.getInt("age"));			e.setPhoneNum(rs.getString("phoneNum"));		}		DBUtil.close(conn);		return e;	}	// 查询所有	@Override	public List
findAll() throws Exception { Connection conn = DBUtil.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select * from PEOPLE"); List
users = new ArrayList
(); while (rs.next()) { User e = new User(); e.setName(rs.getString("name")); e.setId(rs.getInt("id")); e.setAge(rs.getInt("age")); e.setPhoneNum(rs.getString("phoneNum")); users.add(e); } DBUtil.close(conn); return users; } //获取数据库的元数据 public void getData(String tablename)throws Exception{ String sql="select *from " + tablename; Connection conn = DBUtil.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); try { //获取数据库的元数据 DatabaseMetaData dmd=(DatabaseMetaData) conn.getMetaData(); //数据库名 String dbname=dmd.getDatabaseProductName(); //数据库的版本号 int version=dmd.getDatabaseMajorVersion(); //数据库的连接地址 String url=dmd.getURL(); //数据库用户名 dmd.getUserName(); //获取结果集元数据 ResultSetMetaData rsmd=(ResultSetMetaData) rs.getMetaData(); //获取列数 int colCount=rsmd.getColumnCount(); //获取第i列的字段名,jdbc中字段的序号从1开始; String colname= rsmd.getColumnName(1); } catch (Exception e) { // TODO: handle exception } }}

********事务的处理:

Class.forName("com.mysql.cj.jdbc.Driver"); // 加载MYSQL JDBC驱动程序

Connection connect = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/firstDB", "root",

"1234567890");

// 连接URL为 jdbc:mysql//服务器地址:端口号/数据库名 ,后面的2个参数分别是登陆用户名和密码

// 创建一个 Statment对象

//使用Statement,sql语句在执行的时候传递;

Statement stmt = connect.createStatement();

ResultSet rs = stmt.executeQuery("select * from PEOPLE");

 

使用PreparedStatement,sql语句在生成语句对象的时候传递

PreparedStatement prep = conn.prepareStatement("delete from PEOPLE where id=?");//预编译语句对象

prep.setLong(1, id);

prep.executeUpdate();

 

connect.setAutoCommit(false);//jdbc默认是自动提交;这里关闭自动提交

connect.commit();//提交数据

connect.rollback();//回滚数据

 

*****批处理:

***** PreparedStatement实现批处理: Connection conn = null;			      PreparedStatement st = null;			       ResultSet rs = null;				       			       try{			            conn = DBUtil.getConnection();				            String sql = "insert into testbatch(id,name) values(?,?)";				            st = conn.prepareStatement(sql);				            for(int i=1;i<1000008;i++){  //i=1000  2000				                st.setInt(1, i);				                st.setString(2, "aa" + i);				                 st.addBatch();//添加批处理				                if(i%1000==0){				                    st.executeBatch();//执行批处理				                    st.clearBatch();//清除批处理				                 }				           }			            st.executeBatch();			       }catch (Exception e) {			           e.printStackTrace();			       }finally{				             DBUtil.close(conn);				             rs=null;				             st=null;				        }
***** Statement实现数据库批处理:这个的缺点是要多写很多重复的语句。Connection conn = null;        Statement st = null;       ResultSet rs = null;        try{           conn = DBUtil.getConnection();//建立数据库连接            String sql1 = "insert into testbatch(id,name) values(1,'aaa')";           String sql2 = "insert into testbatch(id,name) values(2,'bbb')";             String sql3 = "insert into testbatch(id,name) values(3,'CCC')";                      st = conn.createStatement();            //添加要批量执行的SQL             st.addBatch(sql1);            st.addBatch(sql2);             st.addBatch(sql3);                     //执行批处理SQL语句            st.executeBatch();             //清除批处理命令             st.clearBatch();        }catch (Exception e) {             e.printStackTrace();        }finally{             conn=null;             st=null;             rs=null;         }

 

*****分页查询:

createStatement中三个参数用法:

1.基于缓存的分页查询:一次性把数据全部取出来放在缓存中,根据要看的页数和每页的记录数pageSize来计算要把那些数据显示出来。适合比较小的数据量,数据量大时,对内存的压力很大。

公式:n是第几页;pageSize是每次查询的数据量

(n-1)*pageSize+1   -   (n-1)*pageSize+1+pageSize-1(就是 n*pageSize)

 

//分页查询,page是第几页,pageSize是每页的记录数量

public void getPage(int pageSize,int page)throws Exception{

int begin =(page-1)*pageSize+1;// 记录的起点

String sql="select *from PEOPLE";

Connection conn = DBUtil.getConnection();

Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);//第一个参数是表示可滚动的结果集,可以跳步;第二个参数设置并发性其他用户只读

ResultSet rs = stmt.executeQuery(sql);

//指针定位到绝对位置,第三条记录

rs.absolute(3);

//定位到相对位置,相对于上一个的位置基础上加5.到第8条记录

rs.relative(5);

//下一条,第9条记录

rs.next();

//前一条,第8条记录

rs.previous();

 

2.频繁的查询数据库,内存压力小。

 

********存储过程

 

*******函数

 

 

 

你可能感兴趣的文章
python pipe模块用法
查看>>
安装完 MySQL 后必须调整的 10 项配置
查看>>
开发者必备的 12 个 JavaScript 库
查看>>
http错误码
查看>>
python 多线程
查看>>
sipp命令 各参数含义
查看>>
搜集的动植物分类、检索网站
查看>>
ffmpeg源码分析之媒体打开过程
查看>>
Ubuntu/centos/redhat/SUSE sipp安装(带rtp支持,3.5.1版本)
查看>>
周鸿祎:很多程序员聪明,但我一看就知道他不会成功
查看>>
编译程序遇到问题 relocation R_X86_64_32 against `.rodata' can not be used when making a shared object;
查看>>
Const指针 、 指向const的指针 、引用、指针
查看>>
GDB调试命令
查看>>
常见数据类型的字节数
查看>>
gcc/g++ 编译常见问题
查看>>
【设计模式】 工厂模式实例 C++ , 利用工厂模式写一个计算器
查看>>
opencv
查看>>
【图像处理】 一、OSTU分割
查看>>
Android常用的框架有哪些
查看>>
SSL 证书创建与部署
查看>>