当前位置: 首页 > news >正文

JAVA第一阶段结束喽后天更新第二阶段至于明天当然是练习时间回顾一下之前学的太良心了

3.4.3 分页查询

后端需要知道当前请求的是哪一页,每一页显示多少条数据

前端需要知道当前页的数据以及页面的总数量

-- 分页查询的sql语句
select * from user limit ?,?
第一个?: 这一页开始的索引  (page - 1) * pageSize
第二个?: pageSize
-- 查询总数量
select count(*) from user

  • UserDao接口中

/*** 分页查询* @param page   第几页* @param pageSize 一页显示多少条* @return 分页的数据*/List<User> queryUserByPage(int page,int pageSize);
​/*** 查询用户总数量* @return 总数量*/int queryUserCount();
  • UserDaoImpl中

@Overridepublic List<User> queryUserByPage(int page, int pageSize) {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "select * from user limit ?,?";PreparedStatement preparedStatement = null;ResultSet resultSet = null;List<User> list = new ArrayList<>();try {// 获取预编译对象preparedStatement = connection.prepareStatement(sql);// 给?赋值preparedStatement.setInt(1,(page - 1) * pageSize);preparedStatement.setInt(2,pageSize);// 执行sql语句,返回结果resultSet = preparedStatement.executeQuery();while (resultSet.next()){list.add(getUser(resultSet));}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return list;}
​@Overridepublic int queryUserCount() {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "select count(*) from user";PreparedStatement preparedStatement = null;ResultSet resultSet = null;// 定义总数量int totalRow = 0;try {// 获取预编译对象preparedStatement = connection.prepareStatement(sql);// 执行sql语句,获取结果集resultSet = preparedStatement.executeQuery();if (resultSet.next()){totalRow = resultSet.getInt(1);}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return totalRow;}
  • 测试方法

public static void main(String[] args)  {UserDao userDao = new UserDaoImpl();int page = 1;final int pageSize = 6;List<User> users = userDao.queryUserByPage(page, pageSize);int count = userDao.queryUserCount();// 计算总共有多少页int totalPage = (count % pageSize == 0) ? (count / pageSize) : (count / pageSize + 1);System.out.println("总记录数是" + count);System.out.println("总页数是" + totalPage);users.forEach(System.out::println);}
3.4.4 根据条件查询并分页
-- 条件
根据用户名模糊查询
根据年龄在区间范围内查询   minAge   maxAge
create_time区间范围内查询  beginTime   endTime-- 没有条件
select * from user limit ?,?-- 用户名
select * from user where username like ? limit ?,?-- 用户名 年龄
select * from user where username like ? AND age between ? AND ? limit ?,?-- 年龄
select * from user where age between ? AND ? limit ?,?-- 动态拼接sql语句
where username like ? and age between ? and ? and create_time between ? and ?;-- 按照条件查询总数量
-- 没有条件
select count(*) from user;-- 用户名
select count(*) from user where username like ?;-- 用户名 年龄
select count(*) from user where username like ? AND age BETWEEN ? AND ?;-- 动态拼接sql语句
where username like ? and age between ? and ? and create_time between ? and ?;

  • SearchParamVo

package cn.javasm.entity;import lombok.Data;@Data
public class SearchParamVo {/*** 用户名*/private String nameParam;/*** 最小年龄*/private Integer minAge;/*** 最大年龄*/private Integer maxAge;/*** 开始时间*/private String beginTime;/*** 结束时间*/private String endTime;
}

  • UserDao接口

/*** 按照条件查询并分页* @param searchParamVo  搜索条件* @param page     第几页* @param pageSize  每页显示的数量* @return 结果*/List<User> queryUserByParamAndPage(SearchParamVo searchParamVo,int page,int pageSize);/*** 获取条件查询记录的总数量* @param searchParamVo  条件* @return  总数量*/int queryUserByParamCount(SearchParamVo searchParamVo);
  • UserDaoImpl

@Overridepublic List<User> queryUserByParamAndPage(SearchParamVo searchParamVo, int page, int pageSize) {// 获取连接Connection connection = DBUtil.getConnection();// 拼接sql语句StringBuilder stringBuilder = new StringBuilder();// 拼接sql语句前面固定的内容stringBuilder.append("select * from user");// 动态拼接sqlappendSql(searchParamVo,stringBuilder);// 拼接sql语句后面固定的内容stringBuilder.append(" limit ?,? ");PreparedStatement preparedStatement = null;ResultSet resultSet = null;List<User> list = new ArrayList<>();try {// 获取预编译对象preparedStatement = connection.prepareStatement(stringBuilder.toString());// 给?赋值int count = setParameterCount(searchParamVo,preparedStatement);// 给limit的?赋值preparedStatement.setInt(count++,(page - 1) * pageSize);preparedStatement.setInt(count,pageSize);// 执行sql语句获取结果集resultSet = preparedStatement.executeQuery();while (resultSet.next()){list.add(getUser(resultSet));}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return list;}@Overridepublic int queryUserByParamCount(SearchParamVo searchParamVo) {// 获取连接Connection connection = DBUtil.getConnection();// 拼接固定的sql内容StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("select count(*) from user ");// 动态拼接sql语句appendSql(searchParamVo,stringBuilder);PreparedStatement preparedStatement = null;ResultSet resultSet = null;// 定义变量,记录总数量int totalRow = 0;try {// 获取预编译对象preparedStatement = connection.prepareStatement(stringBuilder.toString());// 给?赋值setParameterCount(searchParamVo,preparedStatement);// 执行sql语句,获取结果集resultSet = preparedStatement.executeQuery();if (resultSet.next()){totalRow = resultSet.getInt(1);}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return totalRow;}private int setParameterCount(SearchParamVo searchParamVo,PreparedStatement preparedStatement) throws SQLException {// 给?赋值Integer maxAge = searchParamVo.getMaxAge();String endTime = searchParamVo.getEndTime();String nameParam = searchParamVo.getNameParam();Integer minAge = searchParamVo.getMinAge();String beginTime = searchParamVo.getBeginTime();// 定义变量,记录参数的位置int count = 1;if (nameParam != null && !nameParam.isBlank()){// 有用户名preparedStatement.setString(count++,"%" + nameParam + "%");}if (minAge != null){// 有年龄preparedStatement.setInt(count++,minAge);preparedStatement.setInt(count++,maxAge);}if (beginTime != null && !beginTime.isBlank()){preparedStatement.setString(count++,beginTime);preparedStatement.setString(count++,endTime);}return count;}/*** 动态拼接sql*/private void appendSql(SearchParamVo searchParamVo,StringBuilder stringBuilder){// 获取参数String nameParam = searchParamVo.getNameParam();Integer minAge = searchParamVo.getMinAge();String beginTime = searchParamVo.getBeginTime();// 判断是否已经添加where   true代表添加过boolean flag = false;if (nameParam != null && !nameParam.isBlank()){stringBuilder.append(" WHERE username like ? AND");flag = true;}if (minAge != null){if (!flag) {stringBuilder.append(" WHERE ");flag = true;}stringBuilder.append(" age BETWEEN ? AND ? AND");}if (beginTime != null && !beginTime.isBlank()){if (!flag){stringBuilder.append(" WHERE ");flag = true;}stringBuilder.append(" create_time BETWEEN ? AND ? AND");}if (flag){// 如果有条件参数,删除掉最后一个多余的ANDstringBuilder.delete(stringBuilder.lastIndexOf("AND"),stringBuilder.length());}}
3.4.5 多表查询
-- 查询用户的id,用户名,用户年龄,用户角色,用户的部门
select 
u.id,u.username,u.age,r.role_name,d.dname
FROM
user u,role r,dept d
WHERE
u.rid = r.id
AND
u.did = d.deptno

  • 方式一

package cn.javasm.entity;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class UserRoleDeptVo {/*** id*/private Long id;/*** 用户名*/private String username;/*** 年龄*/private Integer age;/*** 角色名称*/private String roleName;/*** 部门名称*/private String dname;
}

在UserDao中提供抽象方法

/*** 查询用户信息和角色和部门* @return*/List<UserRoleDeptVo> queryUserAndRoleAndDept();

在UserDaoImpl中实现方法

@Overridepublic List<UserRoleDeptVo> queryUserAndRoleAndDept() {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "select \n" +"u.id,u.username,u.age,r.role_name,d.dname\n" +"FROM\n" +"user u,role r,dept d\n" +"WHERE\n" +"u.rid = r.id\n" +"AND\n" +"u.did = d.deptno";PreparedStatement preparedStatement = null;ResultSet resultSet = null;List<UserRoleDeptVo> list = new ArrayList<>();try {// 获取预编译对象preparedStatement = connection.prepareStatement(sql);// 执行sql,获取结果集resultSet = preparedStatement.executeQuery();while (resultSet.next()){long id = resultSet.getLong(1);String username = resultSet.getString(2);int age = resultSet.getInt("age");String roleName = resultSet.getString(4);String dname = resultSet.getString("dname");// 封装成对象UserRoleDeptVo userRoleDeptVo = new UserRoleDeptVo().setId(id).setRoleName(roleName).setAge(age).setUsername(username).setDname(dname);list.add(userRoleDeptVo);}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return list;}

  • 方式二

定义Role类

@Data
@Accessors(chain = true)
public class Role {/*** 角色id*/private Long id;/*** 角色名称*/private String roleName;/*** 角色描述*/private String roleDesc;
}

定义部门类

@Data
@Accessors(chain = true)
public class Dept {/*** 部门id*/private int deptno;/*** 部门名称*/private String dname;/*** 部门地址*/private String loc;
}

定义UserRoleDept

@Data
@Accessors(chain = true)
public class UserRoleDept {/*** 用户信息*/private User user;/*** 角色信息*/private Role role;/*** 部门信息*/private Dept dept;
}
  • UserDao接口中

/*** 查询用户和角色和部门信息*/List<UserRoleDept> queryUserAndRoleAndDeptAll();

UserDaoImpl中

@Overridepublic List<UserRoleDept> queryUserAndRoleAndDeptAll() {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "select \n" +" *\n" +"FROM\n" +"user u,role r,dept d\n" +"WHERE\n" +"u.rid = r.id\n" +"AND\n" +"u.did = d.deptno";PreparedStatement preparedStatement = null;ResultSet resultSet = null;List<UserRoleDept> list = new ArrayList<>();try {// 获取预编译对象preparedStatement = connection.prepareStatement(sql);// 执行sql语句,获取结果集resultSet = preparedStatement.executeQuery();while (resultSet.next()){User user = new User().setId(resultSet.getLong(1)).setUsername(resultSet.getString("username")).setAge(resultSet.getInt("age")).setBalance(resultSet.getBigDecimal("balance")).setCreateTime((LocalDateTime) resultSet.getObject("create_time"));Role role = new Role().setId(resultSet.getLong(11)).setRoleName(resultSet.getString(12)).setRoleDesc(resultSet.getString(13));Dept dept = new Dept().setDeptno(resultSet.getInt("deptno")).setDname(resultSet.getString("dname")).setLoc(resultSet.getString("loc"));UserRoleDept userRoleDept = new UserRoleDept().setUser(user).setRole(role).setDept(dept);list.add(userRoleDept);}} catch (SQLException e) {throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection,preparedStatement,resultSet);}return list;}

3.5 新增角色

-- 新增角色,指定角色可以执行的菜单功能-- 展示角色对应的权限菜单功能
select * from menu;-- 在角色表中新增一条记录
insert into role (role_name,role_desc) values(?,?)-- 在中间表中添加角色和菜单的关系
insert into role_menu (rid,mid) values(?,?),(?,?)...(?,?)

  • 创建Menu类

@Data
public class Menu {/*** id*/private Long id;/*** 菜单名称*/private String menuName;/*** 菜单地址*/private String menuUrl;/*** 菜单的父菜单id*/private Long parentMenuId;public static Menu getMenu(ResultSet resultSet) throws SQLException {Menu menu = new Menu();menu.setId(resultSet.getLong(1));menu.setMenuName(resultSet.getString(2));menu.setMenuUrl(resultSet.getString(3));menu.setParentMenuId(resultSet.getLong(4));return menu;}
}

  • 测试类

package cn.javasm.demo;import cn.javasm.dao.MenuDao;
import cn.javasm.dao.RoleDao;
import cn.javasm.dao.impl.MenuDaoImpl;
import cn.javasm.dao.impl.RoleDaoImpl;
import cn.javasm.entity.Menu;
import cn.javasm.entity.Role;import java.sql.SQLException;
import java.util.List;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.function.Predicate;public class TestDemo {public static void main(String[] args) throws SQLException {// 新增角色Scanner scanner = new Scanner(System.in);// 角色名称System.out.println("输入新的角色名称");String newRoleName = scanner.next();// 角色描述System.out.println("输入新的角色描述");String newRoleDesc = scanner.next();// 层级展示菜单MenuDao menuDao = new MenuDaoImpl();List<Menu> menuList = menuDao.queryAll();String str = "|- ";//  |- 1 用户管理// stream流menuList.stream().filter(menu -> menu.getParentMenuId() == 0).peek(parentMenu -> {System.out.println(str + parentMenu.getId() + ":" + parentMenu.getMenuName());queryChildMenu(parentMenu,menuList,"| " + str);}).count();System.out.println("对" + newRoleName + "角色选择对应的菜单功能(1,2,3)");// 获取用户输入的菜单的idString menuIdStr = scanner.next();String[] menuIds = menuIdStr.split(",");// 新增角色Role role = new Role().setRoleName(newRoleName).setRoleDesc(newRoleDesc);RoleDao roleDao = new RoleDaoImpl();// 添加角色后获取新增角色的idLong rid = roleDao.insertRole(role);// 新增中间表int row = roleDao.insertRoleAndMenu(rid, menuIds);System.out.println(row);}/*** 层级展示子菜单* @param parentMenu  父菜单* @param menuList    全部菜单* @param str         拼接字符串 美观*/private static void queryChildMenu(Menu parentMenu,List<Menu> menuList,String str){menuList.stream().filter(menu -> menu.getParentMenuId() == parentMenu.getId()).peek(menu -> {System.out.println(str + menu.getId() + ":" + menu.getMenuName());queryChildMenu(menu,menuList,"| " + str);}).count();}private static void demo() {// 传统写法  不适合动态菜单  只能菜单有三层
//        for (Menu menu : menuList) {
//            if (menu.getParentMenuId()== 0){
//                System.out.println(menu.getId() + ":" + menu.getMenuName());
//                for (Menu menu1 : menuList) {
//                    if (menu1.getParentMenuId() == menu.getId()){
//                        System.out.println("\t" + menu1.getId() + ":" + menu1.getMenuName());
//                        for (Menu menu2 : menuList) {
//                            if (menu2.getParentMenuId() == menu1.getId()){
//                                System.out.println("\t\t" + menu2.getId() + ":" + menu2.getMenuName());
//                            }
//                        }
//                    }
//                }
//            }
//        }}
}
  • MenuDao接口

public interface MenuDao {/*** 查询所有的菜单* @return*/List<Menu> queryAll() throws SQLException;
}
  • MenuDaoImpl中

public class MenuDaoImpl implements MenuDao {@Overridepublic List<Menu> queryAll() throws SQLException {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "select * from menu";// 获取预编译对象PreparedStatement preparedStatement = connection.prepareStatement(sql);// 执行sql语句ResultSet resultSet = preparedStatement.executeQuery();// 创建集合List<Menu> menuList = new ArrayList<>();while (resultSet.next()){menuList.add(Menu.getMenu(resultSet));}// 释放资源DBUtil.release(connection,preparedStatement,resultSet);return menuList;}
}
  • RoleDao接口中

public interface RoleDao {/*** 新增角色* @param role 角色对象* @return  插入角色的id*/Long insertRole(Role role) throws SQLException;/*** 新增中间表* @param rid     角色id* @param menuIds 菜单id的数组* @return 数据库受影响的行数*/int insertRoleAndMenu(Long rid,String[] menuIds) throws SQLException;
}
  • RoleDaoImpl中

public class RoleDaoImpl implements RoleDao {@Overridepublic Long insertRole(Role role) throws SQLException {// 获取连接Connection connection = DBUtil.getConnection();// 编写sql语句String sql = "insert into role (role_name,role_desc) values(?,?)";// 获取预编译对象PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);// 给?赋值preparedStatement.setString(1,role.getRoleName());preparedStatement.setString(2,role.getRoleDesc());// 执行sql语句preparedStatement.executeUpdate();// 获取上面刚刚插入角色的id  本质上是执行last_insert_id()函数ResultSet resultSet = preparedStatement.getGeneratedKeys();Long autoId = 0L;if (resultSet.next()){autoId = resultSet.getLong(1);}// 释放资源DBUtil.release(connection,preparedStatement);return autoId;}@Overridepublic int insertRoleAndMenu(Long rid, String[] menuIds) throws SQLException {// 获取连接Connection connection = DBUtil.getConnection();// 拼接sql语句 insert into role_menu (rid,mid) values(?,?),(?,?)...(?,?)StringBuilder stringBuilder = new StringBuilder();// 拼接固定的内容stringBuilder.append("insert into role_menu (rid,mid) values ");for (int i = 0; i < menuIds.length; i++) {stringBuilder.append("(?,?)");if (i == menuIds.length - 1) break; // 最后一个(?,?)没有 ,stringBuilder.append(",");}// 获取预编译对象PreparedStatement preparedStatement = connection.prepareStatement(stringBuilder.toString());// 定义变量,记录占位符?的位置int count = 1;// 给?赋值for (String menuId : menuIds) {preparedStatement.setLong(count++,rid);preparedStatement.setLong(count++,Long.parseLong(menuId));}// 执行sql语句int row = preparedStatement.executeUpdate();// 释放资源DBUtil.release(connection,preparedStatement);return row;}
}

4 MD5加密

在JDK中实现加密BASE64(可逆的)
加密 BASE64.Encoder
解密 BASE64.Decoder信息摘要算法
MD5  不可逆的
  • BASE64

public static void main(String[] args) {
//        Base64.Encoder encoder = Base64.getEncoder();
//        String str = encoder.encodeToString("123456".getBytes());
//        System.out.println(str);Base64.Decoder decoder = Base64.getDecoder();byte[] bytes = decoder.decode("MTIzNDU2");System.out.println(new String(bytes));}

  • MD5

package cn.javasm.util;import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class MD5Util {private static final String SALT = "ewgefefgt";public static String encode(String str) throws NoSuchAlgorithmException {//获取MD5对象MessageDigest messageDigest = MessageDigest.getInstance("MD5");str += SALT;messageDigest.update(str.getBytes());// 进行加密 将每个字节转换成2个16进制的字符byte[] digest = messageDigest.digest();BigInteger bigInteger = new BigInteger(1,digest);String string = bigInteger.toString(16);System.out.println(string);return new String(digest);}
}

5 DCL

事务是逻辑上的一组操作,组成这组操作的单元要么同时成功,要么同时失败

准备工作

create table account(id int PRIMARY KEY auto_increment,name varchar(255),money double
);insert into account values(null,'zs',1000);
insert into account values(null,'ls',1000);
insert into account values(null,'ww',1000);

5.1 MySql进行事务管理

  • 手动开启事务

start transaction; 开启事务
commit;   提交事务
rollback; 回滚事务

5.2 事务的特性和隔离级别[面试题]

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

eg: zs给ls转100
要么都成功  zs 900   ls 1100
要么都失败  zs 1000  ls 1000
  • 一致性:事务前后数据的完整性要保持一致

eg:  zs  1000   ls 1000    总共2000
成功  zs  900    ls 1100    总共2000
失败  zs  1000    ls 1000   总共2000
  • 持久性:指一个事务一旦被提交,它对数据库的数据改动是永久性的,接下来即使数据库发生故障也不应该对结果有任何影响

  • 隔离性: 事务的隔离性指多个用户并发操作数据库时,一个用户的事务不能被其他用户的事务所干扰。多个并发事务之间的数据要相互隔离。

5.2.2 没有隔离性会引发的问题

事务在理想状态下,所有的事务之间要保持隔离,互不影响。因为多个并发操作,多个用户同时访问数据,有可能引发数据安全问题。

可能出现的问题含义
脏读一个事务读取到了另一个事务中尚未提交的数据
不可重复读一个事务中两次读取到数据内容不一致,这是事务update时引发的问题
幻读一个事务中两次读取到的数据数量不一致,这是insert或者delete引发的问题
5.2.3 事务的隔离级别
级别名字隔离级别脏读不可重复读幻读数据库的默认级别
1读未提交read uncommitted
2读已提交read committed不会oracle
3可重复读repeatable read不会不会mysql
4串行化serializable不会不会不会

隔离级别越高,安全性越高,性能效率越差

  • 查看当前事务的隔离级别

select @@transaction_isolation;
  • 设置当前数据库事务的隔离级别(临时设置)

set session transaction isolation level 隔离级别
5.2.4 演示脏读

一个事务读取到了另一个事务尚未提交的数据 read uncommitted

  • 开启AB窗口

  • 设置A窗口的隔离级别为read uncommitted

set session transaction isolation level read uncommitted;
  • AB窗口都开启事务

  • 在B窗口中把zs的钱减少100,事务不要提交

  • 在A窗口中查询账户,发现账户内容改动,出现了脏读

5.2.5 演示不可重复读

不可重复读就是在一个事务里面,同一条sql语句,两次查询的结果不一致

  • 开启AB窗口

  • 设置A窗口的隔离级别时 读已提交(解决脏读)

set session transaction isolation level read committed;
  • AB窗口都开启事务

  • 在B中zs金额较少100,不提交事务

  • 在A中查看(避免了脏读)

  • 在B中提交事务

  • 在A中查看,发现数据改变,出现了不可重复读

5.2.6 演示隔离级别串行化
  • 开启AB窗口

  • 设置A窗口的隔离级别是串行化

set session transaction isolation level serializable;
  • AB窗口都开启事务

  • 在B中zs金额减少100,不提交事务

  • 在A中查询,会发现A中在等待B中提交事务

  • 在B中提交事务

  • 在A中查看,可以看到已经提交过的内容

5.2.7 代码级别使用事务
// 开启事务connection.setAutoCommit(false);// 提交事务connection.commit();// 回滚事务connection.rollback();

使用的时候注意,连接要保证是同一个,否则会回滚失败

public class RoleServiceImpl implements RoleService {@Overridepublic int insertRoleService(Role role, String[] menuIdArray) {// 编写业务逻辑  密码加密  事务控制  日志记录  权限检查...// 添加角色是一个业务逻辑  分为添加角色表和中间表// 获取连接Connection connection = DBUtil.getConnection();RoleDao roleDao = new RoleDaoImpl(connection);try {// 手动开启事务connection.setAutoCommit(false);// 添加角色表Long rid = roleDao.insertRole(role);
//            int i = 1 / 0;// 添加中间表int row = roleDao.insertRoleAndMenu(rid, menuIdArray);// 提交事务connection.commit();return row;} catch (Exception e) {try {// 回滚事务connection.rollback();} catch (SQLException ex) {throw new RuntimeException(ex);}throw new RuntimeException(e);}finally {// 释放资源DBUtil.release(connection);}}
}

6 连接池

6.1 连接池入门版本

  • 自定义连接池

public class MyDataSource1 {// 连接池private static LinkedList<Connection> pool;static {// 静态代码块// 创建连接池pool = new LinkedList<>();for (int i = 0; i < 5; i++) {pool.add(DBUtil.getConnection());}}/*** 提供连接*/public Connection getConnection(){Connection connection = pool.removeFirst();return connection;}/*** 归还连接*/public void addBack(Connection connection){pool.addLast(connection);}
}
  • 使用

6.2 连接池进阶版本

在上面的版本中,我们定义的方法是getConnection()获取连接,那么其他同学也可以使用getAbc()...来获取连接。

为了规范开发,sun公司提供了一套接口DataSource来定好方法的命名,各大厂商都实现了这套规范

  • 自定义连接池

public class MyDataSource2 implements DataSource {private static LinkedList<Connection> pool;static {pool = new LinkedList<>();for (int i = 0; i < 5; i++) {pool.add(DBUtil.getConnection());}}/*** 归还连接*/public void goHome(Connection connection){pool.addLast(connection);}/*** 获取连接* @return* @throws SQLException*/@Overridepublic Connection getConnection() throws SQLException {return pool.removeFirst();}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}
}
  • 使用

6.3 连接池最终版本

上面的连接池,归还的方法是goHome,依然没有规范。

能不能让连接池自带的close方法不再是关闭连接,而是归还连接?

我们的需求是要增强某一个类的某一些方法,可以考虑:继承重写,装饰者设计模式,代理设计模式

装饰者设计模式的作用:改写已存在的类的某个方法,增强方法的逻辑

使用装饰者设计模式需要满足的条件:

  • 增强类和被增强类实现的是同一个接口,或者有共同的父类

  • 增强类里面要拿到被增强类的引用

public class TestDemo3 {public static void main(String[] args) {Car car = new BYD(new BMW());car.run();car.stop();}
}
// 被增强类和增强类都实现的接口
interface Car{void run();void stop();
}
// 被增强类
class BMW implements Car{@Overridepublic void run() {System.out.println("百米加速10秒~");}@Overridepublic void stop() {System.out.println("skr~");}
}
// 增强类
class BYD implements Car{private Car car;public BYD(Car car){this.car = car;}@Overridepublic void run() {System.out.println("百米突破3秒~");}@Overridepublic void stop() {car.stop();}
}

  • 自定义MyConnection 增强类

// 增强类
public class MyConnection implements Connection {private Connection connection;// 被增强类的引用private LinkedList<Connection> pool;//连接池public MyConnection(Connection connection, LinkedList<Connection> pool) {this.connection = connection;this.pool = pool;}// 改写close的逻辑,变成归还@Overridepublic void close() throws SQLException {pool.addLast(connection);System.out.println("归还了" + connection);}@Overridepublic PreparedStatement prepareStatement(String sql) throws SQLException {return connection.prepareStatement(sql);}@Overridepublic void setAutoCommit(boolean autoCommit) throws SQLException {connection.setAutoCommit(autoCommit);}@Overridepublic boolean getAutoCommit() throws SQLException {return false;}@Overridepublic void commit() throws SQLException {connection.commit();}@Overridepublic void rollback() throws SQLException {connection.rollback();}@Overridepublic PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {return connection.prepareStatement(sql,autoGeneratedKeys);}

  • 自定义连接池

public class MyDataSource3 implements DataSource {private static LinkedList<Connection> pool;static {pool = new LinkedList<>();for (int i = 0; i < 5; i++) {pool.add(DBUtil.getConnection());}}@Overridepublic Connection getConnection() throws SQLException {Connection connection = pool.removeFirst();System.out.println("获取了" + connection);MyConnection myConnection = new MyConnection(connection,pool);return myConnection;}
  • 使用

http://www.dtcms.com/a/399900.html

相关文章:

  • 专业门户网站建设用流媒体做的电台网站
  • python(74) 调用dll文件
  • 国家关于网站信息建设管理文件郴州市人口
  • 温州市城市建设档案馆网站公司宣传册排版
  • redis的set集合的编码方式以及应用场景
  • 【MySQL初阶】03-常见的数据类型
  • CPU调用频率偏高 原因调查
  • Nest 中的数据库集成、JWT身份认证与任务调度全解析
  • 中小型企业网站建设与管理设计制作软件
  • 常德网站建设套餐报价怎么制作公司网页教程
  • 音频基础知识
  • 如何在网上建立自己的网站自助建站信息网
  • 网站域名找回密码 用户名景区网站的建设公司
  • HTML应用指南:利用GET请求获取全国奥迪授权经销商门店位置信息
  • golang基础语法(三)常量、指针、别名、关键字、运算符、字符串类型转换
  • 普定县建设局网站河北seo平台
  • dify-随笔
  • 免费开店的平台有哪些标题优化方法
  • seo顾问服务公司站长怎么做软文网站
  • 【JNA】JAVA使用JNA调用C++ dll文件(3)编译Linux版本.so文件
  • MyBatis 操作数据库(⼊⻔)
  • [baka编程]初入C++,如何理解新概念——类和对象
  • 竞价网站做推广一款app是如何制作出来的
  • 北京建设银行网站广东官网网站建设平台
  • 淘宝客怎么在网站做推广网站每年续费费用
  • Pyside6 + QML - 多线程01 - QThread 基础(子线程执行耗时任务)
  • 农产品应该建设哪个网站屏幕分辨率 网站开发
  • 摄影作品展示网站flash全站源码山东住建部和城乡建设官网
  • 购物网站功能模块图使用div建设的网站
  • Python爬虫实战:获取上海石油天然气交易中心2025年液化天然气交易数据并做分析