数据库连接(1)-从JDBC到MyBatis

摘要

因为有持久层框架,和Spring的存在,越来越多的人对数据库连接这块不甚了解,只知使用方便,不知其原理。所以写一个数据库连接的系列文章,总结下本人在数据库连接方面遇到的问题,和对数据库连接的理解。

JDBC

jdbc:Java DataBase Connectivity,Java 数据库连接,一套标准的Java API,用来执行SQL语句。这套命名应该是很老了,毕竟将Data Base直接映射成了关系型数据库,或者说,像我之前在介绍NoSQL数据库时多次提到的,NoSQL数据库还没有一套统一的访问标准语句。

jdbc的作用就是将SQL变成了Java API 访问。

        Connection conn = null;
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/test?"
                + "user=root&password=123456&useUnicode=true&characterEncoding=UTF8";
        conn = DriverManager.getConnection(url);
        Statement stmt = conn.createStatement();
        String sql = "select *from post where user_id=1";
        ResultSet resultSet = stmt.executeQuery(sql);
        List<Post> posts = new ArrayList<>();
        while (resultSet.next()) {
            Post post = new Post();
            post.setId(resultSet.getLong("id"));
            post.setTitle(resultSet.getString("title"));
            post.setContents(resultSet.getString("contents"));
            posts.add(post);
        }
        stmt.close();
        conn.close();

其中Connection,DriverManager,Statement这些类都是jdk提供的,不依赖其他的jar。jdk提供了一套通用的SQL访问API,但是各个数据库并不相同,有各自的标准,所以各个针对MySQL,Oracle提供了不同的驱动。比如MySQL的驱动。

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>

执行Class.forName("com.mysql.jdbc.Driver");加载MySQL驱动

DriverManager.registerDriver(new Driver());

这段代码中包含了所有的基本的数据库操作对象
JDBC 四大对象: DataSource , Connection, Statement,ResultSet

  1. 连接url
  2. 连接: 数据库Server通信与服务的通信
  3. statement:把 SQL 语句发送到 DBMS
  4. ResultSet : 数据库操作返回结果

后续的其他扩展,都是基于以上各个部分的扩展

获取connection,构建statement,执行时Java操作数据库最基本的操作,以后的所有扩展都围绕这个。
从上面的代码中我们可以看到这只是一个hello world,在实际开发中,有很多的数据库操作,如果每个都写一个,那重复代码太多了

Spring-Template--解决重复代码

将1的url封装成了一个DataSource对象

@Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource("jdbc:mysql://localhost:3306/test?"
                + "user=root&password=123456&useUnicode=true&characterEncoding=UTF8");
    }
    @Bean
    public JdbcTemplate jdbcTemplate() {
        return  new JdbcTemplate(dataSource());
    }

将3 Statement重复代码解决了

@Service
public class JdbcTemplateService {
    @Autowired
    private JdbcTemplate mJdbcTemplate;

    public void queryById(long userId) {
        String sql = "select * from post where user_id = " + userId;
        List<Post> result =mJdbcTemplate.query(sql, new PostRowMapper());
    }

    class PostRowMapper implements RowMapper<Post> {
        public Post mapRow(ResultSet rs, int rowNum) throws SQLException {
            Post post = new Post();
            post.setId(rs.getLong("id"));
            post.setTitle(rs.getString("title"));
            post.setContents(rs.getString("contents"));
            return post;
        }

    }
}

解决了连接获取,查询重复语句的问题,
但是没有解决对象映射的问题,需要为每个数据库对象生成独自的Mapper

那么JdbcTemplate是如何做到的呢,因为statemnt的前提是需要一个连接,然后执行。
所以对于Spring框架而言,它当前没有connection对象,所以它需要一个回调来执行。

public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
        Assert.notNull(sql, "SQL must not be null");
        Assert.notNull(rse, "ResultSetExtractor must not be null");
        if (logger.isDebugEnabled()) {
            logger.debug("Executing SQL query [" + sql + "]");
        }

        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            @Override
            @Nullable
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
                try {
                    rs = stmt.executeQuery(sql);
                    return rse.extractData(rs);
                }
                finally {
                    JdbcUtils.closeResultSet(rs);
                }
            }
            @Override
            public String getSql() {
                return sql;
            }
        }

        return execute(new QueryStatementCallback());
    }

对外暴露JdbcTemplate,
内部实现是通过回调方法来实现Statement的执行

连接池

Template只是解决了重复代码的问题,并没有解决连接的资源消耗问题,所以需要连接池,通过一个容器储存连接,然后复用已有的连接,来实现节约资源的目的

一些开源的数据库连接池

  • DBCP
    Apache 下面的,实现了基本的数据库连接池功能,没有自动回收空闲连接的功能
  • C3P0
    实现了数据源与JNDI的绑定,目前使用它的开源项目有Hibernate,
  • Druid
    阿里的开源数据库连接池,分库分表数据库中间件TDDL就是用的这个

数据库连接池是一个老生常谈的话题,不做过多的介绍,在下面的mybatis框架中讲它的实现

持久层框架-mybatis

虽然有了JdbcTemplate,但是还缺乏一些操作,比如对象映射,查询数据的时候希望自动映射到对象上,
另外需要自动生成SQL语句,不需要进行SQL的拼接,赋值。

mybatis的介绍

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

重点在于避免了所有的JDBC代码,和手动设置参数以及获取结果集


对外暴露:SqlSession
在jdbc中是没有session这个概念,只有connection.session即会话,mybatis与数据库的一次交互

内部实现:Executor,StatmentHandler 替换Statement,ResultHander替换resultset,另外多了一个ParameterHandler来处理参数

