DButils

获得自增id

在这里插入图片描述
同样是插入用户后获得自增id,此时用的方法从update变成了insert,这个方法可以返回新增后的用户id,而无需自己再写一次last_insert_id()的sql语句获得,需要传入的参数有,sql, new ScalarHandler(),用户信息

 /**
     * 获得新增成功之后的id
     *
     * @param userInfo 完整的用户信息
     * @return 自增的id
     * @throws SQLException
     */
    int insertUserInfoId(UserInfo userInfo) throws SQLException;
 public int insertUserInfoId(UserInfo userInfo) throws SQLException {
        return queryRunner.insert(
                UserInfoSql.INSERT_USER_SQL,
                new ScalarHandler<BigInteger>(),
                userInfo.getUsername(),
                userInfo.getAge(),
                userInfo.getPass(),
                userInfo.getImage(),
                userInfo.getBirthday(),
                userInfo.getRid()).intValue();
    }

查询一个用户

第二个参数BeanHandler<>(Userinfo.class)

@Override
    public Userinfo selectOneUser(int id) throws SQLException {
        Userinfo query = q.query(UserInfoSql.SELECT_ONE_USER, new BeanHandler<>(Userinfo.class), id);
        return query;
    }

查询所有用户

此时第二个参数传的是BeanListHandler()

@Override
    public List<UserInfo> findAllUserInfo() throws SQLException {
        return queryRunner.query(
                UserInfoSql.FIND_ALL_SQL,
                new BeanListHandler<>(UserInfo.class, new BasicRowProcessor(new GenerousBeanProcessor())));
    }

查询所有用户,并分页展示

List findAllUserPage(int page,int size) throws SQLException;

@Override
    public List<UserInfo> findUserInfoByPage(int page, int size) throws Exception {
        return queryRunner.query(
                UserInfoSql.FIND_PAGE_SQL,
                new BeanListHandler<>(UserInfo.class, new BasicRowProcessor(new GenerousBeanProcessor())),
                (page-1)*size,size);
    }

多表查询

将字段看作key,记录看作value,每行记录都是一个键值对,用Map存储,再用List集合将Map集合存储起来,用来装配的处理器是MapListHander()

@Override
    public List<Map<String, Object>> findAllMgr() throws SQLException {
        return q.query(UserInfoSql.SELECT_MGR, new MapListHandler());
    }

事务

//数据库事务
//ACID 原子性 一致性 隔离性 持久性
// 隔离性:并发事务 根据隔离级别机制的不同 可能会产生不同的问题
//一共就有3个问题
//1. 脏读: 一个事务读到了另外一个事务没有提交的数据
//2. 不可重复读: 在一个事务内部 多次读取到数据 不一致的 (另外一个事务提交 insert/update)
//3.幻读: 在一个事务内部 与insert有关

//读未提交 read uncommitted  1  2  3
//读已提交  read committed  解决1  出现2  3
//可重复读  repeatable read 解决1  2  出现 3
//串行化(序列化) Serializable 解决 1  2  3
//机制越高 数据越安全  性能越低
//mysql: 可重复读
//oracle/sqlServer: 读已提交

模拟2个员工转账

开启事务需要在同一个数据源下,除此之外,想让两条sql语句变成一个事务,需要将自动提交更改为手动提交,通过两行代码使转账和收账处于同一事务下,更改手动提交需要借助数据源,这个数据源(从数据库连接池获得普通jdbc也可以)就是事务所使用的唯一数据源
测试:在不是一个数据源的情况下,无法处于一个事务,事务依然是自动提交
如何使用同一数据源:在dao层设置Connection属性,设置有参构造器,service层在创造对象时把数据源传过去,更新方法采用三个参数的(connection,sql,parameters)
//-- 7839 给 7369 转账
//-- 7839: sal-1000
//-- 7369: sal+1000
//
//UPDATE emp set sal=sal+1000 WHERE empno=7369;
//UPDATE emp set sal=sal-1000 WHERE empno=7839;
思路:
1.查询转账和被转账的对象(获得对象)
2…在service层处理转账动作(设置对象信息)
3.利用对象信息更新数据库信息

Test测试类

