【手把手】JavaWeb 入门级项目实战 -- 文章发布系统 (第五节)

InputStream inputStream = TestProperties.class.getClassLoader().getResourceAsStream(“jdbc.properties”);

这行代码就相当于插了一根吸管在 jdbc.properties 文件上面,准备抽取里面的信息。

p.load(inputStream);

这行代码表示将吸管和 Properties 对象接通。

额,如果实在没有Java IO的基础,就暂时这么想象一下吧。。。

System.out.println§;

输出:

{db.password=, db.dataBaseName=article, db.username=root}

分开来打印:

System.out.println(p.getProperty(“db.username”));

System.out.println(p.getProperty(“db.password”));

System.out.println(p.getProperty(“db.dataBaseName”));

输出:

root

article

(因为密码为空,所以没显示出来)

这样的话,加载资源文件也没有问题了。

06 开始封装自己的DataBaseUtils

DataBaseUtils的意思就是数据库工具类,你可以把这个看成是一个自己的小框架。

Paste_Image.png

我们已经知道要访问数据库的话,需要有username,password,还有dataBaseName。所以,这三个数据就作为工具类的属性吧。

private static String username; //用户名

private static String password; //密码

private static String dataBaseName; //数据库名

接下来,专门定义一个方法来加载properties。

/**

  • 配置数据库的基本信息

  • @return void

*/

public static void config(String path){

InputStream inputStream = DataBaseUtils.class.getClassLoader().getResourceAsStream(path);

Properties p = new Properties();

try {

p.load(inputStream);

username = p.getProperty(“db.username”);

password = p.getProperty(“db.password”);

dataBaseName = p.getProperty(“db.dataBaseName”);

} catch (IOException e) {

e.printStackTrace();

}

}

一旦调用了这个方法,那么就会给私有属性赋值。

为了方便起见,我们让DataBaseUtils类被加载的时候就自动配置 jdbc.properties,比较容易想到的一个方法就是定义一个static块,然后在里面调用一下 config 方法:

static {

config(“jdbc.properties”);

}

这样一来,只要你调用了这个DataBaseUtils中的方法,就会自动配置连接信息了。

获取连接的方法:

/**

  • 获取数据库链接

  • @return Connection

*/

public static Connection getConnection(){

Connection connection = null;

try {

Class.forName(“com.mysql.jdbc.Driver”);

connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/”+dataBaseName+“?useUnicode=true&characterEncoding=utf8”,username,password);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

return connection;

}

测试:

DataBaseUtils.config(“jdbc.properties”);

Connection conn = DataBaseUtils.getConnection();

System.out.println(conn);

结果:

com.mysql.jdbc.Connection@661532

这就说明成功获取连接了。

关闭连接和其他资源的方法

/**

  • 关闭资源

  • @param connection

  • @param statement

  • @param rs

*/

public static void closeConnection(Connection connection,PreparedStatement statement,ResultSet rs){

try {

if(rs!=null)rs.close();

if(statement!=null)statement.close();

if(connection!=null)connection.close();

} catch (Exception e) {

e.fillInStackTrace();

}

}

07 DML操作的实现

DML表示—数据操纵语言,也就是SELECT,DELETE,UPDATE,INSERT。

现在我们开始封装DML的操作。

上代码:

/**

  • DML操作

  • @param sql

  • @param objects

*/

public static void update(String sql,Object…objects){

Connection connection = getConnection();

PreparedStatement statement = null;

try {

statement = (PreparedStatement) connection.prepareStatement(sql);

for (int i = 0; i < objects.length; i++) {

statement.setObject(i+1, objects[i]);

}

statement.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

}finally{

closeConnection(connection, statement, null);

}

}

Object…objects是变长参数,你可以把它理解成一个Object数组。

测试:

String id = UUID.randomUUID() + “”;

String createTime = new SimpleDateFormat(“yyyy-MM-dd”).format(new Date());

update("INSERT INTO t_user(id,username,password,sex,create_time,is_delete,address,telephone) "

  • “VALUES (?, ?, ?, ?, ?, ?, ?, ?)”, id,“张三”,123456,0,createTime,0,“保密”,“保密”);

运行结果:

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column ‘id’ at row 1

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2983)

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)

at com.mysql.jdbc.Connection.execSQL(Connection.java:3283)

at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1332)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1604)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1519)

at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1504)

at util.DataBaseUtils.update(DataBaseUtils.java:147)

at util.DataBaseUtils.main(DataBaseUtils.java:165)

发现报错了,不慌,看看它说什么。

因为是直播,所以如果我的代码报错了,也会把错误放上来,然后纠正。我也是普通人,很难保证代码一次性就写对。

