JDBC事务和数据

来源:互联网 发布:mac os x 10.7 好用吗 编辑:程序博客网 时间:2024/05/16 07:56

上一篇博客  http://blog.csdn.net/forrest_ou/article/details/53907003  简单的使用了JDBC连接MySQL数据库的增删改查,异常和资源关闭等内容均没有涉及

玩一个东西,肯定是先去上手玩,然后才来慢慢的了解学习它的注意事项和更加深层次的内容


这篇博客的主要内容:

       1、创建一个工具类,完成加载驱动,建立连接和释放资源

       2、日期格式的处理

       3、元数据的获取

       4、事务的操作

       5、批处理


所有代码都是自己动手敲出来,实践过,感觉具体的动手会发现更多的问题,也就会了解决更多的问题,重要的是你知道了到底行不行


工具类————加载驱动,建立连接,释放资源

package TestJDBC;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;//JDBC工具类,  加载驱动   建立连接    关闭资源 。方法都是static,可以直接调用public final class JDBCUtil {private static String DRIVER = "com.mysql.jdbc.Driver";private static String URL = "jdbc:mysql://localhost:3306/test";private static String USER_NAME = "admin";private static String PASSWORD = "123456";    //注册驱动放在静态代码块中,保证只注册一次,当类装载到虚拟机中就会执行static{try {Class.forName(DRIVER);} catch (Exception e) {e.printStackTrace();}}//建立连接public static Connection getConnection() throws SQLException{return DriverManager.getConnection(URL, USER_NAME, PASSWORD);}//释放资源public static void closeAll(ResultSet rs, Statement stmt, Connection conn){try {if(rs != null){rs.close();}rs = null;} catch (Exception e) {e.printStackTrace();}finally {try {if(stmt != null){stmt.close();}stmt = null;} catch (Exception e) {e.printStackTrace();}finally {try {if(conn != null){conn.close();}conn = null;} catch (Exception e) {e.printStackTrace();}}}}}

例如我在main方法中的调用

Connection conn = JDBCUtil.getConnection();JDBCUtil.closeAll(rs, stmt, conn);



对于日期处理一直是一个老生常谈的问题,经常遇到。弄一个Datedemo类来实验日期的操作,主要有SimpleDateFormat和Calendar

使用SimpleDateFormat来完成日期与字符串的相互转换,了解Calendar更多的操作方式

package TestForDate;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;  //SimpleDateFormat  格式化存储  日期转换为字符串(sdf.format(Date date)方法),字符串转日期(sdf.parse(String str)方法)public class DateDemo {public static void main(String[] args) throws ParseException {Date date = new Date();//System.out.println(date.toString());//当前日期SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd");String str = "2016-12-12";Date t = sdf.parse(str); String s = sdf.format(date);System.out.println(s);System.out.println(t);//日期处理类,包含Date类, Calendar类 是更厉害,包含更多,通过 set 和  get 方法Calendar cld = Calendar.getInstance();cld.set(2016, 12-1, 12);int year1 = cld.get(Calendar.YEAR);int month1 = cld.get(Calendar.MONTH) + 1;System.out.println(year1 +" "+ month1);cld.set(Calendar.YEAR, 2017);System.out.println(cld.get(Calendar.YEAR));cld.add(Calendar.MONTH, -2);System.out.println(cld.get(Calendar.MONTH) + 1);}}

JDBC中日期的使用,user表中新增一个birthday字段,实验日期。user类与user表中的birthday属性得保证是一样的,这样才能成功操作

1、可以都设置为String类型的

2、Date 类型的的涉及到java.sql.Date与java.util.Date的相互转换

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        String str = "2017-01-01";        java.util.Date date = sdf.parse(str);        //parse后得到的是java.util.Date类型的日期,转换成java.sql.Date类型,才可以使用(父子类,真是青出于蓝而胜于蓝啊)        //都有getTime()方法,返回自1970年1月1日00:00:00到目标日期的毫秒数,通过这样来转换        java.sql.Date sqlDate = new java.sql.Date(date.getTime());


元数据信息的获取

databaseMetadata  parameterMetadata  ResultSetMetada 分别对应 Connection Statement  ResultSet

