jdbc简讲

开篇

1.1 实际开发中会采用客户端操作嘛?

在实际的开发中当用户数据发生不可改变时,不可能通过客户端操执行sql语句因为操作量打无法保证效率和准确性

二‘ 什么是jdbc (Java database connectivity)

2.1什么是jdbc?

jdbc java 连接数据库,可以使用java语言连接数据库crun操作

2.2jdbc核心思想

java 中定义了访问数据库接口,可以为多种关系数据库提供统一的访问方式有数据库厂商提共驱动实现(drive数据库驱动)

 

2.3.1 mysql数据库驱动

mysql-connector-java-5.1x 适用于5.x版本

mysql-connector-java-8.0x 适用于8.x版本

2.3.2 jdbc API

jdbc是由多个接口和类进行功能实现

类型权限定名简介
classjava.sql.DriverManager管理多个数据库类,提供了获取数据库连接的方法
interfacejava.sql.Connection代表一个数据库连接(当connection 不是null 表示连接数据库成功)
interfacejava.sql.Statement发送sql语句到数据库工具
interfacejava.sql.ResultSet保存sql查询语句的结果数据
classjava.sql.cqlException处理数据库应用程序是所发生的异常

2.4环境搭建

1.在项目下新建lib 文件夹,用于存放jar文件

2.将mysql 驱动MySQL-connector-java-8.x复制到项目的lib文件夹中

3.选中lib文件夹右键add as libraay,点击ok

三,jdbc 开发步骤

3.1 注册驱动

     使用Class,forName("com.mysql.jdbc.Driver"); 手动加载字节码文件到jvm  中

 Class.froName("com.mysql.Driver");    加载驱动

3.2连接数据库

 String url ="jdbc:mysql://localhost:3306/baga";
        String user ="root";
        String password ="root";
 ​
        Connection connection= DriverManager.getConnection(url,user,password);

3.3获取发送SQL的对象

通过Connection 对象获得Statement 对象,用于对数据库进行通用访问

 Statement  statement =connection.createStatement();

3.4执行SQL语句

执行SQL语句并接受执行结果

 String    sql="insert into 表名 (表属性1,表属性2) values(值1,值2)";
  • 注意:在编写DML语句时,一定要注意字符串参数的符号是单引号'值'

  • DML 语句:增删改时,返回受影响行数(int 类型)

  • DQL 语句: 查询时,返回结果数据(resultset 结果集)。

3.5处理结果

接受处理操作结果

 if(result==1){
 System.out.println("Success");
 }
  • 受影响行数:逻辑判断,方法返回。

  • 查询结果集:迭代,依次获取

3.6释放资源

遵循先开后关原则,释放所使用到的资源对象

         statement.close();
         connection.close();

创建java连接MySQL创建数据步骤 缺一不可

         //1.注册驱动  加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
 ​
        //2.获得连接
        String url ="jdbc:mysql://localhost:3306/baga";
        String user ="root";
        String password ="root";
 ​
        Connection connection= DriverManager.getConnection(url,user,password);
 ​
         if(connection!=null){
             System.out.printf("连接到数据库");
         }else {
             System.out.printf("连接失败");
         }
         // 3.获取执行SQL    语句的对象
         Statement statement = connection.createStatement();
         //4.编写SQL语句,执行SQL语句
      String sql=   "INSERT INTO   user(id,name) VALUES(2,'雪橇犬')";
 ​
      int result=statement.executeUpdate(sql);   //DML语句
       //  System.out.println(result);
         //5.处理接受结果
         if (result==1){
             System.out.println("创建成功");
         }else {
             System.out.println("创建失败");
         }
       //6.释放资源 先开后关
 ​
         statement.close();
         connection.close();

四, ResultSet (结果集)

在执行查询SQl 后,存放查询到的结果数据

4.1 接受结果集

ResultSet rs=statement.executeQuery(sql);

 ResultSet rs=statement.executeQuery("select * from 表名");

4.2遍历ResultSet 中的数据

ResultSet 以表(tabel ) 结构进行临时结果的存贮,需要通过jdbc ApI 将其中数据进行获取

  • 数据行指针:初始位置阿紫第一行数据前,没调用一次Boolean next () 方法ResultSet 的指针向下移动一行,结果为true ,表示当前行有数据

  • rs.getXXX (整数); 代表根据咧的序号顺序获得,从一开始

  • rs.getXXX ("列名");代表根据列名获得

 boolean nest ()  throws SQLException  //判断 rs 结果集中下一行是否存在数据

