实战JDBC连接Mysql数据库

本文注意讲了如何使用JDBC连接数据库以及SQl注入等问题。
————————————————————————————

  1. 什么是JDBC
    全称 Java DataBase Connectivity, 是Java语⾔中⽤来规范客户端程序如何来访问数据库的应⽤程序接⼝提供了⼀种接⼝基准,可以构建更⾼级的⼯具和接⼝,使数据库开发⼈员能够编写数据库应⽤程序应⽤程序代码⼀般不能直接访问数据库,需要通过相应的数据库驱动程序才⾏.

  2. 什么是数据库驱动?
    通俗来说就是数据库⼚商的JDBC接⼝实现
    在这里插入图片描述

  3. JDBC连接MySQL相关概念
    数据库驱动:不同数据库开发商(⽐如oracle mysql等)为了某⼀种开发语⾔能够实现统⼀的数据库调⽤⽽开发的⼀个程序, 作⽤相当于⼀个翻译⼈员, 将某个语⾔(⽐如java)中对数据库的调⽤通过这个翻译成各个种类的数据库 ⾃⼰的数据库语⾔
    Connection连接:特定数据库的连接(会话),在连接上下⽂中执⾏sql语句并返回结果
    Statement 语句: 创建执⾏SQL语句的statement, 有好⼏种实现类,⽤于执⾏对应的sql
    ResultSet结果集:SQL查询返回的结果信息
    使⽤Java连接Mysql的步骤

    1.加载JDBC驱动程序
    2.建⽴数据库连接Connection
    3.创建执⾏SQL的语句Statement
    4.处理执⾏结果ResultSet
    5.释放连接资源

  4. 准备数据库表相关的
    基础环境:

    ⾃⼰搭建好Mysql数据库,推荐是Mysql5.7版本
    注意 如果连接不上数据库
    检查防⽕墙-云服务器的⽹络安全组
    mysql有没开启允许远程连接
    

Mysql驱动jar包导⼊
mysql数据库表建⽴

CREATE TABLE `user` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `phone` varchar(32) DEFAULT NULL,
 `pwd` varchar(128) DEFAULT NULL,
 `sex` int(2) DEFAULT NULL,
 `img` varchar(128) DEFAULT NULL,
 `create_time` datetime DEFAULT NULL,
 `role` int(11) DEFAULT NULL COMMENT '1是普通⽤户,2是管理员',
 `username` varchar(128) DEFAULT NULL,
 `wechat` varchar(128) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `user` (`id`, `phone`, `pwd`, `sex`, `img`, `create_time`, `role`,
`username`,`wechat`)
VALUES
 (1,'123','666',1,'ch','2021-09-09 00:00:00',1,'jack','class6'),
 (2,'2323432','794666918',1,'wwwww','2020-05-20 04:54:01',1,'ch1','anna'),
 (3,'2323432','lw',1,'wwwww','2020-05-20 04:54:42',1,'ch','class1'),
 (4,'2323432','3232323',1,'wwwww','2020-05-20 04:55:07',1,'⽼ 王','lw');

用idea创建一个web项目,导入Mysql驱动jar包,下载后点击File->projectStructes
进入下图
在这里插入图片描述点击apply,即可。
然后在项目中,编写如下程序:

class JDBCTest {
    public static void main(String [] args) throws Exception{
        //加载JDBC驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //建⽴数据库连接Connection
        String username = "root";
        String password = "123456";
        //协议:⼦协议://ip:端⼝/数据库名称?参数1=值1&参数2=值2
        String url = "jdbc:mysql://127.0.0.1:3306/db11?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        Connection connection =
                DriverManager.getConnection(url,username,password);
        //创建执⾏SQL的语句Statement
        Statement statement = connection.createStatement();
        //处理执⾏结果ResultSet
        ResultSet resultSet = statement.executeQuery("select * from user");
        while (resultSet.next()){
            System.out.println("⽤户名称 name="+
                    resultSet.getString("username") + " 联系⽅式 wechat="+
                    resultSet.getString("wechat"));
        }
        //释放连接资源
        resultSet.close();
        statement.close();
        connection.close();
    }

目前项目结构如图:
在这里插入图片描述运行出现以下内容:
在这里插入图片描述准备工作完毕。

  1. SQL注⼊攻击Statement预编译语句
    什么是SQL注⼊攻击
    可以执⾏恶意SQL语句,将任意SQL代码插⼊数据库查询,使⽤SQL注⼊来添加,修改和删除数据库中的记录
    PrepareStatement
    字⾯可译为预声明,内部包含⼀个预编译的sql语句,参数采⽤占位符 ? 进形填充
    为啥可以防注⼊

     第⼀次操作数据库之前,SQL语句已经被数据库分析和编译,
     对应的执 ⾏计划也会缓存下来,之后数据库就会以参数化的形式进⾏查询
    传⼊的值始终都是会作为⼀个值,⽽不是sql指令
     好处:维护性好、提⾼sql效率、增加安全性
    

sql注入代码:

 private static void inject() throws Exception{
        //加载JDBC驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //建⽴数据库连接Connection
        String username = "root";
        String password = "123456";
        //协议:⼦协议://ip:端⼝/数据库名称?参数1=值1&参数2=值2
        String url = "jdbc:mysql://127.0.0.1:3306/db11?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        Connection connection = DriverManager.getConnection(url, username, password);
        //创建执⾏SQL的语句Statement
        Statement statement = connection.createStatement();
        //处理执⾏结果ResultSet
        String name = "jack";
        String pwd = "666' or 1=1 or'";

        String sql = "select * from user where username ='" + name +"'and pwd ='"+pwd+"'";
        System.out.println(sql);
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
            System.out.println("⽤户名称 name=" +
                    resultSet.getString("username") + " 联系⽅式 wechat=" +
                    resultSet.getString("wechat"));
        }
        //释放连接资源
        resultSet.close();
        statement.close();
        connection.close();
    }

