`

传智播客李勇Jdbc视频笔记(26-33)

阅读更多
26、可滚动结果集与分页技术
static void scroll() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
//在创建一个Statement的时候指定可滚动的结果集的类型
			st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
//在mysql中通过limit关键字实现分页,每种数据库产品的关键字不同例如:Oracle使用rownum,sqlServer用top
//现在有几十中关系型数据库如果数据库不支持这种关键字进行分页的时候可以用滚动的结果集来实现分页,但是
//性能比较低
	rs = st.executeQuery("select id, name, money, birthday  from user limit 150, 10");
			while (rs.next()) {
				System.out.println(rs.getObject("id") + "\t"
						+ rs.getObject("name") + "\t"
						+ rs.getObject("birthday") + "\t"
						+ rs.getObject("money"));
			}

			//绝对定位,可以直接定位到rs所有返回结果中指定的一条记录上
			rs.absolute(150);
			int i = 0;
			//可以通过i来控制循环次数,实现分页效果但是要数据库产品或者驱动支持此功能!
			while (rs.next() && i < 10) {
				i++;
				System.out.println(rs.getObject("id") + "\t"
						+ rs.getObject("name") + "\t"
						+ rs.getObject("birthday") + "\t"
						+ rs.getObject("money"));
			}
			//如果上面设定的结果集是可以滚动的,那么你还可以用里面的很多的方法,在此不列举了
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}


27、可更新和对更新敏感的结果集
static void read() throws SQLException, InterruptedException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			//设置滚动结果集的类型为:ResultSet.TYPE_SCROLL_SENSITIVE,就是能感知到数据库的变化
			st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
					ResultSet.CONCUR_UPDATABLE);

			// 4.执行语句
			rs = st
					.executeQuery("select id, name, money, birthday  from user where id < 5");

	// 5.处理结果
	//下面让rs每循环一次rs睡眠10秒钟,然后再这个过程中我们用mysql客户端修改数据库中的数据
	//我们看看他读出来的是修改前的数据,还是修改后的。我们在上面设置的可滚动的结果集的类型
	//是ResultSet.TYPE_SCROLL_SENSITIVE,也就是能感知数据库的变化,那如果在rs没有读出数据库里的
	//那条数据之前我们在mysql的客户端将原先的数据修改掉,这里读出来的数据应该是修改后的数据,但是在
	//测试的时候读出的数据却依然是修改之前的,这应该和数据库的驱动有关系
	//但是如果是能感知数据库的变化,那么数据库的性能也是降低了,你执行executeQuery()方法后,他已经将数据查询完成
	//打包后给你发送过来了,如果察觉到数据库的变化那么他要在输出之前在查询一遍数据库,这种需求用的比较少,作为
	//了解即可
			while (rs.next()) {
				int id = rs.getInt("id");
				System.out.println("show " + id + "...");
				Thread.sleep(10000);
				System.out.println(id + "\t" + rs.getObject("name") + "\t"
						+ rs.getObject("birthday") + "\t"
						+ rs.getObject("money"));
				String name = rs.getString("name");
				//可更新的结果集,我们并不建议这样做因为上面的sql语句是查询操作
				//但是下面还隐藏着更新操作,对于程序的可读性不好,这种需求也比较少
				//做了解即可
				if("lisi".equals(name)) {
					rs.updateFloat("money",300f);
					//修改完成后要修改一行
					rs.updateRow();
				}
			}
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}


28、数据库的元数据信息:
DatabaseMetaData对象中包含了当前数据库产品的很多的信息,他有很多返回值类型为boolean的方法,来判断
当前的数据库是否支持某些功能,例如事务的支持,隔离级别 版本号等等,对于我们编写程序来说不常用,但是
在框架的编写中经常会用到,例如hibernate,他要屏蔽不同数据库之间的区别,那么他就要知道当前是什么数据库
然后做出相应的判断处理:在使用hibernate的时候有一项是配置数据库的方言,其实就是指定你使用的是什么数据库产品
如果你不进行指定,hibernate会自动的尝试着去检测当前数据库产品的类型,其实就是根据DatabaseMetaData来检测的
public static void main(String[] args) throws SQLException {
		java.sql.Connection conn = JdbcUtils.getConnection();
		//得到数据库的元信息
		DatabaseMetaData dbmd = conn.getMetaData();
		//取出当前使用数据库的名称
		System.out.println("db name: " + dbmd.getDatabaseProductName());
		//看看当前数据库支不支持事务
		System.out.println("tx: " + dbmd.supportsTransactions());
		conn.close();
	}


29、参数的元数据信息
/**链接数据库的url为:url = "jdbc:mysql://localhost:3306/jdbc?generateSimpleParameterMetadata=true
	 * 要加入 generateSimpleParameterMetadata=true时才行,否则会抛
	 * “java.sql.SQLException: Parameter metadata not available for the given statement”,
	 * 因为mysql驱动默认generateSimpleParameterMetadata=false只有设置为true metadata类型会
	 * 将每一个参数反射为Varchar类型
	 * @author guohailong
	 *
	 */
	public static void main(String[] args) throws SQLException {
		String sql = "select * from user where name = ? and sex = ?";
		Object[] params = {"zhangsan", "男"};
		query(sql, params);
	}
	
	public static void query(String sql, Object[] param) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			ParameterMetaData pmd = pstmt.getParameterMetaData();
			int paramsCount = pmd.getParameterCount();
			//得到参数信息的元数据
			for(int i=1; i<=paramsCount; i++) {
				System.out.print(pmd.getParameterClassName(i) + "\t");
				System.out.print(pmd.getParameterType(i) + "\t");
				System.out.print(pmd.getParameterTypeName(i) + "\t");
				System.out.println();
				//用for循环的方法给sql语句中的占位符赋值,但是要约定:sql语句中占位符的所表示的类型
				//和个数和参数数组中是一致的
				pstmt.setObject(i, param[i -1]);
			}
		
		rs = pstmt.executeQuery();
		while(rs.next()) {
			System.out.println(rs.getString(2));
		}
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		}
	}


30、将结果集元数据封装为Map
现在我们有一种需求将ResultSet结果集中的数据封装成Map map的key是数据库中字段的值value就是在字段中的值
public static void main(String[] args) {
		Map<String, Object> datas  = read("select id, name from user");
	}
	private static Map<String, Object> read(String sql) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			//得到ResultSet的元数据
			ResultSetMetaData rsmd = pstmt.getMetaData();
			//得到一条ResultSet数据的列数
			int colCount = rsmd.getColumnCount();
			String[] colName = new String[colCount];
			for(int i=1; i<=colCount; i++) {
				//得到参数的类名,java.lang.String 
				/*System.out.print(rsmd.getColumnClassName(i) + "\t");
				//得到列名
				System.out.print(rsmd.getColumnName(i) + "\t");
				//得到别名:select name as n from user -->得到的是n
				System.out.println(rsmd.getColumnLabel(i) + "\t");*/
				colName[i-1] = rsmd.getColumnLabel(i);
			}
		//新建一个Map对象
		 Map<String, Object> data = new HashMap<String, Object>();
		while(rs.next()) {
			for(int i=1; i<=colName.length; i++) {
				data.put(colName[i-1], rs.getObject(i));
				System.out.println(colName[i-1] + "======" +rs.getObject(i) );
			}
		}
		//返回Map对象
		return data;
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		}finally {
			JdbcUtils.free(rs, pstmt, conn);
		}
	}


31、Java反射技术入门:
传递给你一个Class的对象,用它来构造一对象如果这个对象有无参的构造方法那么
clazz.newInstance(),直接newInstance就可了,但是如果没有无参的构造方法,就要首先根据参数类型
得到构造方法,然后再去构造对象,在张孝祥Java高级笔记中,已经详细的记录了这个问题在这里就不在重复了

32、Java反射的更多的细节

static void invoke1(Object obj, String methodName)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, Exception, NoSuchMethodException {
		//得到类中所有声明的方法,包括私有方法但不能得到从父类继承来的任何方法
		Method[] ms = obj.getClass().getDeclaredMethods();
		//得到所有的方法包括从父类继承来的,但得不到私有方法
		//下面得到属性和得到注解都一样,主要理解两个方法的不同
		ms = obj.getClass().getMethods();
		for (Method m : ms) {
			// System.out.println(m.getName());
			if (methodName.equals(m.getName()))
				m.invoke(obj, null);
		}

		Method m = obj.getClass().getMethod(methodName, null);
		m.invoke(obj, null);
	}

	static void field(Class clazz) throws Exception {
		Field[] fs = clazz.getDeclaredFields();
		//fs = clazz.getFields();
		for (Field f : fs)
			System.out.println(f.getName());
	}
	
	static void annon(Class clazz) throws Exception {
		Annotation[] as = clazz.getAnnotations();
	}


33、利用Java反射技术将查询结果封装为对象
在这个示例中,约定数据库的字段名要和属性的字段名一致, String methodName = "set" + 数据库的字段名。用这样的方法来构成
Javabean中属性的set方法来实现赋值操作,那么在传递sql语句的时候就有一定的局限性了,例如:你不能写 select id , name from user
因为这样得到的set方法setid, setname这样就没法完成赋值操作,要这样写:select id as Id, name as Name fromt user,然后用ResultSetMetadata
getColumnLabel()得到他的别名,然后遍历Javabean中所有的方法找到和我们这个名字一样的,然后执行就可以了,但是通过sql语句来操纵属性
名称然后构成方法名,这样的方式不大好。
分享到:
评论

相关推荐

    传智播客 李勇老师 JDBC代码全部和ppt

    【标题】"传智播客 李勇老师 JDBC代码全部和ppt" 提供的是一个关于JDBC编程的全面学习资源,由知名教育机构传智播客的讲师李勇主讲。JDBC(Java Database Connectivity)是Java编程语言中用于与各种数据库进行交互的...

    传智播客-Jdbc-李勇.ppt

    传智播客-Jdbc-李勇.ppt 传智播客-Jdbc-李勇.ppt 传智播客-Jdbc-李勇.ppt

    传智播客李勇hibernate源码1-20课

    传智播客李勇hibernate源码1-20课,目录如下:01_hibernate介绍与动手入门体验;02_hibernate入门案例的细节分析; 03_hibernate入门案例的代码优化; 04_Session接口及get|load|persist方法 05_实体对象的三种状态...

    传智播客李勇hibernate PPT

    【传智播客李勇hibernate PPT】是一份由知名教育机构传智播客推出的关于Hibernate框架的培训资料,由讲师李勇精心制作。这份PPT详细讲解了Hibernate在实际开发中的应用,旨在帮助学员深入理解并掌握这一强大的Java...

    传智播客_hibernate李勇笔记

    传智播客_hibernate李勇笔记是在学习李勇老师讲的hibernate3.2.5后整理的笔记

    hibernate_传智播客_李勇

    hibernate_传智播客_李勇

    传智播客李勇hibernate

    【传智播客李勇hibernate】课程详解了ORM框架Hibernate的核心概念和技术,适合初学者和想要深入了解Hibernate的开发者。以下是对课程内容的详细解析: 1. **引入ORM框架**: - 阻抗不匹配:由于Java是面向对象的...

    hibernate传智播客李勇ppt

    传智播客hibernate讲解视频配套ppt,李勇

    传智播客 李勇 hibernate 的ppt

    【传智播客 李勇 Hibernate 讲解】 在IT领域,ORM(Object-Relational Mapping,对象关系映射)框架是将面向对象的模型与关系数据库之间进行映射的关键技术,有效地解决了“模型不匹配”(也称为“阻抗不匹配”)的...

    传智播客JDBC_所有源码与ppt

    本资源“传智播客JDBC_所有源码与ppt”是针对JDBC学习的一个综合包,包含了源代码和相关的教学演示PPT,非常适合初学者或希望深入理解JDBC的开发者使用。传智播客是一家知名的教育机构,其课程内容通常具有系统性和...

    传智播客 hibernate PPT 很经典

    传智播客 hibernate PPT 很经典

    JDBC笔记 李勇

    **JDBC笔记 李勇** JDBC(Java Database Connectivity)是Java编程语言中用来规范应用程序如何访问数据库的应用程序编程接口,提供了诸如连接数据库、发送SQL语句、处理结果集等功能。李勇老师的JDBC学习笔记主要...

    传智播客SSHppt

    - **传智播客李勇hibernate**:李勇老师的Hibernate课程可能包括了Hibernate的基本原理、实体类与表的映射、CRUD操作、查询语言(HQL)、Criteria查询、级联操作、缓存策略等。他可能强调了如何优雅地处理数据库操作...

    传智播客SSH三大框架的PPT

    在IT行业中,SSH三大框架是Java Web开发领域中不可或缺的一部分...这些PPT资源,如"传智播客李勇hibernate.ppt"、"spring.ppt"、"struts2.ppt",提供了详细的讲解和示例,对学习SSH框架的开发者来说是一份宝贵的资料。

    传智播客Java培训ppt大全

    本Java培训资料集合了多位知名讲师的精华内容,包括比向东、方力勋、黎活明、张孝祥、杨忠科、李勇、韩顺平等,覆盖了Java的基础到高级知识点,旨在帮助学习者全面掌握Java编程。 1. **Java基础** - **语法基础**...

Global site tag (gtag.js) - Google Analytics