private static void transferAccounts() {
        EmpService es = new EmpServiceImpl();
        try {
            //1.获取两个对象
            Emp emp1 = u.selectEmpById(1011);
            Emp emp2 = u.selectEmpById(1001);
            //2.设置转账金额(为了避免丢精度选择Bigdecimal数据类型)
            BigDecimal money = new BigDecimal("1000");
            //3.开始转帐(需要处理两个对象中的信息,避免代码冗余,所以放到service层维护)
            es.dispote(emp1,emp2,money);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

service处理转账

public class EmpServiceImpl implements EmpService {

    @Override
    public void dispote(Emp e, Emp e2, BigDecimal money)  {
        Connection conn = null;
        try {
            conn = DruidUtil.getDatasource().getConnection();
            UserDao ud = new UserImpl(conn);
            e.setSal(e.getSal().subtract(money));
            e2.setSal(e2.getSal().add(money));
            //一个sql是一个事务,设置手动提交 使处于同一事务
            conn.setAutoCommit(false);
            //开始转账
            ud.updateEmp(e);
            ud.updateEmp(e2);
            System.out.println("转账成功");

            DbUtils.commitAndClose(conn);
        } catch (SQLException throwables) {
            try {
                DbUtils.rollbackAndClose(conn);  //遇到异常回滚
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
            throwables.printStackTrace();
        }
    }
}

dao层写获取对象和更新数据库的方法

public class UserImpl extends BaseDaoImpl<Userinfo> implements UserDao {
    static QueryRunner q = new QueryRunner(DruidUtil.getDatasource());

    private Connection conn;

    public UserImpl(Connection conn) {
        this.conn = conn;
    }
    public UserImpl(Class<Userinfo> tclass) {
        super(tclass);
    }
@Override
    public void updateEmp(Emp e) throws SQLException {
        q.update(conn,UserInfoSql.UPDATE_EMP,
                e.getEname(),
                e.getJob(),
                e.getMgr(),
                e.getHiredate(),
                e.getSal(),
                e.getComm(),
                e.getDeptno(),
                e.getEmpno());
    }
 @Override
    public Emp selectEmpById(int id) throws SQLException {
        List<Emp> execute = q.execute(UserInfoSql.SELECT_EMP,
                new BeanHandler<>(Emp.class, new BasicRowProcessor(new GenerousBeanProcessor())),
                id);
        return execute.get(0);
    }

模糊查询

private static void fuzzySearchByConditions() {
        StringBuilder sql = new StringBuilder("select * from emp");
        System.out.println("按 1.姓名 2.工作 3.无条件 查询(1,2,3)");
        Scanner a = new Scanner(System.in);
        String choice = a.next();
        String[] s = choice.split(",");
        Map<String,String> m = new HashMap<>(16);
        for (String s1 : s) {
            switch (s1) {
                case "1":
                    System.out.println("请输入姓名:");
                    String name = a.next();
                    m.put("ename",name);
                    break;
                case "2":
                    System.out.println("请输入工作:");
                    String job = a.next();
                    m.put("job",job);
                case "3":
                    break;
            }
        }
        if(m!=null)
        {
            sql.append(" where ");
            Set<String> key = m.keySet();
            for (String s1 : key) {
                sql.append(s1).append(" like '%' ? '%'").append(" or ");
            }
            sql = sql.delete(sql.lastIndexOf("or"), sql.length());
        }
        System.out.println(sql);
        try {
            List<Emp> emps = u.likeQueryByConditions(sql.toString(), m);
            for (Emp emp : emps) {
                System.out.println(emp);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

dao层

 @Override
    public List<Emp> likeQueryByConditions(String sql, Map<String, String> m) throws SQLException {
        Collection<String> values = m.values();
        int index = 0;
        String[] v = new String[2];
        for (String value : values) {
            v[index] = value;
            index++;
        }
        List<Emp> query = q.query(sql, new BeanListHandler<>(Emp.class), v);
        return query;
    }
Python DBUtils 是一个轻量级的 Python 数据库连接池库,支持多个线程和多个进程,并可与各种数据库后端一起使用。DBUtils 是一个纯 Python 库,没有其他依赖项。 DBUtils 的主要目的是提供一个共享数据库连接池,这样可以避免在不同的线程和进程中频繁地打开和关闭数据库连接。这可以极大地提高应用程序的性能和响应速度。 DBUtils 提供了一些常见的数据库连接池实现,包括 PooledDB,PersistentDB 和 StackedObjectPool。这些实现都提供了相同的接口,因此可以很容易地将它们用于不同的应用程序。 使用 DBUtils 可以在保持代码简洁的同时获得数据库连接池的好处。以下是一个使用 DBUtils 连接 MySQL 数据库的示例: ```python import pymysql from dbutils.pooled_db import PooledDB POOL = PooledDB( creator=pymysql, maxconnections=5, mincached=2, maxcached=5, blocking=True, maxusage=None, host='localhost', port=3306, user='root', password='password', database='test', charset='utf8mb4' ) def get_conn(): return POOL.connection() def query_data(sql): conn = get_conn() cursor = conn.cursor() cursor.execute(sql) result = cursor.fetchall() cursor.close() conn.close() return result ``` 在上面的示例中,我们使用 `PooledDB` 创建了一个 MySQL 数据库连接池,并使用 `get_conn` 获取一个连接对象,然后使用 `query_data` 函数执行 SQL 查询。注意,我们在使用完连接后需要手动关闭连接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值