第三章 JDBC连接数据库、封装与设计模式

1.JDBC连接数据库

(一)准备jar包

 mysql-connector-java-5.1.0-bin.jar

百度网盘链接:https://pan.baidu.com/s/1Lg1JXu7owpj-yxAvD_yCPA 
提取码:rx0v

(二)连接MySQL
  1. 加载驱动Class.forName("com.mysql.jdbc.Driver");

  2. 使用DriverManager获取数据库connection连接

  3. 创建Statement对象 用于执行SQL语句

  4. 执行SQL语句

  5. 释放资源

  Connection conn = null;
        Statement stat = null;
        try {
            //1.加载驱动  方言
            Class.forName("com.mysql.jdbc.Driver");
            //准备数据库连接路径
            String url = "jdbc:mysql://127.0.0.1:3306/xxshop";
            //用户名与密码
            String username = "root";
            String userpwd = "root";
            //2.根据路径,用户名,密码 使用DriverManager获取数据库connection连接
             conn = DriverManager.getConnection(
                    url,username,userpwd);
            //3.准备要执行的SQL语句
            String sql= "select user_id,user_name from sf_user";
            //创建Statement对象  用于执行SQL语句
            stat = conn.createStatement();
            //4.执行SQL语句
            ResultSet rs =  stat.executeQuery(sql);
            //处理ResultSet结果集
            //rs.next()  返回boolean 值
            while(rs.next()){
                 Long user_id =  rs.getLong(1);
                 String user_name = rs.getString(2);
                 System.out.println("用户ID:"+user_id);
                System.out.println("用户名:"+user_name);
            }
​
​
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5.释放资源
            try {
                stat.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
​

数据库驱动

SQLServer驱动:com.microsoft.jdbc.sqlserver.SQLServerDriver

MySQL驱动:com.mysql.jdbc.Driver

Oracle驱动:oracle.jdbc.driver.OracleDriver

(三)Statement常用对象

执行sql查询语句,并返回ResultSet对象

ResultSet executeQuery(sql)

 执行insert,update,delete语句,返回受影响行数

int executeUpdate(sql)

执行insert,update,delete语句,返回true或false false成功

boolean execute(sql)

防止数据库乱码及日期出错 (放入url连接路径之后)

?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
(四)PreparedStatement对象使用

防止SQL注入,使用占位符“?”方式进行SQL拼接

使用PreparedStatement对象进行用户登录

/**
* 定义登录方法(传入用户输入的用户名与密码)
*/
public User loginUser(String user_name,String user_pwd){
​
 Connection conn = null;
 PreparedStatement ps = null;
try {
//加载驱动  方言
Class.forName("com.mysql.jdbc.Driver");
   //准备数据库连接路径
 String url = "jdbc:mysql://127.0.0.1:3306/xxshop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull";
//用户名与密码
String username = "root";
String userpwd = "root";
//获取Connection对象
conn = DriverManager.getConnection(
                    url,username,userpwd);
//准备登录SQL语句  使用占位符?代表参数
String sql ="select user_id,user_name from sf_user where user_name=? and user_password=?";
//预编译SQL语句
ps = conn.prepareStatement(sql);
//ps.setXXXX(位置<从1开始>,值<参数>)
ps.setString(1,user_name);
ps.setString(2,user_pwd);
//执行查询
ResultSet rs = ps.executeQuery();
//用于判断 等于null登录失败,否则成功
User user = null;
   while(rs.next()){
 //进入循环,登录成功,创建user对象
   user = new User();
//使用rs.getXXX("返回的列名") 放入user对象
user.setUser_id(rs.getLong("user_id"));  
user.setUser_name(rs.getString("user_name"));
   }
   return user;//返回用户登录对象
  } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                ps.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
return null;
​
}
​

返回List集合核心代码

List<Goods> goodsList  = new ArrayList<Goods>();
    while(rs.next()){
        Goods goods = new Goods();
        goods.setGoods_id(rs.getLong("goods_id"));
        goods.setGoods_title(rs.getString("goods_title"));
        goods.setGoods_introduce(rs.getString("goods_introduce"));
        goodsList.add(goods);
    }
    return goodsList;

修改商品信息核心代码 对象入参

String sql = "update sf_goods set goods_title=?," +
                    "goods_browse=?,goods_state=? where goods_id=?";
        ps = conn.prepareStatement(sql);
        ps.setString(1,goods.getGoods_title());
        ps.setInt(2,goods.getGoods_browse());
        ps.setInt(3,goods.getGoods_state());
        ps.setLong(4,goods.getGoods_id());
​
        int i = ps.executeUpdate();
        return  i;

2.JDBC封装与设计模式

(一)DAO模式的应用

Data Access Object(数据存取对象) 持久层

创建包

com.dao ----放接口文件 UserDao

                    BaseDao(数据库工具类)

com.dao.impl----放接口实现类 UserDaoImpl

com.entity ----放实体类 User

封装JDBC
/**
 * 数据库工具类
 */
public class BaseDao {
​
    Connection conn = null;
    PreparedStatement ps = null;
    //获取Conn对象 打开数据库链接
    public boolean getConn() {
        boolean bool = false;//默认 false 未打开数据库
        try {
            //加载驱动  方言
            Class.forName("com.mysql.jdbc.Driver");
            //准备数据库连接路径
            String url = "jdbc:mysql://127.0.0.1:3306/xxshop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull";
            //用户名与密码
            String username = "root";
            String userpwd = "root";
            //根据路径,用户名,密码 使用DriverManager获取数据库connection连接
            conn = DriverManager.getConnection(
                    url,username,userpwd);
            bool = true;//已经打开
        } catch (Exception e) {
            e.printStackTrace();
            bool = false ;//已经打开
        }
            return  bool;
    }
​
    /**
     * 添加,修改,删除数据
     * @param sql
     * @param objs
     * @return
     */
    public int executeUpdate(String sql,Object objs[])
    {
        int res = 0;//初始化执行结果  失败0
        try {
            if(getConn())//打开数据库链接
            {
                ps = conn.prepareStatement(sql);
                if(objs!=null){
                    for (int i = 0; i < objs.length; i++) {
                        ps.setObject((i+1),objs[i]);
                    }
                }
                res = ps.executeUpdate();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeResource();//关闭数据源
        }
        return res;
    }
    /**
     * 查询
     * @param sql
     * @param objs
     * @return
     */
    public ResultSet executeSQL(String sql,Object objs[]){
​
        ResultSet rs = null;
        try {
            if(getConn())//打开数据库链接
            {
                ps = conn.prepareStatement(sql);
                //判断是否有参数
                if (objs != null) {
                    //循环封装参数
                    for (int i = 0; i < objs.length; i++) {
                        ps.setObject((i + 1), objs[i]);
                    }
                }
                rs = ps.executeQuery();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeResource();//释放资源
        }
​
        return rs;
    }
​
    //关闭资源
    public void closeResource(){
        try {
            if(ps!=null)
            {
                ps.close();
            }
            if(conn!=null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }​
}
​
调用工具类

实现类 继承 工具类(BaseDao)

查询:ResultSet rs = this.executeSQL(SQL语句,Object数组<参数数组>)

增,删,改: int i = this.executeUpdate(SQL语句,Object数组<参数数组>)

(二)使用配置文件存储连接信息(properties文件)

后缀为.properties

数据格式为“键=值“

使用“#”来注释

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/xxshop?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull jdbc.username=root jdbc.pwd=root
 Properties properties = new Properties();
//读取properties文件  BaseDao为当前所在类
 InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //将文件信息转换成properties对象
            properties.load(is);
            //通过getProperty(KEY)方法获取属性值
            String driver =  properties.getProperty("jdbc.driver");
​
单例模式

系统运行期间,有且仅有一个实例

  • 一个类只有一个实例——最基本的要求
  • 只提供私有构造器
  • 它必须自行创建这个实例
  • 定义了静态的该类私有对象
  • 它必须自行向整个系统提供这个实例
  • 提供一个静态的公有方法,返回创建或者获取本身的静态私有对象

为何需要单例模式

  • BaseDao:操作数据库的基类
  • 每个线程对系统操作都需new一个BaseDao实例
  • 初始化时的I/O操作消耗系统资源,影响系统性能
单例模式懒汉模式饿汉模式
概念在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例在类加载的时候,就完成初始化
特点类加载速度快,但是运行时获取对象的速度较慢。——“时间换空间”类加载较慢,但获取对象速度快。——“空间换时间”
延迟加载 (lazy loa ding)具备不具备
线程安全线程不安全线程安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值