//DatabaseMetaData  Connectionconn = JDBCUtil.getConnection();DatabaseMetaData dbmd = conn.getMetaData();String url = dbmd.getURL();System.out.println(url+" "+dbmd.getUserName()+" "+dbmd.getDriverName());*//*getURL():返回一个String类对象,代表数据库的URL。getUserName():返回连接当前数据库管理系统的用户名。getDatabaseProductName():返回数据库的产品名称。getDatabaseProductVersion():返回数据库的版本号。getDriverName():返回驱动驱动程序的名称。getDriverVersion():返回驱动程序的版本号。isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。.........等等

/*ResultSet getTables(String catalog,String schemaPattern,String tableNamePattern,String[] types);         * catalog - 表所在的类别名称;""表示获取没有类别的列,null表示获取所有类别的列。         * schema - 表所在的模式名称(oracle中对应于Tablespace);""表示获取没有模式的列,null标识获取所有模式的列; 可包含单字符通配符("_"),或多字符通配符("%");         * tableNamePattern - 表名称;可包含单字符通配符("_"),或多字符通配符("%");         * types - 表类型数组; "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM";null表示包含所有的表类型;可包含单字符通配符("_"),或多字符通配符("%"); *///获取数据库的表ResultSet rs = dbmd.getTables(null, null, null, new String[]{"TABLE"});while(rs.next()){System.out.println(rs.getString(1));//db名称//System.out.println(rs.getString(2));//用户名称System.out.println(rs.getString("TABLE_NAME"));//表名称//System.out.println(rs.getString("REMARKS"));//获取备注}

//获取表主键信息ResultSet rs1 = dbmd.getPrimaryKeys(null, null, "user");while(rs1.next()){System.out.println(rs1.getString("COLUMN_NAME"));//主键列名System.out.println(rs1.getString("TABLE_NAME"));System.out.println(rs1.getShort("KEY_SEQ"));//第几列}

               ParameterMetaData  pmd = stmt.getParameterMetaData();       System.out.println(pmd.getParameterCount());//获取参数个数

                        ResultSet rs = stmt.executeQuery();ResultSetMetaData rsmd = rs.getMetaData();System.out.println(rsmd.getColumnCount());for(int i = 0; i < rsmd.getColumnCount(); i++){System.out.println(rsmd.getColumnName(i+1));}


事务的操作,要么全部执行成功,要么全部执行不成功,回滚到原来的状态

主要的方法有conn.setAutoCommit(false);   conn.commit();  conn.rollback();

1、取消自动提交

2、提交事务信息(不同的sql)

3、提交事务

4、提交出现错误,回滚到原来的状态

//事务处理String sql[] = new String[3];sql[0] = "INSERT INTO user(id,name,password) VALUES (24,'yy','yy')";sql[1] = "INSERT INTO user(id,name,password) VALUES (25,'yyyy','yyyy')";sql[2] = "INSERT INTO user(id,name) VALUES (26,'yyyy')";//这样就不成功,因为password是必填的,三条语句一起执行失败并回滚状态//sql[2] = "UPDATE user SET name = '杨' WHERE id = 88"; //执行成功,88的不存在//sql[2] = "DELETE FROM user WHERE id = 88"; //执行成功,88的不存在try {conn = JDBCUtil.getConnection();conn.setAutoCommit(false);for(int i = 0; i < sql.length; i++){stmt = conn.prepareStatement(sql[i]);stmt.execute();}conn.commit();System.out.println("事务执行成功");} catch (Exception e) {try {System.out.println("事务执行失败,执行回滚");conn.rollback();e.printStackTrace();//打印错误信息对于找原因是为一神技} catch (Exception e2) {e2.printStackTrace();}}finally {conn.setAutoCommit(true);//可以不用,会自动变为falseJDBCUtil.closeAll(rs, stmt, conn);}

批处理:对应Statement和preparedStatement有两种批处理方式

对应Statement的批处理适合不同类型的sql操作

对应preparedStatement的批处理适合相同类型但是不同参数的sql操作

主要是方法:addBatch()添加批处理语句,executeBatch()执行批处理语句,clearBatch()清除缓存

