JDBC初步学习

JDBC:

Java Data Base Connectivity (java数据库连接)

如纽带一样连接着 Java 应用程序和数据库。

可以为多种数据库提供统一的访问
体现了Java“编写一次,处处运行”的伟大精神。

步骤:

例:

package com.imooc.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DBUtil {

    private static final String URL="jdbc:mysql://127.0.0.1:3306/imooc";
    private static final String USER="root";
    private static final String PASSWORD="root";

    public static void main(String[] args) throws Exception {

        // 加载驱动程序
        Class.forName("com.mysql.jdbc.Driver");

        // 获得数据库的连接
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);

        // 通过数据库的连接操作数据库,实现增删改查
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT user_name,age FROM imooc_goddess");  // 将查询的数据存放在这个对象里面

        // 如果对象里面有数据(rs.next返回true或false),就打印
        while(rs.next()) {
            System.out.println(rs.getString("user_name") + "," + rs.getString("age"));
        }
    }
}

样设:

写顺序:从下往上。

搭建模型层:

静态块: static {} 在类加载的时候就执行,且整个应用程序生命中只执行一次。

public class DBUtil {

    private static final String URL = "jdbc:mysql://127.0.0.1:3306/imooc";
    private static final String USER = "root";
    private static final String PASSWORD = "root";

    private static Connection conn = null;