五,常见错误

  • java.lang.ClassNotFoundException :找不到类(类名书写错误。没有导入jar包)

  • java.sql.SQLException:与sql语句相关的错误(约束错误、表名类名书写错误)建议:在客户端工具中测试SQL语句之后在粘贴在代码中

  • com.mysql.jdbc.exception.jdbc4.MySQLSyntaxErrorException:Unknown column 原因 :列值Sting 类型没有加单引号

  • Douplicate entry '1' for key 'PRIMAY' 原因主键值已存在或混乱,更改主键值或清空表

  • com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column 'password' in原因可能输入的值类型不对,确认是否插入的元素时对应的值的类型正确

六,综合案例

6.1创建表

  • 创建一张用户表 User

    • id,主键,自动增长

    • 用户名,字符串类型,唯一,非空

    • 密码,字符串类型,非空

    • 手机号码,字符串类型

  • 插入2条数据测试

6.2实现登录

  • 通过控制台输入用户名和密码

  • 用户输入的用户名和密码为条件,编写查询Sql语句

  • 如果该用户存在,提示登录成功反之提示失败

6.3代码实现

 Scanner scanner = new Scanner(System.in);
         System.out.println("请输入用户名");
         String username = scanner.next();
         System.out.println("请输入密码");
         String password = scanner.next();
 ​
         Class.forName("com.mysql.cj.jdbc.Driver");
 ​
     Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/baga","root","root");
         Statement statement = connection.createStatement();
         ResultSet resultSet=    statement.executeQuery("select * from users where username='"+username+"' and password='"+password+"'");
             if (resultSet.next()){
                 System.out.println("登陆成功");
             }else {
                 System.out.println("登陆失败");
             }
 ​
             resultSet.close();
             statement.close();
             connection.close();

七,SQl注入问题

7.1什么是SQL注入

用户输入的数据有SQL关键字或语法并且参与了SQL语句的编译,导致SQL语句编译后的条件为true一直得到正确的结果。这种现象称为SQL注入

7.2如何避免SQL注入

由于编写的SQL语句实在用户输入数据,整合后在进行编译。所以为了避免SQL注入的问题,我们要使SQL语句在用户输入数据之前就已经进行完整的编译SQl语句,在进行填充数据

八, PreparedStatement(重点)

PreparedStatement继承了Statement接口,所以执行SQL语句的方法无异

作用:1. 预编译SQL语句,效率高

2.安全,避免SQL注入

3.可以动态的填充数据,执行多个同构的SQL的语句

8.1.1参数标记

 //1.预编译
         PreparedStatement prepareStatement=  
         connection.prepareStatement("select * from users where username=? and password=?;");
  • 注意:JDBC中的所有参数都由? 符号占位符,这也被称之为参数标记。在执行SQL语句之前,必须为每个参数提供值

8.1.2动态参数绑定

pstmt.setXXX (下标,值) 参数下标从1开始 ,为指定参数下表绑定值

         PreparedStatement prepareStatement=   connection.prepareStatement("select * from users where username=? and password=?;");
         //为? 站位符 赋值
 ​
         prepareStatement.setString(1,username);
         prepareStatement.setString(2,password);

九, 封装工具类

 

