文章目录
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(); } } }
代码优化与改进
在实际的应用中,我们通常会把代码的声明与实现分开进行。因为在完成一个巨大的代码量时,通常是多人进行合作的,每个人实现一部分的功能,它的声明我认为就相当于一本书的目录,方便管理。
如何进行呢?那么我们就需要用到接口类
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
咳咳,如果有问题欢迎找我讨论哦~