    static {
        try {

            // 加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");

            // 获得数据库的连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);

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

    public static Connection getConnection() {
        return conn;
    }

}

要有数据库对应的实体类

public class Goddess {

    private Integer id;
    private String user_name;
    private Integer sex;
    private Integer age;
    private Date birthday;
    private String email;
    private String mobile;
    private String create_user;
    private String update_user;
    private Date create_date;
    private Date update_date;
    private Integer isbel;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getCreate_user() {
        return create_user;
    }

    public void setCreate_user(String create_user) {
        this.create_user = create_user;
    }

    public String getUpdate_user() {
        return update_user;
    }

    public void setUpdate_user(String update_user) {
        this.update_user = update_user;
    }

    public Date getCreate_date() {
        return create_date;
    }

    public void setCreate_date(Date create_date) {
        this.create_date = create_date;
    }

    public Date getUpdate_date() {
        return update_date;
    }

    public void setUpdate_date(Date update_date) {
        this.update_date = update_date;
    }

    public Integer getIsbel() {
        return isbel;
    }

    public void setIsbel(Integer isbel) {
        this.isbel = isbel;
    }
}

且有各个功能的实现的类:

查找:

    public List<Goddess> query() throws Exception {
        Connection conn = DBUtil.getConnection();
        // 通过数据库的连接操作数据库,实现增删改查
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT user_name,age FROM imooc_goddess");  // 将查询的数据存放在这个对象里面

        List<Goddess> gs = new ArrayList<Goddess>();
        Goddess g = null;

        // 如果对象里面有数据(rs.next返回true或false)
        while(rs.next()) {
            g = new Goddess();
            g.setUser_name(rs.getString("user_name"));
            g.setAge(rs.getInt("age"));

            gs.add(g);
        }

        return gs;
    }

    public Goddess get() {
        return null;
    }

}

添加:

public void addGoddess(Goddess g) throws SQLException {
        Connection conn = DBUtil.getConnection();
        String sql = "" + "INSERT INTO imooc_goddess" +
                     "(user_name,sex,age,birthday,email,mobile," +
                     "create_user,create_date,update_user,update_date,isdel)" +
                     "values(" +
                     "?,?,?,?,?,?,?,current_date(),?,current_date(),?)";

        // 预编译
        PreparedStatement ptmt = conn.prepareStatement(sql);

        // 传参给预编译符 "?" 去赋值
        ptmt.setString(1, g.getUser_name());
        ptmt.setInt(2, g.getSex());
        ptmt.setInt(3, g.getAge());
        ptmt.setDate(4, new Date(g.getBirthday().getTime()));
        ptmt.setString(5, g.getEmail());
        ptmt.setString(6, g.getMobile());
        ptmt.setString(7, g.getCreate_user());
        ptmt.setString(8, g.getUpdate_user());
        ptmt.setInt(9, g.getIsbel());

        ptmt.execute();
    }

current_date():获取当天日期(MYSQL语句)

删除:

public void delGoddess(Integer id) throws Exception {
        Connection conn = DBUtil.getConnection();
        String sql = "DELETE FROM" + " imooc_goddess" +
                     " WHERE" + " id = ?";

        // 预编译
        PreparedStatement ptmt = conn.prepareStatement(sql);

        // 传参给预编译符 "?" 去赋值
        ptmt.setInt(1, id);

        ptmt.execute();
    }
public Goddess get(Integer id) throws Exception {
        Connection conn = DBUtil.getConnection();
        // 通过数据库的连接操作数据库,实现增删改查
        String sql = "SELECT * FROM" + " imooc_goddess" +
                     " WHERE" + " id = ?";

        PreparedStatement ptmt = conn.prepareStatement(sql);

        ptmt.setInt(1, id);

        ResultSet rs = ptmt.executeQuery();

        Goddess g = null;

        if(rs.next()) {
            g = new Goddess();

            g.setId(rs.getInt("id"));
            g.setUser_name(rs.getString("user_name"));
            g.setAge(rs.getInt("age"));
            g.setSex(rs.getInt("sex"));
            g.setBirthday(rs.getDate("birthday"));
            g.setEmail(rs.getString("email"));
            g.setMobile(rs.getString("mobile"));
            g.setCreate_date(rs.getDate("create_date"));
            g.setCreate_user(rs.getString("create_user"));
            g.setUpdate_date(rs.getDate("update_date"));
            g.setUpdate_user(rs.getString("update_user"));
            g.setIsbel(rs.getInt("isdel"));

        }

        return g;
    }

查找的最后执行语句是:ptmt.executeQuery()

按特定语句段查询:

public List<Goddess> query(List<Map<String,Object>> params) throws Exception {
        List<Goddess> result = new ArrayList<Goddess>();

        Connection conn = DBUtil.getConnection();
        // 通过数据库的连接操作数据库,实现增删改查
        StringBuilder sb = new StringBuilder();

        sb.append("SELECT * FROM imooc_goddess WHERE 1=1 ");

        if(params!=null && params.size()>0) {
            for(Map<String,Object> mm : params) {
                sb.append(" and " + mm.get("name") + " " + mm.get("rela") + " " + mm.get("value") + " ");
            }
        }

        PreparedStatement ptmt = conn.prepareStatement(sb.toString());



        ResultSet rs = ptmt.executeQuery();

        // 如果对象里面有数据(rs.next返回true或false)
        while(rs.next()) {

            Goddess g = new Goddess();

            g.setId(rs.getInt("id"));
            g.setUser_name(rs.getString("user_name"));
            g.setAge(rs.getInt("age"));
            g.setSex(rs.getInt("sex"));
            g.setBirthday(rs.getDate("birthday"));
            g.setEmail(rs.getString("email"));
            g.setMobile(rs.getString("mobile"));
            g.setCreate_date(rs.getDate("create_date"));
            g.setCreate_user(rs.getString("create_user"));
            g.setUpdate_date(rs.getDate("update_date"));
            g.setUpdate_user(rs.getString("update_user"));
            g.setIsbel(rs.getInt("isdel"));

            result.add(g);
        }

        return result;
    }

主函数测试语句:

List<Map<String,Object>> params = new ArrayList<Map<String,Object>>();
        Map<String,Object> param = new HashMap<String, Object>();

        param.put("name", "user_name");
        param.put("rela", "=");
        param.put("value", "'小美'");

        param.put("name", "mobile");
        param.put("rela", "=");
        param.put("value", "'13915487681'");

        params.add(param);

        List<Goddess> result = g.query(params);

        for(Goddess goddess : result) {
            System.out.println(goddess);
        }

小技巧:在 WHERE 后加 1=1 ,永为真,再加 and 就可以包括第一条语句在内的所有语句了

搭建控制层:

连接视图层和模型层的桥梁(通过调用模型层的方法实现)

public class GoddessAction {

