上一篇博客 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 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 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);//可以不用,会自动变为false
JDBCUtil.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);//可以不用,会自动变为false
JDBCUtil.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);//预编译sql
stmt.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——————————
好记性不如烂笔头,总结为一篇博客,下次需要时或者有所忘记的时候,可以再来瞧瞧