文章目录
1.准备工作
- 首先找到MySQL安装文件地址,在根目录下将mysql-connector-java-5.1.7文件放置在里面。例如我的MySQL文件是在C:\Program Files\MySQL\MySQL Server 5.5
- 在eclipse中创建一个java或者javaweb工程
- 在工程文件根目录上创建一个文件夹,命名为lib,然后将驱动文件:mysql-connector-java-5.1.7-bin.jar复制在此文件夹中。驱动文件是在如下图所示:
- 点击工程中lib文件mysql-connector-java-5.1.7-bin.jar,右键:
2.创建一个数据库
(1)命令窗口形式:
create database student;//1.创建数据库
use student;//2.使用创建的数据库
//3.创建一个简单的表
create table mystudent(
id int primary key,
name varchar(20),
age int
);
//4.在表中添加数据
insert into mystudent values(null,"小明",19);
insert into mystudent values(null,"小芳",18);
insert into mystudent values(null,"小刚",20);
(2)使用SQLyog:
我觉得它就是命令窗口的可视化软件,具体的安装步骤可以百度,在打开时,写上你的数据库的对应端口号,账号和密码即可。
- 鼠标放在在左框》右键
- 打开数据库,右键表
- 写表名,以及表的列数据
- 右键所创的表
- 打开以后添加数据即可。
注:由于我之前创建过mystudent,为了区分我加了下划线。
3.JDBC&java数据库的连接
简单的介绍JDBC
Java Database Connectivity
java数据库连接
- SUN公司提供的访问数据库规则、规范,由于数据库种类较多,并且java语言使用比较广泛,sun公司就提供了一种规范,让其他的数据库去实现底层的访问规则。我们的java程序只要使用sun公司提供的jdbc驱动即可。
JDBC连接数据库简单步骤(以遍历数据库信息为例):
- 注册驱动
- 建立连接
- 创建statement
- 执行sql,得到ResultSet
- 遍历结果集
- 释放资源
package test;
import java.sql.*;
public class MainTest {
public static void main (String[] args) throws ClassNotFoundException {
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
//1.注册驱动
//静态代码块----》类加载了就会执行:java.sql.DriverManager.registerDriver(new Driver());
//因此以下代码,相当于注册了两次
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");//修改
//2.建立连接 参数一:协议+访问的数据库,参数二:用户名,参数三:密码
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");
//3.创建statement,跟数据库打交道,一定需要这个对象
Statement st = conn.createStatement();
//4.执行查询,得到结果集
String sql="select * from mystudent";
ResultSet rs=st.executeQuery(sql);
//遍历每一条记录
while(rs.next()) {
int id=rs.getInt("id");
String name=rs.getString("name");
int age=rs.getInt("age");
System.out.println("id="+id+"==name="+name+"==age="+age);
}
rs.close();
st.close();
conn.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
代码优化与改进
在实际的应用中,我们通常会把代码的声明与实现分开进行。因为在完成一个巨大的代码量时,通常是多人进行合作的,每个人实现一部分的功能,它的声明我认为就相当于一本书的目录,方便管理。
如何进行呢?那么我们就需要用到<mark>接口类</mark>
JDBC Dao模式
- 新建一个dao的接口,里面声明数据库访问规则创建一个package:dao
在里面新建一个接口类:
package dao;
/** * 定义操作数据库的方法 * */
public interface UserDao {
void findAll();//findAll;
void login(String username,String password);//登录方法(有条件查询)
void insert(String username,String password);
void delete(int id);
void update(int id,String name);//根据ID更新具体用户名
}
- 新建一个dao的实现类,具体实现早前定义的规则(由于代码偏多,主要例举遍历数据库和插入数据)
package dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.jupiter.api.Test;
import dao.UserDao;
import util.JDBCUtil;
public class UserDaoImpl implements UserDao{
@Override
@Test
public void findAll() {
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
//1.获取连接对象
conn = JDBCUtil.getConn();
//2.创建Statement对象
st = conn.createStatement();
//3.
String sql = "select * from myuser";
rs = st.executeQuery(sql);
while(rs.next()) {
int id=rs.getInt("id");
String username=rs.getString("username");
String password=rs.getString("password");
String qqemail=rs.getString("QQ邮箱");
int phone=rs.getInt("phone");
System.out.println("id="+id+" username="+username+" password="+password+" QQ邮箱="+qqemail+" phone="+phone);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.release(conn, st, rs);//资源释放类在后面写
}
}
public void insert(String username,String password) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
conn=JDBCUtil.getConn();
String sql="insert into myuser values(null,?,?)";
ps=conn.prepareStatement(sql);
//给占位符赋值
ps.setString(1, username);
ps.setString(2, password);
int result=ps.executeUpdate();
if(result>0) {
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(conn, ps);
}
}
}
- 资源释放类JDBCUtil
==说明:==我们通常不把driver,root,password直接写在程序里
static String url=jdbc:mysql://localhost/student
statico String name=root
static String password=root
而是将它们单独写在资源文件中然后在使用时读取文件,这样我们只需要更改资源文件信息即可,不需要找到源java文件。
首先在根目录下创建一个资源文件:
右键项目文件》new》flie
然后将其命名为jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/user
name=root
password=root
url=jdbc:mysql://localhost/user
中user是指具体使用数据库的名字,在写代码时要灵活处理
package util;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
static String driverClass=null;
static String url=null;
static String name=null;
static String password=null;
static {
try {
Properties properties= new Properties();
InputStream is=new FileInputStream("jdbc.properties");//放在工程文件下使用
//InputStream is=JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");//放在src下使用
//导入输入流
properties.load(is);
//读取属性
driverClass=properties.getProperty("driverClass");
url=properties.getProperty("url");
name=properties.getProperty("name");
password=properties.getProperty("password");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/** * 获取连接对象 * @return * */
public static Connection getConn() {
Connection conn=null;
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(url,name,password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/** 释放资源 * * **/
public static void release(Connection conn,Statement st,ResultSet rs) {
closeRs(rs);
closeSt(st);
closeConn(conn);
}
public static void release(Connection conn,Statement st) {
closeSt(st);
closeConn(conn);
}
private static void closeRs(ResultSet rs) {
try {
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
rs=null;
}
}
private static void closeSt(Statement st) {
try {
if(st!=null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
st=null;
}
}
private static void closeConn(Connection conn) {
try {
if(conn!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
conn=null;
}
}
}
- 测试类,测试你连接数据库是否成功
package test;
import org.junit.Test;
import dao.UserDao;
import dao.impl.UserDaoImpl;
public class TestUserDaoImpl {
@Test
public void TestfindAll() {
UserDao dao=new UserDaoImpl();//接口引用对象
dao.findAll();
}
@Test
public void insert() {
UserDao dao=new UserDaoImpl();
dao.insert("xiaofang", "991");
}
}
在这里,我们用了一个junit包,在想要测试的方法前写@Test
然后鼠标放在该方法名上》右键
就可以运行,如果运行结果显示绿色条,证明运行没有错误,但并不能保证逻辑等完全正确。
这是改进后我所用的数据库:
最终运行结果为:
成功!
这个 UserDao;UserDao.impl;JDBCUtil;jdbc.properties
文件可以保留下来在多个工程中都可以去用,只需要稍作改动,这样避免每次都要写,很麻烦。
4.statement安全问题
statement的执行,其实是拼接sql语句,然后再一起执行。
//前面先拼接sql语句,如果变量里面带有了数据库的关键字,那么一并认为是关键字,不认为是普通的字符串
String sql = "select * from myuser where username='"+username+"' and password='"+password+"'";
rs = st.executeQuery(sql);
if(rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
public void TestLogin() {
UserDao dao=new UserDaoImpl();
dao.login("admin", "10086'or'1=1");
// SELECT * FROM myuser WHERE username="admin" AND PASSWORD="10088" OR 1=1;
}
PrepareStatement
该对象就是替换前面的statement对象(预先对sql语句执行语法校验)
String sql="select * from myuser where username=? and password=?";
//?对应的内容,后面不管传递什么进来,都把它看成是字符串
PreparedStatement ps = conn.prepareStatement(sql);
//?对应的索引从1开始
ps.setString(1, username);
ps.setString(2, password);
rs=ps.executeQuery();
if(rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
statement 给preparedstatement参数不报错因为preparedstatement是statement 的子类(体现了多态性)
5.数据库连接包mysql-connector-java-5.1.7链接以及SQLyog的安装包链接
链接:https://pan.baidu.com/s/1Guio_lS-TmvbTN6_LKo3Rg
提取码:herm
咳咳,如果有问题欢迎找我讨论哦~