javaweb学习笔记(十七):JDBC(3)

版权声明:转载请注明出处: https://blog.csdn.net/qq_34774655/article/details/83794983

目录

 1.模拟事务回滚

2.BeanUtils组件

3.元数据


1.模拟事务回滚

当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行可使用下列语句:

Connection.setAutoCommit(false);

Connection.rollback();  

Connection.commit();


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

import org.junit.Test;

import util.jdbcUtil;

public class RollbackDemo {
	private Connection conn;
	private PreparedStatement stmt;
	@Test
	public void test1() {
		//模拟事务回滚到事务开始前。
		//其中第三个SQL语句有错误。
		String sql_1="INSERT INTO student (NAME,age) VALUES(\"xiaohua\",1)";
		String sql_2="INSERT INTO student (NAME,age) VALUES(\"xiaohua\",2)";
		String sql_3="INSERT INTO false (NAME,age) VALUES(\"xiaohua\",3)";
		try {
			//建立连接
			conn=jdbcUtil.getConnection();
			//设置手动提交事务
			conn.setAutoCommit(false);
			//第一次执行SQL语句
			stmt=conn.prepareStatement(sql_1);
			stmt.executeUpdate();
			//第二次执行SQL语句
			stmt=conn.prepareStatement(sql_2);
			stmt.executeUpdate();
			//第三次执行SQL语句,有错误
			stmt=conn.prepareStatement(sql_3);
			stmt.executeUpdate();
			
		}catch(Exception e){
			try {
				//出现异常,回滚事务到开始前。
				conn.rollback();
			}catch(SQLException e1) {
				
			}
			e.printStackTrace();
		}finally {
			try {
				//所有操作成功时,提交事务
				conn.commit();
				jdbcUtil.close(conn, stmt);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	@Test
	public void test2() {
		Savepoint sp=null;
		//模拟事务回滚到指定位置。
		//其中第三个SQL语句有错误。
		String sql_1="INSERT INTO student (NAME,age) VALUES(\"xiaohua\",1)";
		String sql_2="INSERT INTO student (NAME,age) VALUES(\"xiaohua\",2)";
		String sql_3="INSERT INTO false (NAME,age) VALUES(\"xiaohua\",3)";
		try {
			//建立连接
			conn=jdbcUtil.getConnection();
			//设置手动提交事务
			conn.setAutoCommit(false);
			//第一次执行SQL语句
			stmt=conn.prepareStatement(sql_1);
			stmt.executeUpdate();
			//第二次执行SQL语句
			stmt=conn.prepareStatement(sql_2);
			stmt.executeUpdate();
			//确定前面语句不会出现问题,在此设置保存点
			sp=conn.setSavepoint();
			//第三次执行SQL语句,有错误
			stmt=conn.prepareStatement(sql_3);
			stmt.executeUpdate();
			
		}catch(Exception e){
			try {
				//出现异常,回滚到指定位置
				conn.rollback(sp);
			}catch(SQLException e1) {
				
			}
			e.printStackTrace();
		}finally {
			try {
				//提交事务
				conn.commit();
				jdbcUtil.close(conn, stmt);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
	}

	
}

初始状态:

执行test1()无变化

执行test2(),第一条、第二条被执行:

2.BeanUtils组件

程序中对javabean的操作很频繁, 所以apache提供了一套开源的api,方便对javabean的操作,即BeanUtils组件。

BeanUtils组件,可以简化反射封装参数的步骤,给对象封装参数。且给对象封装参数的时候会进行类型自动转换。

常用的三个操作:

1:对象属性的拷贝

static void copyProperty(Object bean,String name,Object value)

static void setProperty(Object bean,String name,Object value)

2:对象的拷贝

static void copyProperties(Object dest,Object orig)

3:map数据拷贝到javabean中

static void populate(Object bean,Map<String,? extends Object> properties)

注:map中的key要与javabean的属性名称一致

BeanUtils的应用场景:

①快速将一个JavaBean各个属性值,赋值给有相同结构的另一个JavaBean中。

②快速收集表单中的所有数据到JavaBean中。

使用BenUtils组件:

①打开Apache官网http://www.apache.org/,最下面找到字符索引C开头的 Commons,点击中间BeanUtils,点击左侧Download,下载中间的支持包:commons-beanutils-1.9.3-bin.zip和源码包commons-beanutils-1.9.3-src.zip。

②打开Apache官网http://www.apache.org/,最下面找到字符索引C开头的 Commons,点击中间logging,点击左侧Download,下载中间的日志支持包:commons-logging-1.2-bin.zip。

③解压支持包:commons-beanutils-1.9.3-bin.zip,并导入commons-beanutils-1.9.3-jar到java项目中。

④解压日志支持包:commons-logging-1.2-bin.zip,并导入commons-logging-1.2.jar到java项目中。

例1:常见的三个操作:


import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import entity.Student;
public class BeanUtilDemo{
	@Test
	public void test1() throws Exception {
		Student stu=new Student();
		//a.对象属性的拷贝
		BeanUtils.copyProperty(stu,"name","xiaohua");
		BeanUtils.setProperty(stu, "age", "24");//对基本数据类型,会自动类型转换
		Student newStu=new Student();
		//b.对象的拷贝
		BeanUtils.copyProperties(newStu, stu);
		Student stuMap=new Student();
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("name","xiaona");
		map.put("age","24");
		//c.拷贝map数据到对象中
		BeanUtils.populate(stuMap, map);
		//测试
		System.out.println(stu.toString());
		System.out.println(newStu.toString());
		System.out.println(stuMap.toString());	
	}
}

其中entity包下实体类:Student.java文件为:

package entity;
public class Student {
	private String name;
	private int age;
	
	public Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}	
}

运行结果:

例2:日期类型的拷贝


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;
import entity.Student;
public class BeanUtilDemo {
	//2. 自定义日期类型转换器
	@Test
	public void test2() throws Exception {
		// 模拟表单数据
		String name = "xiaohua";
		String age = "24";
		String birth = "1994-02-20";
		// 对象
		Student stu=new Student();
		// 注册日期类型转换器:1, 自定义的方式
		ConvertUtils.register(new Converter() {
			// 转换的内部实现方法,需要重写
			@Override
			public Object convert(Class type, Object value) {
				// 判断
				if (type != Date.class) {
					return null;
				}
				if (value == null || "".equals(value.toString().trim())) {
					return null;
				}
				try {
					// 字符串转换为日期
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					return sdf.parse(value.toString());
				} catch (ParseException e) {
					e.printStackTrace();
					throw new RuntimeException(e);
				}
			}
		},Date.class);
		// 把表单提交的数据,封装到对象中
		BeanUtils.copyProperty(stu, "name", name);
		BeanUtils.copyProperty(stu, "age", age);
		BeanUtils.copyProperty(stu, "birth", birth);
		//------ 测试------
		System.out.println(stu);
	}
	//2. 使用提供的日期类型转换器工具类
	@Test
	public void test3() throws Exception {
		// 模拟表单数据
		String name = "xiaona";
		String age = "25";
		String birth ="1993-10-15";
		// 对象
		Student stu=new Student();
		// 注册日期类型转换器:2, 使用组件提供的转换器工具类
		ConvertUtils.register(new DateLocaleConverter(), Date.class);	
		// 把表单提交的数据,封装到对象中
		BeanUtils.copyProperty(stu, "name", name);
		BeanUtils.copyProperty(stu, "age", age);
		BeanUtils.copyProperty(stu, "birth", birth);
		//------ 测试------
		System.out.println(stu);
	}
}

其中:student.java文件为:



import java.util.Date;

public class Student {
	private String name;
	private int age;
	private Date birth;
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	public Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", birth=" + birth + "]";
	}
	
	
}

运行结果:

3.元数据

元数据:数据库、表、列的定义信息。

①Connection.getMetaData()

DataBaseMetaData对象

getURL(): 返回一个String类对象,代表数据库的URL。

getUserName(): 返回连接当前数据库管理系统的用户名。

getDatabaseProductName(): 返回数据库的产品名称。

getDatabaseProductVersion(): 返回数据库的版本号。

getDriverName(): 返回驱动驱动程序的名称。

getDriverVersion(): 返回驱动程序的版本号。

isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。

②PreparedStatement . getParameterMetaData() 获得代表PreparedStatement元数据的ParameterMetaData对象。

getParameterCount() 获得指定参数的个数

getParameterType(int param) 获得指定参数的sql类型(mysql驱动不支持)

③ResultSet. getMetaData() 获得代表ResultSet对象元数据的ResultSetMetaData对象。

getColumnCount() 返回resultset对象的列数

getColumnName(int column) 获得指定列的名称

getColumnTypeName(int column)获得指定列的类型

例:


import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import org.junit.Test;
import util.jdbcUtil;
public class MetaDataDemo {
	@Test
	//1.数据库元数据
	public void test1() throws Exception{
		//获取连接
		Connection conn=jdbcUtil.getConnection();
		//获取数据库元数据
		DatabaseMetaData metaData=conn.getMetaData();
		System.out.println(metaData.getURL());
		System.out.println(metaData.getUserName());
		System.out.println(metaData.getDatabaseProductName());
		System.out.println(metaData.getDatabaseProductVersion());
		System.out.println(metaData.getDriverName());
		System.out.println(metaData.getDriverVersion());
		System.out.println(metaData.isReadOnly());
		System.out.println("**********************");
	}
	@Test
	//1.参数元数据
	public void test2() throws Exception{
		//获取连接
		Connection conn=jdbcUtil.getConnection();
		//sql语句
		String sql="SELECT * FROM student WHERE id=? AND age=?;";
		//预编译
		PreparedStatement stmt=conn.prepareStatement(sql);
		//获取参数元数据
		ParameterMetaData metaData=stmt.getParameterMetaData();
		System.out.println(metaData.getParameterCount());
		System.out.println("**********************");
	}
	@Test
	//1.结果集元数据
	public void test3() throws Exception{
		//获取连接
		Connection conn=jdbcUtil.getConnection();
		//sql语句
		String sql="SELECT * FROM student ";
		//预编译
		PreparedStatement stmt=conn.prepareStatement(sql);
		//执行,返回结果集
		ResultSet rs=stmt.executeQuery();
		//获取结果集元数据
		ResultSetMetaData metaData=rs.getMetaData();
		//迭代每一行
		while(rs.next()) {
			//获取列的个数
			int count=metaData.getColumnCount();
			//遍历每一列的列名称、列值
			for(int i=0;i<count;i++) {
				String columnName=metaData.getColumnName(i+1);
				Object columnValue=rs.getObject(columnName);
				System.out.print(columnName+"="+columnValue+",");
			}
			System.out.println();
		}
	}
}

运行结果:

猜你喜欢

转载自blog.csdn.net/qq_34774655/article/details/83794983