执行后结果如下图:
在这里插入图片描述解决代码:

 private static void solveInject() throws Exception{
        //加载JDBC驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //建⽴数据库连接Connection
        String username = "root";
        String password = "123456";
        //协议:⼦协议://ip:端⼝/数据库名称?参数1=值1&参数2=值2
        String url = "jdbc:mysql://127.0.0.1:3306/db11?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        Connection connection = DriverManager.getConnection(url, username, password);
        //创建执⾏SQL的语句Statement
        PreparedStatement preparedStatement = connection.prepareStatement("select * from user where username = ? and pwd = ?");
        //处理执⾏结果ResultSet

        String name = "jack";
        String pwd = "666 ' or 1=1 or '";
        preparedStatement.setString(1,name);
        preparedStatement.setString(2,pwd);

        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.println("⽤户名称 name=" +
                    resultSet.getString("username") + " 联系⽅式 wechat=" +
                    resultSet.getString("wechat"));
        }
        //释放连接资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

运行结果:
在这里插入图片描述

新增一条记录代码

private static void insert() throws Exception {
        //加载JDBC驱动程序
        Class.forName("com.mysql.cj.jdbc.Driver");
        //建⽴数据库连接Connection
        String username = "root";
        String password = "123456";
        //协议:⼦协议://ip:端⼝/数据库名称?参数1=值1&参数2=值2
        String url = "jdbc:mysql://127.0.0.1:3306/db11?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        Connection connection = DriverManager.getConnection(url, username, password);
        //创建执⾏SQL的语句Statement
     PreparedStatement preparedStatement =  connection.prepareStatement("insert into user (username,pwd) values (?,?)");
        preparedStatement.setString(1,"陈浩");
        preparedStatement.setString(2,"111");
       preparedStatement.execute();
        //释放连接资源

        preparedStatement.close();
        connection.close();
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ShardingSphere是一款开源的分布式数据库中间件,它的前身是ShardingJDBC。ShardingSphere提供了分库分表、读写分离、分布式事务等功能,支持的数据库包括MySQL、Oracle、SQL Server等。 下面将介绍ShardingSphere的分库分表实战: 1. 引入依赖 在pom.xml文件中引入ShardingSphere的相关依赖: ``` <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>5.0.0-alpha</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>5.0.0-alpha</version> </dependency> ``` 2. 配置数据源和分片规则 在application.yml文件中配置数据源和分片规则: ``` spring: datasource: name: ds type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root sharding: tables: user: actualDataNodes: ds.user${0..1} tableStrategy: inline: shardingColumn: id algorithmExpression: user${id % 2} keyGenerateStrategy: column: id keyGeneratorName: snowflake order: actualDataNodes: ds.order${0..1} tableStrategy: inline: shardingColumn: id algorithmExpression: order${id % 2} keyGenerateStrategy: column: id keyGeneratorName: snowflake default-key-generator: type: SNOWFLAKE column: id ``` 上述配置中,我们定义了两个表user和order,分别分成两个库,每个库有两张表,使用id字段来进行分片。其中,key-generator用于生成分布式唯一ID,这里使用的是snowflake算法。 3. 配置数据源和事务管理器 在SpringBoot的启动类中配置数据源和事务管理器: ``` @SpringBootApplication @MapperScan("com.example.mapper") @EnableTransactionManagement @Import(ShardingDataSourceAutoConfiguration.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public DataSource dataSource() throws SQLException { return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), createShardingRuleConfiguration(), new Properties()); } private Map<String, DataSource> createDataSourceMap() { Map<String, DataSource> dataSourceMap = new HashMap<>(); DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false"); dataSource.setUsername("root"); dataSource.setPassword("root"); dataSourceMap.put("ds", dataSource); return dataSourceMap; } private ShardingRuleConfiguration createShardingRuleConfiguration() { ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); shardingRuleConfig.getTableRuleConfigs().add(getUserTableRuleConfiguration()); shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration()); return shardingRuleConfig; } private TableRuleConfiguration getUserTableRuleConfiguration() { TableRuleConfiguration result = new TableRuleConfiguration("user", "ds.user${0..1}"); result.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "user${id % 2}")); result.setKeyGenerateStrategyConfig(new KeyGenerateStrategyConfiguration("id", "snowflake")); return result; } private TableRuleConfiguration getOrderTableRuleConfiguration() { TableRuleConfiguration result = new TableRuleConfiguration("order", "ds.order${0..1}"); result.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "order${id % 2}")); result.setKeyGenerateStrategyConfig(new KeyGenerateStrategyConfiguration("id", "snowflake")); return result; } @Bean public PlatformTransactionManager txManager(final DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } ``` 4. 编写业务代码 在业务代码中,我们可以使用分片后的数据源来进行CRUD操作,例如: ``` @Service @Transactional public class UserService { @Autowired private UserMapper userMapper; public Long insert(User user) { userMapper.insert(user); return user.getId(); } public void delete(Long id) { userMapper.deleteByPrimaryKey(id); } public User select(Long id) { return userMapper.selectByPrimaryKey(id); } public void update(User user) { userMapper.updateByPrimaryKey(user); } } ``` 在这个例子中,我们使用了@Transactional注解来开启事务,使用了UserMapper来进行CRUD操作。 以上就是ShardingSphere分库分表的实战介绍。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工藤学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值