构建一个SqlSessionFactory

    @Bean
    public SqlSessionFactory sqlSessionFactory() {
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource());
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session
                .Configuration(environment);
        configuration.addMapper(PostMapper.class);
        return new SqlSessionFactoryBuilder().build(configuration);
    }

获取session然后执行

 @Autowired
    private SqlSessionFactory sqlSessionFactory;
    public void queryByUserId(long userId) {
        SqlSession session = sqlSessionFactory.openSession();
        PostMapper postMapper = session.getMapper(PostMapper.class);
        Post post = postMapper.findPostByUserId(userId);
    }
}

spring-mybatis

spring-mybatis 的作用就是让你不知道mybatis
Spring 将会加载必要的 MyBatis 工厂类和 session 类。由spring来接管数据库连接的创建。
并且提供一个简单的方式来注入 MyBatis 数据映射器和 SqlSession 到业务层的 bean 中

所有代码

https://github.com/FS1360472174/javaweb/tree/master/db-connection/mysql-jdbc

mybatis 与hibernate一些区别,下期再讲

关注【方丈的寺院】,与方丈一起开始技术修行之路
喜欢这篇文章的话,点个赞呗

参考

http://www.cnblogs.com/JavaSubin/p/5294721.html
http://www.mybatis.org/mybatis-3/zh/index.html
http://www.mybatis.org/spring/zh/index.html
http://blog.csdn.net/u014723529/article/details/41288333
https://github.com/spring-projects/spring-framework/blob/master/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java

原文地址:https://www.cnblogs.com/stoneFang/p/10743825.html

时间: 2024-10-12 00:38:54

数据库连接(1)-从JDBC到MyBatis的相关文章

原理分析之一:从JDBC到Mybatis

原理分析之一:从JDBC到Mybatis Mybatis学习(一)原生态的JDBC编程总结 -----系列 深入浅出MyBatis-快速入门

jdbc ,jdbcTemplate,MyBatis,Hibernate比较与分析

JDBC 1:jdbc(Java Data Base Connection 数据库连接)是一种用于执行sql语句的API,其中使用jdbc连接时需要的,Connection,Statement,ResultSet都是接口: 2:主要用于对数据库要求是快速的:因为jdbc相对比是原生态的,所以速度会比较快,但是需要写一大堆代码. JDBCTemplate 针对数据查询提供了多个重载的模板方法,可以根据需要选用不同的模板方法,如果查询很简单,仅仅是传入相应的SQL或者相关参数,然后取得一个单一的结果

【Mybatis3学习入门】【一】从JDBC到Mybatis

转自:  http://chenjc-it.iteye.com/blog/1455688 1.引言 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架.再而论述Mybatis作为一个数据持久层框架本身有待改进之处. 2.JDBC实现查询分析 我们先看看我们最熟悉也是最基础的通过JDBC查询数据库数据,一般需要以下七个步骤: (1)  加载JDBC驱动 (2)  建立并获取数据库连接 (3)  创建 JDBC Statemen

从JDBC到Mybatis

http://chenjc-it.iteye.com/blog/1455688 1.引言 本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架.再而论述Mybatis作为一个数据持久层框架本身有待改进之处. 2.JDBC实现查询分析 我们先看看我们最熟悉也是最基础的通过JDBC查询数据库数据,一般需要以下七个步骤: (1)  加载JDBC驱动 (2)  建立并获取数据库连接 (3)  创建 JDBC Statements 对象

深入浅出MyBatis:JDBC和MyBatis介绍

最近在休陪产假,时间比较零碎,准备看2本书充实下,一本是「深入浅出MyBatis:技术原理与实践」,一本是「RabbitMQ实战:高效部署分布式消息队列」,为了加深记忆和理解,会进行整理.扩展和记录. 看书的目标不是把所有的细节都记住,而是从整体上了解一个技术能做什么,包含的特性.基本模块,实现原理和常见使用场景. 本篇分享MyBatis书籍的第一篇,首先回忆下JDBC的相关概念,了解Java提供的访问数据库最基本的方式,然后介绍下MyBatis的基本特性和核心组件,最后说下书的整体结构,了解后

jdbc,mybatis,hibernate各自有优缺点以及区别

JDBC: 我们平时使用jdbc进行编程,大致需要下面几个步骤: 1,使用jdbc编程需要连接数据库,注册驱动和数据库信息 2,操作Connection,打开Statement对象 3,通过Statement对象执行SQL,返回结果到ResultSet对象 4,使用ResultSet读取数据,然后通过代码转化为具体的POJO对象 5,关闭数据库相关的资源 jdbc的缺点: 一:工作量比较大,需要连接,然后处理jdbc底层事务,处理数据类型,还需要操作Connection,Statement对象和

springboot配置数据库连接池druid、整合mybatis、整合pagehelper

springboot配置数据库连接池druid druid所需pom依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>o

JDBC 和 Mybatis连接mysql数据库的时候,设置字符集编码

jdbc连接MySQL数据库的时候,设置字符集编码!!! 可以如下配置,mysql可直接在url后面加上字符集设置: String url = "jdbc:mysql://localhost:3306/exceltest1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"; Mybatis连接mysql数据库的时候,设置字符集编码!!! 可以如下配置,Mybatis的配

JSDI——实现数据库连接池(JDBC改进)

一.将驱动jar包放到服务器(例如tomcat)目录下的lib包中,让服务器自动管理数据库连接 二.在项目根中的META-INF文件夹中,建立context.xml文件,其中需要配置数据源 1 <?xml version="1.0" encoding="UTF-8"?> 2 <Context> 3 <Resource name="jdbc/oracle" 4 auth="Container" 5