    private GoddessDao dao = new GoddessDao();

    // 添加
    public void add(Goddess goddess) throws Exception {
        dao.addGoddess(goddess);
    }

    // 更新
    public void edit(Goddess goddess) throws Exception {
        dao.updateGoddess(goddess);
    }

    // 删除
    public void del(Integer id) throws Exception {
        dao.delGoddess(id);
    }

    // 全部查找
    public List<Goddess> query() throws Exception {
        return dao.query();
    }

    // 按条件查找
    public List<Goddess> query(List<Map<String,Object>> params) throws Exception {
        return dao.query(params);
    }

    // 获得某个ID的信息
    public Goddess get(Integer id) throws Exception {
        return dao.get(id);
    }
}
搭建视图层:
public class View {
    private static final String CONTEXT="欢迎来到女神禁区:\n" +
            "下面是女神禁区的功能列表:\n" +
            "[MAIN/M]:主菜单\n" +
            "[QUERY/Q]:查看全部女神的信息\n" +
            "[GET/G]:查看某位女神的详细信息\n" +
            "[ADD/A]:添加女神信息\n" +
            "[UPDATE/U]:更新女神信息\n" +
            "[DELETE/D]:删除女神信息\n" +
            "[SEARCH/S]:查询女神信息(根据姓名、手机号来查询)\n" +
            "[EXIT/E]:退出女神禁区\n" +
            "[BREAK/B]:退出当前功能,返回主菜单" ;

    private static final String OPERATION_MAIN="MAIN";
    private static final String OPERATION_QUERY="QUERY";
    private static final String OPERATION_GET="GET";
    private static final String OPERATION_ADD="ADD";
    private static final String OPERATION_UPDATE="UPDATE";
    private static final String OPERATION_DELETE="DELETE";
    private static final String OPERATION_SEARCH="SEARCH";
    private static final String OPERATION_EXIT="EXIT";
    private static final String OPERATION_BREAK="BREAK";

