接上节:
对上节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‘, ‘[email protected]‘)"; 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("[email protected]"); 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
时间: 2024-10-07 23:15:02