时间:2021-07-01 10:21:17 帮助过:21人阅读
对上节http://4440271.blog.51cto.com/4430271/1661684
程序修改:
package com.jike.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TransactionTest {
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/info", "*****", "******");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return conn;
}
// 向用户表中插入数据
// 对代码修改
public static void insertUserData(Connection conn) throws SQLException {
// ctrl+shift+f格式化代码
String sql = "insert into tbl_user(id, name, password, email)"
+ "values(10, ‘Tom‘, ‘2525252‘, ‘tom@123.com‘)";
Statement st = conn.createStatement();
int count = st.executeUpdate(sql);
System.out.println("向用户表中插入了" + count + "条数据");
// conn.close();
}
// 向地址表中插入数据
public static void insertAddressData(Connection conn) throws SQLException {
String sql = "insert into tbl_address(id, city, country, user_id)"
+ "values(1, ‘shanghai‘, ‘china‘, ‘10‘)";
Statement st = conn.createStatement();
int count = st.executeUpdate(sql);
System.out.println("向地址表中输入了" + count + "条记录");
// conn.close();
}
public static void main(String[] args) {
Connection conn = null;
try {
conn = getConnection();
conn.setAutoCommit(false); // 禁止事务自动提交
insertUserData(conn);
insertAddressData(conn);
// 这里,在提交insertAddressData方法是抛出异常,异常被捕获,因此事务回滚。
//提交事务
conn.commit();
} catch (Exception e) {
System.out.println("*************捕获到sq异常************");
e.printStackTrace();
try {
conn.rollback(); //如果提交失败则回滚
System.out.println("事务回滚成功");
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}finally{
try {
if(conn != null){
conn.close();
}
} catch (Exception e3) {
// TODO: handle exception
e3.printStackTrace();
}
}
}
}输出结果:

在数据库中:

数据没有插入,说明回滚成功,数据的一致性没有受到破坏。
JDBC 编程优化:
将配置信息提取出来,放到属性文件里面:
创建属性文件 : 在src目录下右键,点击 new--> other --> General-->File-->next---> 文件名. properties-->finish
点击add,添加如下内容:

点击下方的source可以看到:
新建如下两个类:

在工厂类中添加代码:
package com.jike.jdbc.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
// 创建数据库连接工厂类,放在util包下
public class ConnectionFactory {
// 创建四个成员变量用于保存从属性文件中读出的数据库配置信息
private static String driver;
private static String dburl;
private static String user;
private static String password;
private static final ConnectionFactory factory = new ConnectionFactory();
//定义Connection类型变量保持数据连接
private Connection conn;
// 配置信息的读取
static{//静态代码块用于初始化类,为类的属性赋值,静态代码块只执行一次
Properties prop = new Properties();//定义属性类,用于保存属性文件中的键值对
try {
InputStream in = ConnectionFactory.class.getClassLoader().
getResourceAsStream("dbcofig.properties");// 获取属性文件中的内容
// 首先获得当前类的类加载器,然后通过加载器中的getResourceAsStream方法读取属性文件中的内容。
// 这个方法将属性文件中的内容读取到一个输入流中
prop.load(in);//从输入流中读取属性列表,即属性文件中的键值对列表
} catch (Exception e) {
// TODO: handle exception
System.out.println("读取配置文件错误");
}
//将读取到的值赋值给成员变量
driver = prop.getProperty("driver");
dburl = prop.getProperty("dburl");
user = prop.getProperty("user");
password = prop.getProperty("password");
}
// 定义默认的构造函数
private ConnectionFactory(){
}
// 用于获取ConnectionFactory实例
public static ConnectionFactory getInstance(){
return factory;
}
// 获取数据库连接的方法
public Connection makeConnection(){
try {
Class.forName(driver);
conn = DriverManager.getConnection(dburl, user, password);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return conn;
}
}在测试类中添加如下代码:
package com.jike.test;
import java.sql.Connection;
import com.jike.jdbc.util.ConnectionFactory;
public class ConnectionFactoryTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
ConnectionFactory cf = ConnectionFactory.getInstance();
Connection conn = cf.makeConnection();
System.out.println(conn.getAutoCommit());
}
}测试结果为:true
然后创建相应的DTO

添加相应的实体类:
在IdEntity类中:
package com.jike.entity;
// 封装主键信息
public abstract class IdEntity {
protected Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}在User类中:
package com.jike.entity;
// 创建用户信息的实体类
public class User extends IdEntity {
// 添加成员属性,与数据库中user表的属性一一对应
private String name;
private String password;
private String email;
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [name=" + name + ", password=" + password + ", email="
+ email + ", id=" + id + "]";
}
}在Address类中:
package com.jike.entity;
public class Address extends IdEntity {
private String city;
private String country;
private Long userId;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public String toString() {
return "Address [city=" + city + ", country=" + country + ", userId="
+ userId + ", id=" + id + "]";
}
}这样,就完成了实体类的创建。
创建DAO

在接口UserDao中添加:
package com.jike.dao;
import java.sql.Connection;
import java.sql.SQLException;
import com.jike.entity.User;
//定义实现类的行为
public interface UserDao {
//定义对数据库的操作
public void save(Connection conn, User user) throws SQLException;
public void update(Connection conn, Long id, User user) throws SQLException;
public void delete(Connection conn, User user) throws SQLException;
}在接口的实现类UserDaoImpl中添加
package com.jike.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.jike.dao.UserDao;
import com.jike.entity.User;
public class UserDaoImpl implements UserDao {
/*
* 保存用户信息
*/
@Override
public void save(Connection conn, User user) throws SQLException {
// TODO Auto-generated method stub
//PreparedStatement是jdbc用于执行sql查询语句的api之一,用来执行参数化的查询
//?是占位符
PreparedStatement ps = conn.prepareStatement
("insert into tbl_user(name, password, email) values (?,?,?)");
//参数设置
ps.setString(1, user.getName());//索引从1开始
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.execute();
//将参数传入的user对象中的相关信息保存到数据库表中
}
/*
* 根据用户id更新用户信息
*/
@Override
public void update(Connection conn, Long id, User user) throws SQLException {
// TODO Auto-generated method stub
String updateSql = "update tbl_user set name=?, password=?, email=? where id=?";
PreparedStatement ps = conn.prepareStatement(updateSql);
ps.setString(1, user.getName());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.setLong(4, id);
ps.execute();
}
/*
* 删除指定的用户信息
*/
@Override
public void delete(Connection conn, User user) throws SQLException {
// TODO Auto-generated method stub
PreparedStatement ps = conn.prepareStatement("delete from tbl_user where id=?");
ps.setLong(1, user.getId());
ps.execute();
}
}添加测试程序:
package com.jike.test;
import java.sql.Connection;
import com.jike.dao.UserDao;
import com.jike.dao.impl.UserDaoImpl;
import com.jike.entity.User;
import com.jike.jdbc.util.ConnectionFactory;
public class UserDaoTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn = null;
try {
conn = ConnectionFactory.getInstance().makeConnection();
conn.setAutoCommit(false);
System.out.println(conn.getAutoCommit());
UserDao userDao = new UserDaoImpl();
User tom = new User();
tom.setName("Tom");
tom.setPassword("123");
tom.setEmail("tom@123.com");
userDao.save(conn, tom);
conn.commit(); //提交事务
} catch (Exception e) {
// TODO: handle exception
try {
conn.rollback();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}查看数据库,新加入的数据成功提交。
极客学院:http://www.jikexueyuan.com/course/566_6.html?ss=2
JSP(3) ----JDBC编程2
标签:java web