    public static void main(String[] args) {
        System.out.println(CONTEXT);

        Goddess goddess = new Goddess();
        GoddessAction action = new GoddessAction();

        String prenious = null;
        Integer step = 1;

        Scanner scan = new Scanner(System.in);

        // 有输入值的时候,保持程序的一直运行
        while(scan.hasNext()) {

            String in = scan.next();

            // 如果输入的是 EXIT , 或者 E , 退出
            if(in.toUpperCase().equals(OPERATION_EXIT) || in.toUpperCase().equals(OPERATION_EXIT.substring(0, 1))) {
                System.out.println("您已成功退出女神禁区。");
                break;
            } else if (in.toUpperCase().equals(OPERATION_QUERY) || in.toUpperCase().equals(OPERATION_QUERY.substring(0, 1))) {

                try {
                    List<Goddess> list = action.query();

                    for (Goddess g : list) {
                        System.out.println(g.getId() + ",姓名:" + g.getUser_name());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else if (in.toUpperCase().equals(OPERATION_ADD) || in.toUpperCase().equals(OPERATION_ADD.substring(0, 1)) || prenious.equals(OPERATION_ADD)) {

                prenious = OPERATION_ADD;

                if(1 == step) {
                    System.out.println("请输入女神的 [姓名] ");
                } else if (2 == step) {
                    goddess.setUser_name(in);
                    System.out.println("请输入女神的 [年龄] ");
                } else if (3 == step) {
                    goddess.setAge(Integer.valueOf(in));
                    System.out.println("请输入女神的 [生日] , 格式如:yyyy-MM-dd");
                } else if (4 == step) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    Date birthday = null;
                    try {
                        birthday = sf.parse(in);
                        goddess.setBirthday(birthday);
                        System.out.println("请输入女神的 [邮箱] ");
                    } catch (ParseException e) {
                        e.printStackTrace();
                        System.out.println("您输入的格式有误,请重新输入:");
                        step = 3;
                    }
                } else if (5 == step) {
                    goddess.setEmail(in);
                    System.out.println("请输入女神的 [手机号] ");
                } else if (6 == step) {
                    goddess.setMobile(in);
                    System.out.println("新增女神成功!");
                    try {
                        action.add(goddess);
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("新增女神失败。");
                    }
                }

                if (OPERATION_ADD.equals(prenious)) {
                    step ++;
                }

            } else {
                System.out.println("您输入的值为:" + in);
            }




        }
    }
}
JDBC各种连接数据库方式的对比:
  1. JDBC + ODBC桥的方式。
    特点:需要数据库的 ODBC 驱动,仅适用于微软的系统。

  2. JDBC + 厂商API的形式。
    特点:厂商API一般使用C编写。

  3. JDBC + 厂商Database Connection
    Server + DataBase 的形式。
    特点:在 Java 与 Database 之间架起了一台专门用与数据库连接的服务器(一般由数据库厂商提供)

  4. JDBC + DataBase 的连接方式。(推荐使用)
    特点:这使得Application与数据库分开,开发者只需关心内部逻辑的实现而不需注重数据库连接的具体实现。

无参数存储过程的调用:

public static void select_nofilter() throws SQLException {

        // 1.获得连接
        Connection conn = DBUtil.getConnection();

        // 2.获得 callablestatement
        CallableStatement cs =  conn.prepareCall("CALL sp_select_nofilter");

        // 3.执行存储过程
        cs.execute();

        // 4.处理返回的结果:结果集或出参
        ResultSet rs = cs.getResultSet();

        while(rs.next()) {
            System.out.println(rs.getString("user_name") + rs.getString("email") + rs.getString("mobile"));

        }

    }
带参数的存储过程:
BEGIN
    IF sp_name IS NULL OR sp_name = "" THEN 
        SELECT * FROM imooc_goddess;
    ELSE 
    IF length(sp_name)=11 AND substring(sp_name,1,1)=1 THEN 
        SELECT * FROM imooc_goddess WHERE mobile=sp_name;
    ELSE
        SELECT * FROM imooc_goddess WHERE user_name LIKE CONCAT('%',sp_name,'%');
        END IF;
    END IF;
END

传参:IN sp_name VARCHAR(20)

如果 sp_name 为空或等于 NULL ,则查询全表。
如果长度为 11 且开头字母为 1,以手机号匹配查询。
否则,以名称匹配。
(IF-THEN连用)

public static List<Goddess> select_filter(String sp_name) throws Exception {

        // 1.获得连接
        Connection conn = DBUtil.getConnection();

        // 2.获得 callablestatement
        CallableStatement cs =  conn.prepareCall("CALL sp_select_filter(?)");

        cs.setString(1, sp_name);

        // 3.执行存储过程
        cs.execute();

        // 4.处理返回的结果:结果集或出参
        ResultSet rs = cs.getResultSet();

        Goddess g = null;
        List<Goddess> result = new ArrayList<Goddess>();

        while(rs.next()) {
            g = new Goddess();

            g.setId(rs.getInt("id"));
            g.setUser_name(rs.getString("user_name"));
            g.setAge(rs.getInt("age"));
            g.setMobile(rs.getString("mobile"));

            result.add(g);
        }

        return result;
    }
调用带输出参数的存储过程:
BEGIN
    SELECT count(*) INTO count FROM imooc_goddess;

END

将全表记录的数量(count)放入(INTO)count变量中

public static Integer select_count () throws Exception {

        Integer count = 0;

        // 1.获得连接
        Connection conn = DBUtil.getConnection();

        // 2.获得 callablestatement
        CallableStatement cs =  conn.prepareCall("CALL sp_select_count(?)");

        cs.registerOutParameter(1, Types.INTEGER); // Types JDBC封装的常用的数据类型

        // 3.执行存储过程
        cs.execute();

        count = cs.getInt(1);

        return count;
    }

CallableStatement 的 registerOutParameter 方法获得输出参数,TYPES 为JDBC常用封装类型。
不用 ResultSet 而直接用 cs.getInt(1) 获取第一个出参。

事务管理:

事务是作为单个逻辑工作单元执行的一系列操作。
这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行。

特点:
1.原子性
事务是一个完整的操作。

2.一致性
当事务完成时,数据必须处于一致状态。
(如这边减少了100,那边应该同时增加100)

3.隔离性
对数据进行修改的所有并发事务是彼此隔离的。
如:
A: z+100,x-100
B: z+100,x-100,
当A事务处理时,B等待(同一时间对数据库的操作保持一个事务的锁定)

4.永久性
事务完成后,它对数据库的修改被永久保存。

JDBC对事务管理的支持:

1.我们通过提交 commit() 或是回退 rollback() 来管理事务的操作。
(回滚:回到之前未更新删除等状态)
2.事务操作默认是自动提交。
3.可以通过调用 setAutoCommit(false) 来禁止自动提交。

无事务管理:

public String trans (Account from, Account to, Double amount) throws Exception {

        AccountDao accountDao = new AccountDao();
        TransInfoDao transInfoDao = new TransInfoDao();

        from.setAmount(from.getAmount()-amount);
        accountDao.updateAccount(from);

        String s = null;
        s.split("1");

        to.setAmount(to.getAmount()+amount);
        accountDao.updateAccount(to);

        TransInfo info = new TransInfo();

        info.setSource_account(from.getAccount());
        info.setSource_id(from.getId());
        info.setDestination_account(to.getAccount());
        info.setDestination_id(to.getId());
        info.setAmount(amount);

        transInfoDao.addTransInfo(info);



        return "sccess";

    }

中间的两行 String 和 split 会报空指针错误,如果没有事务管理,数据库自动提交将导致 a 的钱没了,但是 maket 钱也没增加(因为中间报错就停了)

有事务管理:

public String transaction (Account from, Account to, Double amount) throws Exception {

        Connection conn = DBUtil.getConnection();
        conn.setAutoCommit(false);

        try {

            AccountDao accountDao = new AccountDao();
            TransInfoDao transInfoDao = new TransInfoDao();

            from.setAmount(from.getAmount()-amount);
            accountDao.updateAccount(from);

            /*String s = null;
            s.split("1");*/

            to.setAmount(to.getAmount()+amount);
            accountDao.updateAccount(to);

            TransInfo info = new TransInfo();

            info.setSource_account(from.getAccount());
            info.setSource_id(from.getId());
            info.setDestination_account(to.getAccount());
            info.setDestination_id(to.getId());
            info.setAmount(amount);

            transInfoDao.addTransInfo(info);

            conn.commit();

            return "success";

        } catch (Exception e) {

            conn.rollback();

            e.printStackTrace();

            return "fail";

        }

    }

获取连接,加了 conn.setAutoCommit(false) 将自动提交关闭。
用 try-catch 去捕获可能出现的错误,如果出错,就调用 conn.rollback() 回滚。
如果没错,再用 conn.commit() 提交。

数据库连接池:

常用的开源的连接池:
1.dbcp
2.c3p0

dbcp:
1.导入相关jar包
commons-dbcp2-2.1.1.jar
commons-pool2-2.4.2.jar
commons-logging-1.2.jar

2.在项目根目录增加配置文件
dbcp.properties

可以手动将所有东西写进去:

也可以直接引入配置文件:

public class DBCPUtil {

    private static DataSource DS;

    private static final String configFile = "/dbcp.properties";

    public DBCPUtil () {

        initDbcp();

    }

    private static void initDbcp () {

        Properties pops = new Properties();

        try {
            pops.load(Object.class.getResourceAsStream(configFile));
            DS = BasicDataSourceFactory.createDataSource(pops);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public Connection getConn () {

        Connection con = null;

        if (DS != null) {

            try {
                con = DS.getConnection();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                con.setAutoCommit(false);
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }

        return con;

    }
}

两个变量: DataSource DS 和 String configFile=”/dbcp.properties”
在构造方法中调用初始化 initDbcp()
初始化方法中声明配置变量 Properties pops,加载配置文件 pops.load(Object.class.getResourceAsStream(configFile))
用 DS 接收 DS = BasicDataSourceFactory.createDataSource(pops)

获得连接方法:
如果 DS 非空
con = DS.getConnection();
设置不自动提交
com.setAutoCommit(false);

return con

配置文件:

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc\:mysql\://127.0.0.1\:3306/imooc_db?useUnicode\=true&amp;characterEncoding=UTF-8
username=root
password=root

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=30

#<!-- 最大空闲连接 -->
maxIdle=10

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=1000
initialSize=5
minIdle=1

removeAbandoned=true

removeAbandonedTimeout=180

在Dao层用DBCP方式获取连接:

DBCPUtil db = new DBCPUtil();
Connection conn = db.getConn();

C3P0:
C3P0是一个开源的JDBC的连接池,它实现了数据源和JNDI绑定,支持JDBC和JDBC2的标准扩展。

1.导入相关jar包
c3p0-0.9.2-pre4.jar
mchange-commons-java-0.2.2.jar

2.在项目根目录增加配置文件
c3p0.properties

3.编写类文件,创建连接池

配置文件:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:\:mysql\://127.0.0.1\:3306/imooc_db?useUnicode\=true&amp;characterEncoding=UTF-8
c3p0.user=root
c3p0.password=root

工程文件:

public class C3P0Util {

    private static ComboPooledDataSource ds = new ComboPooledDataSource();

    public static Connection getConnection () {

        try {

            return ds.getConnection();

        } catch (SQLException e) {

            throw new RuntimeException(e);

        }

    }

}
c3p0和dbcp的不同点:

JDBC升级替代品—Commons-dbutils:

Apache 组织提供的一个开源JDBC工具类库,对传统操作数据库的类进行二次封装,可以把结果集转化成List

特点:
1.杜绝资源泄露。修正JDBC代码并不困难,但是这通常导致连接泄露并且难以跟踪到。

2.大段的持久化数据到数据库代码彻底精简,剩下的代码清晰地表达了编码的意图。

3.不需要手工从ResultSet里set值到JavaBean中,每一行数据都将会以一个Bean实例的形式出现。

核心接口:
1.DbUtils
提供如关闭连接、装载JDBC驱动程序等常规工作的工具类

2.QueryRunner
该类简单化了SQL查询,它常与ResultSetHandler组合在一起使用

3.ResultSetHandler
执行处理一个java.sql.ResultSet,将数据转变并处理为任何一种形式,这样有益于其应用而且使用起来更容易

示例:

Hibernate:

一种Java语言下的对象关系映射解决方案。它是一种自由、开源的软件。

优点:
1.轻量级的ORM框架
2.对JDBC进行了很好的封装,使用了ORM做了映射,那么就可以通过面向对象的方式很容易的操作数据库了
3.它还提供了缓存机制,可以提高效率

缺点:
如果对大量数据进行频繁的操作,性能效率比较低,不如直接使用JDBC

核心接口:

myBatis:

MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

特点:
1.易于上手和掌握
2.sql写在xml里,便于统一管理和优化
3.解除sql与程序代码的耦合
4.提供映射标签,支持对象与数据库的orm字段关系映射
5.提供对象关系映射标签,支持对象关系组建维护
6.提供xml标签,支持编写动态sql

JDBC理解:

1.Class.forName()将对应的驱动类加载到内存中,然后执行内存中的static静态代码段,代码段中,会创建一个驱动Driver的实例,放入DriverManager中,供DriverManager使用。

2.DriverManager:管理Driver驱动
DriverManger可以注册和删除加载的驱动程序
可以根据给定的url获取符合url协议的驱动Driver或者是建立Conenction连接,进行数据库交互。

3.java.sql.Driver接口规定了厂商实现该接口,并且定义自己的URL协议。厂商们实现的Driver接口通过acceptsURL(String url)来判断此url是否符合自己的协议,如果符合自己的协议,则可以使用本驱动进行数据库连接操作,查询驱动程序是否认为它可以打开到给定 URL 的连接。

一定要在第一次使用DriverManager之前设置jdbc.drivers,因为DriverManager中的static静态代码段只会被执行一次!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值