• 第6章 数据库事务 & 第7章 DAO及相关实现类


    第6章 数据库事务 

    1.数据库事务介绍

    *事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态

    *事务处理:保证所有事务都作为一个工作单元来执行

    2.JDBC事务处理

    *数据一旦提交则不可回滚

    *导致数据自动提交的操作:DDL操作、DML默认情况、关闭连接时

    3.事务的ACID属性

    (1)ACID属性

    原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生

    一致性:事务必须使数据库从一个一致性状态变换到另一个一致性状态

    隔离性:一个事务的执行不能被其他事务干扰

    持久性:一个事务一旦被提交,它对数据库中数据的改变就是永久性的

    (2)数据库的并发问题

       脏读:对于两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段。之后,若T2回滚,T1读取的内容就是临时且无效的。

       不可重复读:对于两个事务T1,T2,T1读取了一个字段,然后 T2 更新了该字段。之后, T1再次读取同一个字段,值就不同了。

       幻读:对于两个事务T1, T2, T1从一个表中读取了一个字段, 然后T2在该表中插入了一些新的行。之后,如果T1再次读取同一个表,就会多出几行。

    (3)四种隔离级别

    *Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE。

    Oracle 默认的事务隔离级别为: READ COMMITED

    *Mysql 支持 4 种事务隔离级别。

    Mysql 默认的事务隔离级别为: REPEATABLE READ

    (4)在MySQL中设置隔离级别

    第7章 DAO及相关实现类

    *BaseDAO:装针对于数据表的通用操作;使用abstract修饰,表示不能被实例化;针对不同的表提供具体的DAO

    *xxDAO接口:用于规范针对某数据表的常用操作

    *xxDAOImpl抽象类:继承BaseDAO,实现xxDAO接口

    BaseDAO:

    1. package chapter7;
    2. import utils.JDBCUtiles;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.ParameterizedType;
    5. import java.lang.reflect.Type;
    6. import java.sql.*;
    7. import java.util.ArrayList;
    8. /*封装针对于数据表的通用操作*/
    9. /*使用abstract修饰,表示不能被实例化*/
    10. /*针对不同的表提供具体的DAO*/
    11. public abstract class BaseDAO {
    12. private Class clazz=null;
    13. {
    14. //获取当前子类的泛型
    15. Type genericSuperclass = this.getClass().getGenericSuperclass();
    16. ParameterizedType paramType= (ParameterizedType) genericSuperclass;
    17. Type[] actualTypeArguments = paramType.getActualTypeArguments();
    18. clazz=(Class) actualTypeArguments[0];
    19. }
    20. //通用的查询操作,用于返回查询结果集(考虑事务)
    21. public ArrayList getInstance(Connection conn, String sql, Object ...args){
    22. ArrayList ts = null;
    23. PreparedStatement pr = null;
    24. ResultSet resultSet = null;
    25. try {
    26. ts = new ArrayList<>();
    27. pr = conn.prepareStatement(sql);
    28. for (int i = 0; i < args.length; i++) {
    29. pr.setObject(i+1,args[i]);
    30. }
    31. resultSet = pr.executeQuery();
    32. ResultSetMetaData metaData = resultSet.getMetaData();
    33. int columnCount = metaData.getColumnCount();
    34. while (resultSet.next()){
    35. T t = clazz.newInstance();
    36. for (int i = 0; i < columnCount; i++) {
    37. Object value = resultSet.getObject(i + 1);
    38. String name = metaData.getColumnLabel(i + 1);
    39. Field declaredField = clazz.getDeclaredField(name);
    40. declaredField.setAccessible(true);
    41. declaredField.set(t,value);
    42. }
    43. ts.add(t);
    44. }
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. } finally {
    48. JDBCUtiles.closeResource(null,pr,resultSet);
    49. }
    50. return ts;
    51. }
    52. //通用的增删改操作,获取连接和关闭连接都在外部进行
    53. public int update(Connection conn,String sql,Object... args){
    54. PreparedStatement pr=null;
    55. try {
    56. pr = conn.prepareStatement(sql);
    57. for (int i = 0; i < args.length; i++) {
    58. pr.setObject(i+1,args[i]);
    59. }
    60. return pr.executeUpdate();
    61. } catch (SQLException e) {
    62. e.printStackTrace();
    63. } finally {
    64. JDBCUtiles.closeResource(null,pr);
    65. }
    66. return 0;
    67. }
    68. //用于查询特殊值的通用方法
    69. public E getValue(Connection conn,String sql,Object... args){
    70. PreparedStatement pr = null;
    71. ResultSet resultSet = null;
    72. try {
    73. pr = conn.prepareStatement(sql);
    74. for (int i = 0; i < args.length; i++) {
    75. pr.setObject(i+1,args[i]);
    76. }
    77. resultSet = pr.executeQuery();
    78. if(resultSet.next()){
    79. return (E)resultSet.getObject(1);
    80. }
    81. } catch (SQLException e) {
    82. e.printStackTrace();
    83. } finally {
    84. JDBCUtiles.closeResource(null,pr,resultSet);
    85. }
    86. return null;
    87. }
    88. }

    xxDAO接口

    1. package chapter7;
    2. import bean.Customer;
    3. import java.sql.Connection;
    4. import java.util.Date;
    5. import java.util.List;
    6. /*此接口用于规范针对于customers表的常用操作*/
    7. public interface CustomerDAO {
    8. //将cust对象添加到数据库中
    9. void insert(Connection conn, Customer cust);
    10. //根据指定的ID删除表中的一条记录
    11. void deleteByID(Connection conn,int id);
    12. //根据指定的ID修改数据表中的记录
    13. void updateByID(Connection conn,int id,Customer cust);
    14. //根据指定的ID查询对应的Customer对象
    15. Customer getCustomerByID(Connection conn,int id);
    16. //查询表中的所有记录构成的集合
    17. List getAll(Connection conn);
    18. //返回数据表中数据的条目数
    19. Long getCount(Connection conn);
    20. //返回数据表中最大的生日
    21. Date getMaxBirth(Connection conn);
    22. }

    xxDAOImpl抽象类:

    1. package chapter7;
    2. import bean.Customer;
    3. import java.sql.Connection;
    4. import java.util.ArrayList;
    5. import java.util.Date;
    6. import java.util.List;
    7. public class CustomerDAOImpl extends BaseDAO implements CustomerDAO{
    8. //将cust对象添加到数据库中
    9. @Override
    10. public void insert(Connection conn, Customer cust) {
    11. String sql="insert into customers(name,email,birth) values(?,?,?)";
    12. update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth());
    13. }
    14. //根据指定的ID删除表中的一条记录
    15. @Override
    16. public void deleteByID(Connection conn, int id) {
    17. String sql="delete from customers where id=?";
    18. update(conn,sql,id);
    19. }
    20. //根据指定的ID修改数据表中的记录
    21. @Override
    22. public void updateByID(Connection conn, int id, Customer cust) {
    23. String sql="update customers set name=?,email=?,birth=? where id=? ";
    24. update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth(),id);
    25. }
    26. //根据指定的ID查询对应的Customer对象
    27. @Override
    28. public Customer getCustomerByID(Connection conn, int id) {
    29. String sql="select name,email,birth from customers where id=?";
    30. ArrayList instance = getInstance(conn, sql, id);
    31. return instance.get(0);
    32. }
    33. //查询表中的所有记录构成的集合
    34. @Override
    35. public List getAll(Connection conn) {
    36. String sql="select name,email,birth from customers ";
    37. ArrayList instance = getInstance(conn, sql);
    38. return instance;
    39. }
    40. //返回数据表中数据的条目数
    41. @Override
    42. public Long getCount(Connection conn) {
    43. String sql="select count(1) from customers";
    44. Object value = getValue(conn, sql);
    45. return (Long) value;
    46. }
    47. //返回数据表中最大的生日
    48. @Override
    49. public Date getMaxBirth(Connection conn) {
    50. String sql="select max(birth) from customers";
    51. Object value = getValue(conn, sql);
    52. return (Date) value;
    53. }
    54. }

     

  • 相关阅读:
    数据库与Socket学习
    Flask-SQLAlchemy 中使用显式主主数据库设置
    jmeter(二):jmeter组件总结,利用取样器中http发送请求
    【Java笔试强训】Day1(100449-组队竞赛 、OR63 删除公共字符)
    Navicat 使用教程
    【开源项目】libfaketime安装、使用——小白教程
    为什么Java有了synchronized之后还造了Lock锁这个轮子?
    Nacos 开源版的使用测评
    python-(6-4-1)爬虫---利用re解析获得数据信息
    在域控用命令批量创建OU,并增加防删除功能
  • 原文地址:https://blog.csdn.net/weixin_47687315/article/details/127885871