java JDBC4 事务、Threadlocal 线程安全


在这里插入图片描述
  按照 DAO 将昨天的 用户管理系统写完。
  数据库。
在这里插入图片描述

  代码结构。分为 dao,service 业务,entity 用户,utils 工具类,user 用户管理。
在这里插入图片描述


public class DBUtiles {

    public  static final String URL = "jdbc:mysql://localhost:3306/mydb1?characterEncoding=utf-8";
    public  static final String USERNAME = "root";
    public  static final String PASSWORD = "Liu01234";
    public  static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";

    public static Connection getConnection() {

        try {
            Class.forName(DRIVER_CLASS);
            return DriverManager.getConnection(URL,USERNAME,PASSWORD);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void close(AutoCloseable ...args) {
        for (AutoCloseable c : args) {
            if (c != null) {
                try {
                    c.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


@Data  //自动生成set get
@AllArgsConstructor  //设置一个全参构造器
@NoArgsConstructor  // 设置一个无参构造器
public class User {

    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer sex;


    @Override
    public String toString() {

        String sexName = "";
        if (sex == 1) {
            sexName = "男";
        } else if (sex == 2) {
            sexName = "女";
        } else {
            sexName = "程序员";
        }

        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", sex=" + sexName +
                '}';
    }
}


public interface IUserDao {

    public int addUser(User user);
    public List<User> getUserList();
    public int deleteUserByUsername(String username);
    public int updateUser(User user);
    public User getUserByUsername(String username);
}


public class UserDaoImpl implements IUserDao {


    @Override
    public int addUser(User user) {

        Connection connection = DBUtiles.getConnection();
        PreparedStatement prst = null;

        try {
            prst = connection.prepareStatement("insert into t_user(username,password,age,sex) value(?,?,?,?)");
            prst.setString(1,user.getUsername());
            prst.setString(2,user.getPassword());
            prst.setInt(3,user.getAge());;
            prst.setInt(4,user.getSex());;


            int i = prst.executeUpdate();
            return i;

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtiles.close(prst, connection);
        }

        return 0;
    }

    @Override
    public List<User> getUserList() {

        Connection connection = DBUtiles.getConnection();
        PreparedStatement prst = null;
        ResultSet resultSet = null;

        List<User> userlist = new ArrayList<>();

        try {
            prst = connection.prepareStatement("select * from t_user");
            resultSet = prst.executeQuery();

            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                int sex = resultSet.getInt("sex");
                int age = resultSet.getInt("age");

                User user = new User(id,username,password,age,sex);
                userlist.add(user);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtiles.close(resultSet, prst, connection);
        }

        return userlist;
    }

    @Override
    public int deleteUserByUsername(String username) {

            Connection connection = DBUtiles.getConnection();
            PreparedStatement prst = null;

            try {
                prst = connection.prepareStatement("delete from t_user where username = ?");
                prst.setString(1, username);

                int i = prst.executeUpdate();
                return i;

            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DBUtiles.close(prst, connection);
            }


        return 0;
    }

    @Override
    public int updateUser(User user) {



            Connection connection = DBUtiles.getConnection();
            PreparedStatement prst = null;

            try {
                prst = connection.prepareStatement("update t_user set password=?,age=?,sex=? where username=?");
                prst.setString(1,user.getPassword());
                prst.setInt(2,user.getAge());
                prst.setInt(3,user.getSex());
                prst.setString(4,user.getUsername());

                int i = prst.executeUpdate();
                return i;

            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DBUtiles.close(prst, connection);
            }


        return 0;
    }

    public User getUserByUsername(String username) {

        if (username == null || username.length() == 0) {
            System.out.println("用户名不能为空");
            return  null;
        }

        Connection connection = DBUtiles.getConnection();
        PreparedStatement prst = null;
        ResultSet resultSet = null;
        User user = null;

        try {
            prst = connection.prepareStatement("select * from t_user where username = ?");
            prst.setString(1,username);
            resultSet = prst.executeQuery();

            if (resultSet.next()) {
                user = new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setAge(resultSet.getInt("age"));
                user.setSex(resultSet.getInt("sex"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtiles.close(resultSet,prst,connection);
        }

        return user;

    }
}


public interface IUserService {

    public int addUser(User user);
    public List<User> getUserList();
    public int deleteUserByUsername(String username);
    public int updateUser(User user);
    public User getUserByUsername(String username);

    public User login(String username, String password);
}


public class UserServiceImpl implements IUserService {

    private IUserDao userDao = new UserDaoImpl();

    @Override
    public int addUser(User user) {
        return userDao.addUser(user);
    }

    @Override
    public List<User> getUserList() {
        return userDao.getUserList();
    }

    @Override
    public int deleteUserByUsername(String username) {
        return userDao.deleteUserByUsername(username);
    }

    @Override
    public int updateUser(User user) {
        return userDao.updateUser(user);
    }

    @Override
    public User getUserByUsername(String username) {
        return userDao.getUserByUsername(username);
    }

    @Override
    public User login(String username, String password) {

        User user = getUserByUsername(username);

        if (user != null) {
            if (user.getPassword().equals(password)) {
                return user;
            }

        }

        return null;
    }
}



public class UserManager {

    static Scanner scanner = new Scanner(System.in);
    // 实例化 Service 层
    static IUserService userService = new UserServiceImpl();

    public static void main(String[] args) {

        System.out.println("欢迎");

        while (true) {

            System.out.println("1.添加 2.修改 3.删除 4.查询 5.登陆 6.退出");

            int num = 0;
            while (true) {
                try {
                    String text = scanner.next();
                    num = Integer.parseInt(text);
                    break;
                } catch (NumberFormatException e) {
                    System.out.println("请出入正确的编号");
                }
            }

            if (num == 1) {
                addUser();
            } else if (num == 2) {
                updateUser();
            } else if (num == 3) {
                deleteUser();
            } else if (num == 4) {
                getUserList();
            } else if (num == 5) {
                login();
            } else if (num == 6) {
                System.out.println("good bye...");
                System.exit(-1);
            }

        }

    }

    private static void login() {
        System.out.println("请输入用户名:");
        String username = scanner.next();


        System.out.println("请输入密码:");
        String password = scanner.next();

        if (username == null || username.length() == 0) {
            System.out.println("用户名不能为空");
            return;
        }

        User user = userService.login(username, password);
        if (user != null) {
            System.out.println(username + "已登陆");
        } else  {
            System.out.println("用户名 或 密码错误..");
        }


    }

    private static void getUserList() {

        List<User> userList = userService.getUserList();
        for (User user:userList) {
            System.out.println(user);
        }

    }

    private static void deleteUser() {

        System.out.println("请输入要删除的用户名");
        String username = scanner.next();

        User user = userService.getUserByUsername(username);
        if (user != null) {

            int i1 = userService.deleteUserByUsername(username);
                if (i1 > 0) {
                    System.out.println("删除成功");
                } else {
                    System.out.println("删除失败");
                }


        } else  {
            System.out.println(username + "\t" + "用户不存在");
        }

    }

    private static void updateUser() {
        System.out.println("请输入要修改的用户名");
        String username = scanner.next();

        User user = userService.getUserByUsername(username);
        if (user != null) {
            User newUser = inputUserInfo();
            newUser.setUsername(username);
            int i = userService.updateUser(newUser);

                if (i > 0) {
                    System.out.println("修改成功");
                } else {
                    System.out.println("修改失败");
                }



        } else  {
            System.out.println(username + "\t" + "用户不存在");
        }

    }

    private static User inputUserInfo() {
        System.out.println("输入用户的密码:");
        String password = scanner.next();

        System.out.println("输入用户的年龄:");
        int age = scanner.nextInt();

        System.out.println("输入用户的性别:");
        int sex = scanner.nextInt();

        User user = new User();
        user.setPassword(password);
        user.setSex(sex);
        user.setAge(age);
        return user;
    }



    private static void addUser() {

        System.out.println("输入用户的姓名:");
        String username = scanner.next();

        User user = inputUserInfo();
        user.setUsername(username);


        int i = userService.addUser(user);
        if (i > 0) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }

    }

}

  Threadlocal 线程安全。ThreadLocal 提供了线程内存储变量的能力,这些变量不同之处在于每一个线程读取的变量是对应的互相独立的。通过get和set方法就可以得到当前线程对应的值。


// ThreadLocal<String> 和 String 作对比。
public class Test1 {

	// String str = null;
    static ThreadLocal<String> str = new ThreadLocal<>();

    public static void main(String[] args) {

        String name = Thread.currentThread().getName();

        str.set(name);

        for (int i = 0; i < 10; i ++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String name = Thread.currentThread().getName();
                    str.set(name);
                    System.out.println(name + " --- " + str.get());
                }
            },"name_" + i).start();

        }

        System.out.println(name + " --- " + str.get());

    }

}

  ThreadLocal 应用于Connection。用户管理系统例子。
  数据库。
在这里插入图片描述

  代码结构。分为 dao,service 业务,user 用户, utils 工具类,controller 用户控制管理。
在这里插入图片描述


public class DBUtils {

    public  static final String URL = "jdbc:mysql://localhost:3306/mydb1?characterEncoding=utf-8";
    public  static final String USERNAME = "root";
    public  static final String PASSWORD = "Liu01234";
    public  static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";

    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    public static Connection getConnection() {

        Connection connection = threadLocal.get();

        System.out.println("connection = " + connection );

        if (connection == null) {

            try {
                Class.forName(DRIVER_CLASS);

                connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);

                threadLocal.set(connection);

            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            }

        }
        return connection;
    }

    public static void close(AutoCloseable ...args) {
        for (AutoCloseable c : args) {
            if (c != null) {
                try {
                    c.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


@Data
@AllArgsConstructor
@NoArgsConstructor

public class Account {

    private  Integer id;

    private String name;

    private String password;

    private double balance;

}


public interface IAccountDao {

    // 账户加钱
    public int in(String inName,Double money);

    // 账户扣钱
    public int out(String outName,Double money);

    Account getAccountByUsername(String username);

}


public class AccountDaoImpl implements IAccountDao {
    @Override
    public int in(String inName, Double money) {

        Connection connection = DBUtils.getConnection();

        PreparedStatement prst = null;
        try {
            String sqlString = "update t_account set balance = balance + ? where name = ?";
            prst = connection.prepareStatement(sqlString);
            prst.setDouble(1, money);
            prst.setString(2, inName);

            int i = prst.executeUpdate();
            return i;

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    @Override
    public int out(String outName, Double money) {

        Connection connection = DBUtils.getConnection();

        PreparedStatement prst = null;
        try {
            String sqlString = "update t_account set balance = balance - ? where name = ?";
            prst = connection.prepareStatement(sqlString);
            prst.setDouble(1, money);
            prst.setString(2, outName);

            int i = prst.executeUpdate();
            return i;

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    @Override
    public Account getAccountByUsername(String username) {


        Connection connection = DBUtils.getConnection();

        PreparedStatement prst = null;

        ResultSet resultSet = null;

        Account account = null;

        try {
            String sqlString = "select * from t_account where name = ?";
            prst = connection.prepareStatement(sqlString);
            prst.setString(1, username);

            resultSet = prst.executeQuery();

            if (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String password = resultSet.getString("password");
                double balance = resultSet.getDouble("balance");

                account = new Account(id,name,password,balance);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return account;
    }
}


public interface IAccountService {
    // 转账方法
    public void  transfer(String name, String password, Double money, String inName);

}


public class AccountServiceImpl implements IAccountService {

    private IAccountDao accountDao = new AccountDaoImpl();

    @Override
    public void transfer(String name, String password, Double money, String inName) {

        Account account = accountDao.getAccountByUsername(name);

        if (account == null) {
            System.out.println(name + "不存在");
            return;
        }

        if (!account.getPassword().equals(password)) {
            System.out.println("账户或密码错误");
            return;
        }

        // 判断金额
        if (money > account.getBalance()) {
            System.out.println("余额不足");
            return;
        }

        // 判断对方账户是否存在
        Account inAccount = accountDao.getAccountByUsername(inName);

        if (inAccount == null) {
            System.out.println("对方账户不存在");
            return;
        }

        // 扣钱
        accountDao.out(account.getName(),money);

        accountDao.in(inName, money);

        System.out.println("转账成功..");
    }
}


public class JdbcTransactionController {

    static IAccountService accountService = new AccountServiceImpl();

    public static void main(String[] args) {

        // 直接写入假数据
        String username = "zs";
        String password = "123";
        Double money = 200.0;
        String inName = "ls";

        accountService.transfer(username, password, money, inName);

    }
}


  JDBC 事务。


public class Test1 {

    public static void main(String[] args) {

        Connection con = DBUtils.getConnection();

        PreparedStatement prst = null;

        try {
        	// 设置手动管理事务
            con.setAutoCommit(false);

            String sqlString = "update t_account set balance = balance - ? where name = ?";

            prst = con.prepareStatement(sqlString);

            prst.setDouble(1,100.0);
            prst.setString(2,"zs");

            prst.executeUpdate();

            System.out.println("修改余额成功。。");

            // 提交事务
            con.commit();

        } catch (SQLException e) {
            e.printStackTrace();

            // 出错 回滚事务
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

        } finally {
            DBUtils.close(prst,con);
        }


    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值