我知道,初学的时候看到报错就害怕,这是很正常的。没事,慢慢来。

好的,让我们看看它说什么。

Data truncation: Data too long for column ‘id’ at row 1

哦,这说明id的字段长度太短了,而我们生成的UUID太长。

找到User类

Paste_Image.png

我们把id的长度调大一点,换成varchar(100)吧。

Paste_Image.png

接着,修改一下TableUtils,将建表语句加一个删除旧表的判断。

public static String getCreateTableSQl(Class<?> clazz){

StringBuilder sb = new StringBuilder();

//获取表名

Table table = (Table) clazz.getAnnotation(Table.class);

String tableName = table.tableName();

sb.append(“DROP TABLE IF EXISTS “).append(tableName).append(”;\n”);

sb.append("create table ");

sb.append(tableName).append(“(\n”);

Field[] fields = clazz.getDeclaredFields();

String primaryKey = “”;

//遍历所有字段

for (int i = 0; i < fields.length; i++) {

Column column = (Column) fields[i].getAnnotations()[0];

String field = column.field();

String type = column.type();

boolean defaultNull = column.defaultNull();

sb.append(“\t” + field).append(" ").append(type);

if(defaultNull){

if(type.toUpperCase().equals(“TIMESTAMP”)){

sb.append(“,\n”);

}else{

sb.append(" DEFAULT NULL,\n");

}

}else{

sb.append(" NOT NULL,\n");

if(column.primaryKey()){

primaryKey = “PRIMARY KEY (”+field+“)”;

}

}

}

if(!StringUtils.isEmpty(primaryKey)){

sb.append(“\t”).append(primaryKey);

}

sb.append(“\n) DEFAULT CHARSET=utf8”);

return sb.toString();

}

然后,重新生成一下sql语句。

String sql = TableUtils.getCreateTableSQl(User.class);

System.out.println(sql);

Paste_Image.png

加分号,回车。

Paste_Image.png

查看表结构

Paste_Image.png

Paste_Image.png

成功改变了。

好的,回到DataBaseUtils,执行新增操作

String id = UUID.randomUUID() + “”;

String createTime = new SimpleDateFormat(“yyyy-MM-dd”).format(new Date());

update("INSERT INTO t_user(id,username,password,sex,create_time,is_delete,address,telephone) "

  • “VALUES (?, ?, ?, ?, ?, ?, ?, ?)”, id,“张三”,123456,0,createTime,0,“保密”,“保密”);

让我们查询一下现在表里有几条数据。

Paste_Image.png

嗯,应该是成功了呢。

时间关系,本章先介绍到这里。国庆放假正好有时间,过几天还会有一章。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

复习的面试资料

这些面试全部出自大厂面试真题和面试合集当中,小编已经为大家整理完毕(PDF版)

  • 第一部分:Java基础-中级-高级

image

  • 第二部分:开源框架(SSM:Spring+SpringMVC+MyBatis)

image

  • 第三部分:性能调优(JVM+MySQL+Tomcat)

image

  • 第四部分:分布式(限流:ZK+Nginx;缓存:Redis+MongoDB+Memcached;通讯:MQ+kafka)

image

  • 第五部分:微服务(SpringBoot+SpringCloud+Dubbo)

image

  • 第六部分:其他:并发编程+设计模式+数据结构与算法+网络

image

进阶学习笔记pdf

  • Java架构进阶之架构筑基篇(Java基础+并发编程+JVM+MySQL+Tomcat+网络+数据结构与算法

image

  • Java架构进阶之开源框架篇(设计模式+Spring+SpringMVC+MyBatis

image

image

image

  • Java架构进阶之分布式架构篇 (限流(ZK/Nginx)+缓存(Redis/MongoDB/Memcached)+通讯(MQ/kafka)

image

image

image

  • Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)

image

image

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
PJLlbQPt-1713548602086)]

  • Java架构进阶之开源框架篇(设计模式+Spring+SpringMVC+MyBatis

[外链图片转存中…(img-BPwv1lxg-1713548602089)]

[外链图片转存中…(img-WFf6uoBq-1713548602091)]

[外链图片转存中…(img-8brtagdK-1713548602092)]

  • Java架构进阶之分布式架构篇 (限流(ZK/Nginx)+缓存(Redis/MongoDB/Memcached)+通讯(MQ/kafka)

[外链图片转存中…(img-Cee42pal-1713548602094)]

[外链图片转存中…(img-KTwZLno8-1713548602095)]

[外链图片转存中…(img-NU9teNH7-1713548602096)]

  • Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)

[外链图片转存中…(img-pI1wdwVp-1713548602098)]

[外链图片转存中…(img-KGprReKS-1713548602099)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值