java应用操作数据库(循序渐进)

267 阅读1分钟

1、jdbc实现数据库操作

完整简单demo

首先添加依赖,这里使用maven

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    //根据自己数据库服务版本选择驱动版本 我这里使用8.0.25
    <version>${mysql.version}</version>
</dependency>

简单使用

public class SimpleJdbc {

    public static void main(String[] args) {
        //加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            //获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=true",
                    "root", "root123");
            String sql = " select * from t_user tu where name = '张三'";
            //执行sql
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            //获取结果
            while (resultSet.next()) {
                String name = resultSet.getString("name");
                Integer age = resultSet.getInt("age");
                //打印输出结果集
                System.out.println("name:" + name + " age:" + age);  
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

注册驱动

private static void loadDriver(String driverName) {
        //第一种方式:类加载(常用)
//        try {
//            Class.forName(driverName);
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
        //第二种方式:利用Driver对象
        try {
            Driver driver = new com.mysql.cj.jdbc.Driver();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //第三种方式:利用系统参数  需在idea中配置program arguments为下面的参数
        //-Djdbc.drivers = com.mysql.cj.jdbc.Driver
    }

获取连接

private static Connection getConn(String url, String user, String pwd) {
    try {
        return DriverManager.getConnection(url, user, pwd);
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

执行sql操作

方法1

String sql1 = " select * from t_user tu where name = '张三'";
statement = connect.createStatement();
resultSet = statement.executeQuery(sql1);

方法2

 //第二种方式:PreStatement
String sql2 = " select * from t_user tu where name = ?";
PreparedStatement preState2 = connect.prepareCall(sql2);
preState2.setString(1, "张三");
ResultSet resultSet = preState2.executeQuery();

获取结果

while (resultSet.next()) {
    String name = resultSet.getString("name");
    Integer age = resultSet.getInt("age");
    //打印输出结果集
    System.out.println("name:" + name + " age:" + age);      
}

关闭连接

private static void close(Connection connect,
                          Statement statement,
                          ResultSet resultSet) {
    try {
        if (resultSet != null) resultSet.close();
        if (statement != null) statement.close();
        if (connect != null) connect.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

2、jdbc相关知识点

常见驱动

Oraclejdbc:oracle:thin:@localhost:1521:user_test
SqlServerjdbc:microsoft:sqlserver://localhost:1433; DatabaseName=user_test
MySql:jdbc:mysql://localhost:3306/user_test

Statement、PreparedStatement比较

1、Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。

2、PreperedStatement防止sql注入 PreparedStatement操作:

String sql1 = " select * from t_user tu where name = ?";
statement = connect.prepareStatement(sql1);
statement.setString(1,"张三");
resultSet = statement.executeQuery();

mysql支持存储图片视频

数据库字段类型image,图片视频需要转成二进制存储

不建议使用,最好有文件系统存储,数据库存放url

事务

一般事务 image.png

事务回滚点 image.png

事务隔离级别 image.png

todo 详细事务相关待整理一篇

3、数据库连接池

单纯的jdbc操作 image.png 比如我们有1000个用户,每个用户请求10次,每次请求平均两个数据库操作,我们就需要连接关闭数据库1000102次。大量的消耗数据库资源

数据库连接池 image.png 比如我们数据库连接池配置5个连接(最大也5个),上面的1000个用户的请求就可以在这五个连接里面完成,每次处理完成,连接不关闭,又返回连接池,等待下一个请求。大量的节省资源。同时我们也专注于自己的业务处理,不需要cp大量冗余代码。

dbcp连接池

先上手试试

引入依赖

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    //同样这里使用的版本根据自己实际情况确定
    <version>1.4</version>
</dependency>

image.png

image.png

配置

参考配置

#######DBCP配置文件##########
#驱动名
driverClassName=com.mysql.cj.jdbc.Driver
#url
url=jdbc:mysql://mac.zjf:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=true
#用户名
username=root
#密码
password=zhang1019
#初试连接数
initialSize=30
#最大活跃数
maxTotal=30
#最大idle数
maxIdle=10
#最小idle数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=1000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1

具体配置及意义参考类BasicDataSourceFactory.createDataSource(Properties properties) 这里简单列举几个

image.png

image.png 不同版本的dbcp连接池配置有一些差异,具体参考自己使用的版本

dbcp数据连接池工作原理讲解

c3p0连接池

引入依赖

<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>

跟dbcp类似 image.png

hikariCP连接池

引入依赖

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>4.0.3</version>
</dependency>

HikariCP以其优秀的性能,spring boot2.0开始已经是其默认的数据库连接池 image.png

阿里druid

druid除了数据库连接池外,还兼具了很多其他功能,比如自己的sql parser,监控等 现在国内使用的主流数据库连接池 后续结合spring一块

4、mybatis

数据库连接池接管了数据库连接,释放等问题,剩下的就是创建statement 执行sql,获取结果这部分操作了,但是这部分操作还是有点繁琐,有没有什么技术框架简化这部分操作,持久层框架就诞生了。 持久层框架主要包括hibernate、mybatis 等。国内mybatis占主流。

先上手

引入依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.4</version>
</dependency>

image.png

  1. 添加配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 配置参考 https://mybatis.org/mybatis-3/zh/configuration.html-->
<configuration>
    <!-- 使用-->
    <properties resource="mybatis-jdbc.properties"/>

    <settings>
        <setting name="jdbcTypeForNull" value="VARCHAR"/>
    </settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

上面引用的mybatis-jdbc.properties配置

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://mac.zjf:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=true
username=root
password=zhang1019

上面引用的UserMapper.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.soft1010.db.mybatis.mapper.UserMapper">

    <select id="queryUserById" resultType="top.soft1010.db.mybatis.po.User">
        select id,name,age from t_user
        where id = #{id,jdbcType=INTEGER}
    </select>

</mapper>
  1. 实例化SqlSessionFactory SqlSessionFactoryBuilder加载配置文件,创建SqlSessionFactory实例 ,SqlSessionFactory能创建sqlSession实例,SqlSessionFactory最好单例,应用只创建一个。

  2. SqlSession对象 SqlSessionFactory 有多个方法获取sqlsession对象,每个线程一个sqlsession对象。

  3. 接口通过动态代理获得接口实例

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

5、调用方法

User user = userMapper.queryUserById(1);

6.原理核心 动态代理

源码

部分使用的源码

--------------------------end-------------------------

对你有帮助的话,记得点个赞👍

  • [六十七点五 ]

--------------------------end-------------------------