try {conn = JDBCUtil.getConnection();Statement stmt = conn.createStatement();//添加批处理语句stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (1,'oo','oo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (2,'ooo','ooo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (3,'oooo','oooo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (4,'ooooo','ooooo',111)");stmt.addBatch("UPDATE user SET name = '杨' WHERE id = 2 ");stmt.executeBatch();//执行批处理语句stmt.clearBatch();//去除缓存/*String sql = "DELETE FROM user WHERE id = ?";    stmt = conn.prepareStatement(sql);*/    /*for(int i = 1; i < 5; i++){stmt.setInt(1, i);stmt.addBatch();//添加批处理语句}*//*for(int i = 25; i > 14; i--){stmt.setInt(1, i);stmt.addBatch();//添加批处理语句}stmt.executeBatch();//执行批处理语句stmt.clearBatch();//去除缓存*/} catch (Exception e) {e.printStackTrace();}finally {JDBCUtil.closeAll(rs, stmt, conn);}



整体代码,包含上面的工具类,一共三个类

JdbcForUser2类

package TestJDBC;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.Date;import java.sql.ParameterMetaData;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.Statement;import java.text.SimpleDateFormat;public class JdbcForUser2 {private static Connection conn = null;private static PreparedStatement stmt = null;private static ResultSet rs = null;public static void main(String[] args) throws Exception {//获取是否支持事务和是否自动提交信息/*conn = JDBCUtil.getConnection();DatabaseMetaData dbmd = conn.getMetaData();System.out.println(dbmd.supportsTransactions()+" "+conn.getAutoCommit());*///日期格式一致性问题/*JdbcForUser2 jfu = new JdbcForUser2();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        String str = "2017-01-01";        java.util.Date date = sdf.parse(str);        //parse后得到的是java.util.Date类型的日期,转换成java.sql.Date类型,才可以使用(父子类,真是青出于蓝而胜于蓝啊)        //都有getTime()方法,返回自1970年1月1日00:00:00到目标日期的毫秒数,通过这样来转换        java.sql.Date sqlDate = new java.sql.Date(date.getTime());jfu.addUser(new User(13,"test3","ooo","2222",sqlDate));*//*User user1 = jfu.getById(10);System.out.println(user1.getName()+" "+user1.getBirthday());*///元数据//DatabaseMetaData  Connection/*conn = JDBCUtil.getConnection();DatabaseMetaData dbmd = conn.getMetaData();String url = dbmd.getURL();System.out.println(url+" "+dbmd.getUserName()+" "+dbmd.getDriverName());*//*getURL():返回一个String类对象,代表数据库的URL。getUserName():返回连接当前数据库管理系统的用户名。getDatabaseProductName():返回数据库的产品名称。getDatabaseProductVersion():返回数据库的版本号。getDriverName():返回驱动驱动程序的名称。getDriverVersion():返回驱动程序的版本号。isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。.........等等*//*ResultSet getTables(String catalog,String schemaPattern,String tableNamePattern,String[] types);         * catalog - 表所在的类别名称;""表示获取没有类别的列,null表示获取所有类别的列。         * schema - 表所在的模式名称(oracle中对应于Tablespace);""表示获取没有模式的列,null标识获取所有模式的列; 可包含单字符通配符("_"),或多字符通配符("%");         * tableNamePattern - 表名称;可包含单字符通配符("_"),或多字符通配符("%");         * types - 表类型数组; "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM";null表示包含所有的表类型;可包含单字符通配符("_"),或多字符通配符("%"); *///获取数据库的表/*ResultSet rs = dbmd.getTables(null, null, null, new String[]{"TABLE"});while(rs.next()){System.out.println(rs.getString(1));//db名称//System.out.println(rs.getString(2));//用户名称System.out.println(rs.getString("TABLE_NAME"));//表名称//System.out.println(rs.getString("REMARKS"));//获取备注}*///获取表主键信息/*ResultSet rs1 = dbmd.getPrimaryKeys(null, null, "user");while(rs1.next()){System.out.println(rs1.getString("COLUMN_NAME"));//主键列名System.out.println(rs1.getString("TABLE_NAME"));System.out.println(rs1.getShort("KEY_SEQ"));//第几列}*///ParameterMetaData   PreparedStatement//下面getById(int id)方法内//ResultSetMetaData   ResultSet//下面getById(int id)方法内/*JdbcForUser2 jfu = new JdbcForUser2();User user1 = jfu.getById(1);System.out.println(user1.getName()+" "+user1.getBirthday());*///事务处理/*String sql[] = new String[3];sql[0] = "INSERT INTO user(id,name,password) VALUES (24,'yy','yy')";sql[1] = "INSERT INTO user(id,name,password) VALUES (25,'yyyy','yyyy')";sql[2] = "INSERT INTO user(id,name) VALUES (26,'yyyy')";//这样就不成功,因为password是必填的,三条语句一起执行失败并回滚状态//sql[2] = "UPDATE user SET name = '杨' WHERE id = 88"; //执行成功,88的不存在//sql[2] = "DELETE FROM user WHERE id = 88"; //执行成功,88的不存在try {conn = JDBCUtil.getConnection();conn.setAutoCommit(false);for(int i = 0; i < sql.length; i++){stmt = conn.prepareStatement(sql[i]);stmt.execute();}conn.commit();System.out.println("事务执行成功");} catch (Exception e) {try {System.out.println("事务执行失败,执行回滚");conn.rollback();e.printStackTrace();//打印错误信息对于找原因是为一神技} catch (Exception e2) {e2.printStackTrace();}}finally {conn.setAutoCommit(true);//可以不用,会自动变为falseJDBCUtil.closeAll(rs, stmt, conn);}*///批处理JdbcForUser2 jfu = new JdbcForUser2();jfu.batchDel();//System.out.println("批处理成功");}public void addUser(User user) {try {    conn = JDBCUtil.getConnection();String sql = " INSERT INTO user (id,name,password,phone,birthday) VALUES (?,?,?,?,?) ";stmt = conn.prepareStatement(sql);//预编译sqlstmt.setInt(1, user.getId());stmt.setString(2, user.getName());stmt.setString(3, user.getPassword());stmt.setString(4, user.getPhone());//stmt.setDate(5, new Date(System.currentTimeMillis()));stmt.setDate(5, user.getBirthday());stmt.execute();} catch (Exception e) {e.printStackTrace();}finally {JDBCUtil.closeAll(rs, stmt, conn);}}public User getById(int id) {User user = null;try {conn = JDBCUtil.getConnection();String sql = " SELECT * FROM user WHERE id = ?";PreparedStatement stmt = conn.prepareStatement(sql);stmt.setInt(1, id);ParameterMetaData  pmd = stmt.getParameterMetaData();System.out.println(pmd.getParameterCount());//获取参数个数//System.out.println(pmd.getParameterTypeName(2));ResultSet rs = stmt.executeQuery();ResultSetMetaData rsmd = rs.getMetaData();System.out.println(rsmd.getColumnCount());for(int i = 0; i < rsmd.getColumnCount(); i++){System.out.println(rsmd.getColumnName(i+1));}user = new User();while(rs.next()){user.setName(rs.getString("name"));user.setPhone(rs.getString("phone"));user.setBirthday(rs.getDate("birthday"));}} catch (Exception e) {e.printStackTrace();}finally {JDBCUtil.closeAll(rs, stmt, conn);}return user;}//批处理,对应Statement和preparedStatement的两种批处理方式public void batchDel(){try {conn = JDBCUtil.getConnection();Statement stmt = conn.createStatement();//添加批处理语句stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (1,'oo','oo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (2,'ooo','ooo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (3,'oooo','oooo',111)");stmt.addBatch("INSERT INTO user (id,name,password,phone) VALUES (4,'ooooo','ooooo',111)");stmt.addBatch("UPDATE user SET name = '杨' WHERE id = 2 ");stmt.executeBatch();//执行批处理语句stmt.clearBatch();//去除缓存/*String sql = "DELETE FROM user WHERE id = ?";    stmt = conn.prepareStatement(sql);*/    /*for(int i = 1; i < 5; i++){stmt.setInt(1, i);stmt.addBatch();//添加批处理语句}*//*for(int i = 25; i > 14; i--){stmt.setInt(1, i);stmt.addBatch();//添加批处理语句}stmt.executeBatch();//执行批处理语句stmt.clearBatch();//去除缓存*/} catch (Exception e) {e.printStackTrace();}finally {JDBCUtil.closeAll(rs, stmt, conn);}}}



User类

package TestJDBC;import java.sql.Date;public class User {private int id;private String name;private String password;private String phone;private Date birthday;public User(int id, String name, String password, String phone, Date birthday){this.id = id;this.name = name;this.password = password;this.phone = phone;this.birthday = birthday;}public User(){}public User(int id, String name, String password){this.id = id;this.name = name;this.password = password;}public User(int id, String name, String password, String phone){this.id = id;this.name = name;this.password = password;this.phone = phone;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}


————————over——————————

好记性不如烂笔头,总结为一篇博客,下次需要时或者有所忘记的时候,可以再来瞧瞧

1 0
原创粉丝点击