9.1重用性方案

     //获取连接   getConnection
     public static Connection getConnection(){
         Connection connection=null;
         try {
             Class.forName("com.mysql.cj.jdbc.Driver");
              connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/baga","root","root");
             return connection;
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return connection;
     }
     //2.释放资源
     public static void colseAll(Connection connection, Statement statement, ResultSet resultSet){
         try {
             if (connection!=null){
                 connection.close();
             }
             if (statement!=null){
                 statement.close();
             }
             if (resultSet!=null){
                 resultSet.close();
             }
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
     }
 ​

10.1跨平台方案

  • 定义 pulblic static final Properties prop=new Properties(); //读取配置文件

  • 定义

  •  static {
         InputStream is= DBUtils.class.getResourceAsStream("路径");  /通过复用本类自带流,读取 jdbc.properties 配置文件。classPath=bin
         try {
             PROPERTIES.load(is);  //通过流,prpo对象将流中的配置信息分割成键值对
     ​
            String  diverName=prpo.getProperty("driver");//通过driverName的键获取时对应的值
            (com.mysql.jdbc.Driver)
            Calss.forName(driverName);//加载驱动
            }       

10.2.1跨平台工具类实现

在src目录下新建DB.properties 文件

 driver=com.mysql.cj.jdbc.Driver
 url=jdbc:mysql://localhost:3306/baga
 username=root
 password=root

10.2.2工具类的封装

  private static final Properties PROPERTIES=    new Properties();
 ​
     static {
         InputStream is= DBUtils.class.getResourceAsStream("/db.properties");
         try {
             PROPERTIES.load(is);  //通过流,将配置文件内容加载到properties   集合
             Class.forName(PROPERTIES.getProperty("driver"));
         } catch (IOException e) {
             e.printStackTrace();
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
 ​
     }
         public static Connection getConnection(){
         Connection connection=null;
             try {
                 connection=   DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("username"),PROPERTIES.getProperty("password"));
             } catch (SQLException throwables) {
                 throwables.printStackTrace();
             }
             return connection;
         }
         public static void  closeAll(Connection connection, Statement statement, ResultSet resultSet){
             try {
                 if (resultSet!=null){
                     resultSet.close();
                 }
                 if (statement!=null){
                     statement.close();
                 }
                 if (resultSet!=null){
                     resultSet.close();
                 }
             } catch (SQLException throwables) {
                 throwables.printStackTrace();
             }

十,ORM

ORM(object Relational Mapping)

从数据库查询的结果集(ResultSet) 在进行遍历时,逐行遍历,取出的都是零散的数据。在实际应用开发中,我们需要将零散的数据进行封装整理

11.1实体类(entity): 零散数据的载体

  • 一行数据中,多个零散的数据进行整理

  • 通过entity的规则对表中的数据进行对象的封装

  • 表名=类名; 列名=属性名 ; 提供各个属性的get set 方法

  • 提供无参构造方法(视情况添加有参构造)

11.2实体类演示

 public class Users {
     private   int id;
     private String username;
     private String password;
     private String phone;
      public Users() {
     }
 ​
     public Users(int id, String username, String password, String phone) {
         this.id = id;
         this.username = username;
         this.password = password;
         this.phone = phone;
     }
 ​
     public int getId() {
         return id;
     }
 ​
     public void setId(int id) {
         this.id = id;
     }
 ​
     public String getUsername() {
         return username;
     }
 ​
     public void setUsername(String username) {
         this.username = username;
     }
 ​
     public String getPassword() {
         return password;
     }
 ​
     public void setPassword(String password) {
         this.password = password;
     }
 ​
     public String getPhone() {
         return phone;
     }
 ​
     public void setPhone(String phone) {
         this.phone = phone;
     }
 ​
     @Override
     public String toString() {
         return "Users{" +
                 "id=" + id +
                 ", username='" + username + '\'' +
                 ", password='" + password + '\'' +
                 ", phone='" + phone + '\'' +
                 '}';
     }
    }

十一,DAO 数据访问对象(Data Access Object)

  • DAO实现了业务逻辑与数据库访问相分离

    • 对同一张表的所有封装在XXXDaolmp对象中

    • 根据增删改查的不同功能实现具体的方法(insert ,update, delete, select, selectAll)

 

12.1创建数据库

  • 创建一张表Person 有以下列:

    • id : int ,主键 自动增长

    • name :varcahr(20) 非空

    • age : int 非空

    • bornDtae : Date

    • email : 字符串

    • address: 字符串

12.2封装实体类

创建entity 实体类 Person 编写属性私有化 构造方法 get/set 方法

12.3编写DAOLMPL类

编写DAOLMPL 类,提供增删改查方法,使用JDBC 开发步骤,完成功能。

12.4实现六个方法

      //新增
 ​
 public int insert(Person person){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
 ​
         String sql="insert into person(name,age,borndate,email,address) values(?,?,?,?,?);";
         try {
             connection=  DBUtils.getConnection();
             preparedStatement=    connection.prepareStatement(sql);
             preparedStatement.setString(1,person.getName());
             preparedStatement.setInt(2,person.getAge());
             preparedStatement.setDate(3,null);
             preparedStatement.setString(4,person.getEmail());
             preparedStatement.setString(5,person.getAddress());
             int result = preparedStatement.executeUpdate();
             return   result ;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             DBUtils.closeAll(connection,preparedStatement,null);
         }
         return 0;
     }
 ​
 ​
    PersonDaoImpl personDao = new PersonDaoImpl();
         Person person = new Person("Gavin",19,null,"Gavin@163.com","洛阳市");
 ​
         int result = personDao.insert(person);
         if(result==1){
             System.out.println("新增成功");
         }else {
             System.out.println("新增失败");
         }
 //修改
     public int update(Person person){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
        String sql="update person  set name=?,age=?,borndate=?,email=?,address=? where id=?";
         try {
             connection=DBUtils.getConnection();
             preparedStatement= connection.prepareStatement(sql);
             preparedStatement=    connection.prepareStatement(sql);
             preparedStatement.setString(1,person.getName());
             preparedStatement.setInt(2,person.getAge());
             preparedStatement.setDate(3,null);
             preparedStatement.setString(4,person.getEmail());
             preparedStatement.setString(5,person.getAddress());
             preparedStatement.setInt(6,person.getId());
             int result = preparedStatement.executeUpdate();
             return result;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             DBUtils.closeAll(connection,preparedStatement,null);
         }
         return 0;
     }
 ​
 ​
 ​
 ​
  PersonDaoImpl personDao = new PersonDaoImpl();
         Person person=  new Person(1,"a",20,null,"a@163.com","河南省");
         int result = personDao.update(person);
 ​
         if(result==1){
             System.out.println("新增成功");
         }else {
             System.out.println("新增失败");
         }
 //删除
     public int delete(int id){
         Connection connection =null;
         PreparedStatement preparedStatement=null;
         String sql="delete from person where id=?";
         try {
             connection = DBUtils.getConnection();
             preparedStatement = connection.prepareStatement(sql);
             preparedStatement.setInt(1,id);
             int resulr = preparedStatement.executeUpdate();
             return resulr;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
         DBUtils.closeAll(connection,preparedStatement,null);
         }
 ​
 ​
         return 0;
     }
 ​
 ​
         PersonDaoImpl personDao = new PersonDaoImpl();
         int result = personDao.delete(2);
         if (result==1){
             System.out.println("删除成功");
         }else {
             System.out.println("程序错误");
         }
 //查单个
     public Person select( int id) {
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         ResultSet resultSet=null;
         String sql="select * from person where id=?;";
         Person person=null;
 ​
         try {
             connection=   DBUtils.getConnection();
             preparedStatement = connection.prepareStatement(sql);
             preparedStatement.setInt(1,id);
             resultSet=  preparedStatement.executeQuery();
             if (resultSet.next()){
                  person = new Person();
               int pid=  resultSet.getInt("id");
               String name=resultSet.getString("name");
               int age = resultSet.getInt("age");
                 Date borndate=resultSet.getDate("borndate");
                 String email=resultSet.getString("email");
                 String address=resultSet.getString("address");
                 person.setId(pid);
                 person.setName(name);
                 person.setAge(age);
                 person.setBornDate(borndate);
                 person.setEmail(email);
                 person.setAddress(address);
 ​
             }
             return person;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             DBUtils.closeAll(connection,preparedStatement,resultSet);
         }
         return null;
     }
 ​
 ​
         PersonDaoImpl personDao = new PersonDaoImpl();
         Person select = personDao.select(1);
         if (select!=null){
             System.out.println(select);
         }else {
             System.out.println("没有该数据");
         }
 ​
  //查所有
     public List<Person> selectAll(){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         ResultSet resultSet=null;
         Person person=null;
         List<Person> personList= new ArrayList<>();
         try {
             connection=   DBUtils.getConnection();
             preparedStatement = connection.prepareStatement("select * from person");
          resultSet=   preparedStatement.executeQuery();
          while (resultSet.next()){
              int pid=  resultSet.getInt("id");
              String name=resultSet.getString("name");
              int age = resultSet.getInt("age");
              Date borndate=resultSet.getDate("borndate");
              String email=resultSet.getString("email");
              String address=resultSet.getString("address");
            person=  new Person(pid,name,age,borndate,email,address);
         personList.add(person);
          }
          return   personList;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             DBUtils.closeAll(connection,preparedStatement,resultSet);
         }
 ​
         return null;
     }
 ​
 ​
  PersonDaoImpl personDao = new PersonDaoImpl();
         List<Person> personList=personDao.selectAll();
         for(Person p: personList){
             System.out.println(p);
         }

十二` Date 工具类

现有问题:数据库存储数据类型为java.sql.Date .而我们java.util.Date 当我们用java应用程序插带有日期的数据到数据库中时,需要进行转换

12.1 java.util.Date

  • java语言常规应用层面的日期类型,可以通过字符串创建的时间对象

  • 无法直接通过JDBC插入到数据库

12.2java.sql.Date

  • 不可以通过字符串创建对应的时间对象,只能通过毫秒值创建对象(1970年至今的毫秒值)

  • 可以直接通过JDBC插入到数据库中

12.3SimpleDateFormat

格式化和解析日期的具体类。允许进行格式化(日期》文本),解析(文本>日期)和规范化

12.3.1SimpleDateFormat应用

将日期转换封装成一个类

 private static  SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
     //1.字符串转换为util.Date
     public  static java.util.Date strToUtil(String str){
         try {
             Date date = sdf.parse(str);
             return  date;
         } catch (ParseException e) {
             e.printStackTrace();
         }
         return null;
     }
     //2.util.Date转换为sql.Date
     public  static java.sql.Date utilToSql(java.util.Date date){
         return  new java.sql.Date(date.getTime());
     }
     //3.util.Date 转换为字符串形式
     public  static  String utilToStr (java.util.Date date){
         return sdf.format(date);
     }

十三·业务层逻辑

13.什么是业务

代表一个用户完成的业务,可以有多个DAO的调用组成(软件的所有功能都叫业务)

 

13.2业务开发流程

13.2.1.代码实现

 

三个类:AccountDaoImpl

AccountServiceImpl

TestAccount

  public int insert(Account account){
             return 0;
         }
         public int delete(String card){
             return 0;
         }
         //修改
     public int update(Account account){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         String sql="update account set password=? ,name=?,balance=?  where cardNo=?";
         try {
             connection= DBUtils.getConnection();
             preparedStatement=  connection.prepareStatement(sql);
             preparedStatement.setString(1,account.getPassword());
             preparedStatement.setString(2,account.getName());
             preparedStatement.setDouble(3,account.getBalance());
             preparedStatement.setString(4,account.getCardNo());
             int  result=preparedStatement.executeUpdate();
             return result;
 ​
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
             return 0;
     }
 ​
     //查询单个
     public Account  select (String cardNo){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         ResultSet resultSet=null;
         Account account =null;
         String sql="select * from account where cardNo=?";
         try {
           connection=  DBUtils.getConnection();
             preparedStatement=   connection.prepareStatement(sql);
             preparedStatement.setString(1,cardNo);
              resultSet = preparedStatement.executeQuery();
              if (resultSet.next()){
                  String cardNos = resultSet.getString("cardNo");
                  String password = resultSet.getString("password");
                  String name = resultSet.getString("name");
                  double balance = resultSet.getDouble("balance");
                  account=new Account(cardNo,password,name,balance);
 ​
              }
                 return account;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return null;
  public void transfer(String formNo,String pwd,String toNo,double money){
         try {
             AccountDaoImpl accountDao = new AccountDaoImpl();
             //2.组织完善业务
             //2.1验证fromNo是否存在
             Account account =accountDao.select(formNo);
             if (account==null){
                 throw new RuntimeException("卡号不存在");
             }
             //2.2验证formNo的密码是否正确
             if (!  account.getPassword().equals(pwd)){
                 throw new RuntimeException("密码不正确");
             }
             //2.3验证余额是否充足
             if (account.getBalance()<money){
                 throw new RuntimeException("余额不足");
             }
             //2.4验证toNO是否存在
             Account   toAccount =accountDao.select(toNo);
             if (account==null){
                 throw new RuntimeException("对方卡号不存在");
             }
             //2.5减少fromNO的余额
             account.setBalance(account.getBalance()-money);
             accountDao.update(account);
             //2.6增加tono的余额
             toAccount.setBalance(toAccount.getBalance()+money);
             accountDao.update(toAccount);
             System.out.println("转账成功");
         } catch (RuntimeException e) {
             System.out.println("转账失败");
             e.printStackTrace();
         }
     }
      AccountServiceImpl accountService = new AccountServiceImpl();
         accountService.transfer("6002","1234","6003",1000);

十四,事务

14.1service层控制事务

 

14.2解决方案:传递Connection

为了解决线程中Connection对象不同的问题,可以将Connection对象通过service传递给各个DAO方法

14.2.1传递问题

  • 如果使用传递COnnection,容易造成窗口污染(Bad Smell)。

  • 定义接口是为了更容易更换实现,而将Connection定义在接口中会造成污染档期那接口

14.3解决方案2:ThreadLocal

  • 可以将整个线程中(单线程)中,存储一个共享值

  • 线程拥有一类似Map的属性,键值对结构TheadLoca 对象,值

14.4ThreadLocal应用

一个线程共享同一个ThraedLocal在整个流程中任何一环可以存值或取值

十五,事务的封装

15.1工具类

     private  static final Properties PROPERTIES=new Properties();
     private static ThreadLocal<Connection>  threadLocal=new ThreadLocal<>();
     //获取连接
     static {
         try {
             InputStream is = DBUtils.class.getResourceAsStream("/db.properties");
             PROPERTIES.load(is);
             Class.forName(PROPERTIES.getProperty("driver"));
         } catch (IOException e) {
             e.printStackTrace();
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
 ​
     }
     //开启事务
     public static void begin(){
         try {
             Connection connection=getConnection();
             connection.setAutoCommit(false);
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
     }
     //提交事务
     public static void commit(){
         Connection connection=null;
         try {
 ​
                 connection=    getConnection();
             connection.commit();
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             closeAll(connection,null,null);
         }
     }
     //回滚事务
     public static void rollback(){
         Connection connection=null;
         try {
 ​
             connection=    getConnection();
             connection.rollback();
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             closeAll(connection,null,null);
         }
     }
     public   static Connection getConnection(){
         Connection connection=threadLocal.get();//将当前线程中Connnection对象赋值connection
         try {
             if (connection==null) {
                 connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
 ​
             threadLocal.set(connection);//把链接存在线程中
 ​
             }
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return connection;
     }
     public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){
         try {
             if (connection!=null){
                 connection.close();
                 threadLocal.remove();//关闭连接,移除已关闭connection对象
             }
             if (statement!=null){
                 statement.close();
             }
             if (resultSet!=null){
                 resultSet.close();
             }
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
     } 

十六·三层架构

16.1什么是三层架构

  1. 表示层:

命名:XXXView

职责:收集用户的数据和需求,展示数据

2.业务逻辑层

命名:XXXServiceLmpl

职责:数据加工处理,调用DAO完成业务实现,控制事务。

3.数据访问层

命名:XXXDaoImpl

职责:向业务层提供数据,将业务层加工后的数据同步数据库

16.2三层架构项目搭建(按开发步骤)

 

  • utils存放工具类(DButils)

  • entity存放实体类(Person)

  • dao存放DAO接口(PersonDao)

    • impl存放service接口(PersonService)

  • view存放程序启动类(main)

  • 程序设计,考虑易修改,易扩展,为Service层和DAO层设计接口,便于未来更换实现类

十七,DaoUtils

17.1commonsUpdate

 public int commonsUpdate(String sql,Object... args){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         connection=  DBUtils.getConnection();
         try {
              preparedStatement = connection.prepareStatement(sql);
             for (int i = 0; i < args.length; i++) {
                 preparedStatement.setObject(i+1,args[i]);
             }
             int result=preparedStatement.executeUpdate();
            return result ;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }finally {
             DBUtils.closeAll(null,preparedStatement,null);
         }
         return 0;
     }

17.2commonsSelect

 public List<T>  commonsSelect(String sql, RowMapper<T> rowMapper, Object... args){
         Connection connection=null;
         PreparedStatement preparedStatement=null;
         ResultSet resultSet=null;
         List<T>   list=new ArrayList<>();
         connection=  DBUtils.getConnection();
         try {
        preparedStatement=    connection.prepareStatement(sql);
        if (args!=null){
             for (int i = 0; i < args.length; i++) {
                 preparedStatement.setObject(i+1,args[i]);
                 
             }
        }
             resultSet=preparedStatement.executeQuery();
             while (resultSet.next()){
             //id,name,age,bordate,email,address
                 //如何根据查询结果完成ORM如何进行对象的创建赋值
                 T t=rowMapper.getRow(resultSet);//回调--》调用者提供的一个封装方法ORM
                 list.add(t);
             }
             return list;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return null;
     }

十八,连接池

在程序初始时,预先创建指定数量的数据库连接数据库在池中。当需要连接数据库时,从连接池中取出现有连接;使用完毕后,也不会进行关闭,而是放回池中,实现复用,节省资源。

18.1Druid 连接池使用步骤

  • 创建database.properties配置文件。

  • 引入druid-1.1.5.jar 文件

18.1.1database.properties配置文件

 driver=com.mysql.cj.jdbc.Driver
 url=jdbc:mysql://localhost:3306/baga
 username=root
 password=root
 #初始化连接
 initialSize=10
 #最大连接数量
 maxActive=30
 #最小空闲连接
 maxIdle=5
 #超时等待时间
 maxWait=3000

十九,Apache的DBUtils使用

Commons DbUtils 是Apache组织提供的一个对JDBC进行间的封装的开源工具类库,使用它能够简化JDBC应用程序的开发!同时不会影响程序的性能

19.1DbUtils简介

  • DbUtils是Java编程中数据库操作实用小工具,小巧,简单。实用

    • 对于数据表的查询操作,可以把结果咋混换为List,Array,set集合。便于操作

    • 对于数据的Dml操作,也可以变得很简单(只需要写SQL语句);

19.1.1DbUtils主要包含

  • ResultSetHandler接口;转换类型接口

    • BeanHandler类;实现类,把一条记录转换成对象

    • BeanListHandler类: 实现类,把多条记录转成List集合

    • ScalarHandler类;实现类,适合获取一行一列的数据

  • QueryRunner:执行sql语句的类

    • 增删改查 update( );

    • 查询:query( );

 

19.2.1代码实现

DBUtils工具类

 port javax.sql.DataSource;
 import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.Properties;
 ​
 public class DbUtils {
     private static DruidDataSource ds;
 ​
     static {
         Properties properties = new Properties();
          InputStream is= DbUtils.class.getResourceAsStream("/database.properties");
         try {
             properties.load(is);
             try {
             ds=(DruidDataSource)    DruidDataSourceFactory.createDataSource(properties);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
     public static Connection getConnection(){
         try {
             return ds.getConnection();
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return null;
     }
     public static DataSource getDataSource(){
         return ds;
     }
 }

UserDaoImpl访问数据对象

user接口

 public interface UserDao {
     public int insert(User user);
     public int update(User user);
     public int delete(int id);
     public User select(int id);
     public List<User> selectAll();
     //查询数量
     public long selectUserNums();
 ​
 }

实现类

 public class UserDaoImpl implements UserDao {
     private QueryRunner queryRunner=new QueryRunner(DbUtils.getDataSource());
     @Override
     public int insert(User user) {
         Object[] params={user.getUserid(),user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone()};
         try {
             final int result = queryRunner.update("insert into user(userid,username,password,address,phone) values (?,?,?,?,?)", params);
             return result;
         } catch (Exception e) {
             e.printStackTrace();
         }
         return 0;
     }
 ​
     @Override
     public int update(User user) {
         Object[] params={user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone(),user.getUserid()};
         try {
             int result=queryRunner.update("update user set username=?,password=?,address=?,phone=? where userid=?",params);
             return result;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return 0;
     }
 ​
     @Override
     public int delete(int id) {
 ​
         try {
             int result=   queryRunner.update("delete from user where userid=?",id);
             return  result;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
         return 0;
     }
 ​
     @Override
     public User select(int id) {
         try {
             User user=    queryRunner.query("select * from user where userid=?",new BeanHandler<User>(User.class),id);
             return user;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
 ​
         return null;
     }
 ​
     @Override
     public List<User> selectAll() {
         try {
             List<User> user=    queryRunner.query("select * from user ",new BeanListHandler<User>(User.class));
             return user;
         } catch (SQLException throwables) {
             throwables.printStackTrace();
         }
 ​
         return null;
     }
 ​
     @Override
     public long selectUserNums() {
             try {
                 long count=  queryRunner.query("select count(*) from user;",new ScalarHandler<>());
                 return count;
             } catch (SQLException throwables) {
                 throwables.printStackTrace();
         }
         return 0;
     }
 ​
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值