文章目录
JDBC
JDBC(java database connectivty):实现使用java这样的编程语言操作数据库
什么是JDBC ?
JDBC 就是提供了一些方法与接口的规范 ,而出现那么JDBC种类是因为不同厂商针对不同数据库进行对应的方法和规范和实现与设计如:mysql-connector-java-5.1.0-bin.jar, mysql的JDBC驱动包,其实就是一个jar包
JDBC连接数据步骤:
1.导入jar包 (不同代码编辑工具不太一样)
2.通过反射来加载驱动
3.得到连接对象 connection
4.得到发送sql 对象(交通工具)
5.得到返回的结果
6.关闭资源 从下往上进行关闭
注意点:所有的jar包都是导入的是 java.sql.*
import java.sql.*;
//主函数
public static void main(String[] args) {
Connection con = null;
Statement sta = null;
ResultSet rs = null;
try {//第一步:
Class.forName("com.mysql.jdbc.Driver");
//第二步:
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_db?characterEncoding=utf-8", "root", "admin");
//第三步:
sta = con.createStatement();
String sql = "select * from user";
//第四步:
rs = sta.executeQuery(sql);//查询的结果全部存在resultset集合里面,其实可把这个集合类比为一个迭代器
while (rs.next()) {//类似迭代器
int uid = rs.getInt("uid");//指定要查询的数据库列名,字符串名必须和数据库列名相同
String uname = rs.getString("uname");
String upwd = rs.getString("upwd");
System.out.println("编号:" + uid + " 账户: " + uname + " 密码:" + upwd);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {//关闭资源,从下往上关闭
//第五步:
try {
if (rs != null) {
rs.close();
}
if (sta != null) {
sta.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
jdbc的详细解释:
- Class.forName(“com.mysql.jdbc.Driver”); 通过反射来加载驱动 Driver ==>驱动类
- DriverManager 驱动管理对象来获取连接对象 getConnection(“url”,“username”,“password”) =》返回值就是 Connection
url==>表示连接数据库的地址 jdbc:mysql://localhost:3306/数据库的库名?characterEncoding=utf-8 || jdbc:mysql:///day03_db 只支持本地连接 - jdbc: 表示主的协议==>也就是使用jdbc来连接数据库
- mysql: 表示子协议==>也及时使用mysql数据库
- localhost: 表示本机的ip地址
- 3306 表示mysql数据库的端口号,端口号后是数据库的库ming
- ? 后都是表示设置的参数 characterEncoding=utf-8 ==>设置其编码格式
- username:表示数据库的用户名
- password 表示数据库 密码
- conn.createStatement(); ==>表示通过连接对象来获取执行sql 的对象Statement(交通工具)
- sta.executeQuery(sql) 发送sql语句,数据库返回一个结果集 ResultSet
- 关闭资源(从下往上关闭)
jdbc连接数据库使用的类
Driver
DriverManager ( 3.Connection 4.Statement 5.ResultSet)
getConnection();
createStatement()
executeQuery(sql)
colse()
prepareStatement() 获取到 PrepareStatement
ps.setString(1,“li”); ? 表示占位符 给站位符来进行赋值 第一参数是索引 索引是从1开始 第二个参数是具体设置的值
executeUpdate(sql) 执行增删改的方法 返回是int类型 是影响的行数
JDBC常见的错误
- nknown database ‘us’:表示 数据库不存在
- Access denied for user ‘root’@‘localhost’ (using password: YES) : 表示 用户名与密码不正确
- You have an error in your SQL syntax :表示sql 异常
Statement 存在的问题
存在sql注入,sql容易被修改造成不安全,对于动态的变量每次都要直接接拼,非常麻烦
PreparedStatement替换Statement
- 他是 Statement 对象的一个子类
- 可以防止sql注入,保证sql语句的安全
- 会预编译检验sql是否正确 ,不像Statement 全部交给数据库处理造成效率低下(效率高) 用于替换Statement
- 避免sql语句的拼写,使用?占位符
import java.sql.*;
public class NewSelect {
public static void main(String[] args) {
Connection con = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_db?characterEncoding=utf-8", "root", "admin");
String sql = "select * from user where uid=? and uname=?";
PreparedStatement pre = con.prepareStatement(sql);
//根据要传入的数据类型进行填坑
pre.setInt(1, 1);//索引是从1 开始,索引1代表的是第一个?,第二个参数什么类型填什么类型的数据
pre.setString(2, "admin");
//填值结束,执行sql语句
ResultSet res = pre.executeQuery();
while (res.next()) {//类似迭代器
int uid = res.getInt("uid");//指定要查询的数据库列名,字符串名必须和数据库列名相同
String uname = res.getString("uname");
String upwd = res.getString("upwd");
System.out.println("编号:" + uid + " 账户: " + uname + " 密码:" + upwd);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {//关闭资源,从下往上关闭
try {
if (rs != null) {
rs.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
junit 测试
主要是用于测试代码
使用步骤:
1.导包 添加依赖
2.编写一个测试方法(不是main)
注意点:
- 需要使用public void
- 这个方法没有返回值
- 这个方法没有参数
3.在方法加注解 @Test
4.直接运行 绿色表示没有错误 红色表示产生了错误
@Test
public void test(){
}
jdbcUtils工具类的封装
1.加载驱动(只需要加载一次,写在静态代码块)
2.获取连接对象写成一个方法 (三个参数写成常量)
3.增删改
4.查询
5.关闭资源
import com.student.demo.entity.Animal;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BaseDao {
private final static String Driver = "com.mysql.jdbc.Driver";
private final static String url = "jdbc:mysql://localhost:3306/animal_db?characterEncoding=utf-8";
private final static String username = "root";
private final static String password = "admin";
static {//自动加载驱动
try {
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getconnection() {//获取连接对象
try {
return DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void close(Connection con, PreparedStatement pre, ResultSet re) {//关闭数据库连接
try {
if (con != null) {
con.close();
}
if (pre != null) {
pre.close();
}
if (re != null) {
re.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//增删改的方法抽取 ,返回结果是个int ,变量是sql语句,sql的参数的类型和个数 ,还有索引的个数是未知
public static int update(String sql, Object[] objects) {
Connection con = null;
PreparedStatement pre = null;
con = getconnection();
int j = -1;//如果返回负数就是失败
try {
pre = con.prepareStatement(sql);
if (objects != null && objects.length > 0) {
for (int i = 0; i < objects.length; i++) {
pre.setObject(i + 1, objects[i]);
}
}
j = pre.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(con, pre, null);
}
return j;
}
public static List<Animal> selectUtil(String sql, Object[] objects) {
List<Animal> list = new ArrayList<>();
Connection con = null;
PreparedStatement pre = null;
ResultSet re = null;
try {
con = getconnection();
pre = con.prepareStatement(sql);
if (objects != null && objects.length > 0) {
for (int i = 0; i < objects.length; i++) {
pre.setObject(i + 1, objects[i]);
}
}
re = pre.executeQuery();
while (re.next()) {
Animal ani = new Animal();
ani.setId(re.getInt("id"));
ani.setName(re.getString("name"));
ani.setHealth(re.getInt("health"));
ani.setLove(re.getInt("love"));
ani.setStrain(re.getString("strain"));
list.add(ani);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(con, pre, re);
}
return list;
}
}
test类:
import com.student.demo.entity.Animal;
import com.student.demo.util.BaseDao;
import org.junit.Test;
import java.util.List;
public class JDBCTest {
/* 用jdbc 增加一个宠物
根据 id修改宠物信息
删除 id为2的宠物
分页查询前五条信息
使用模糊查询 宠物名字为花的宠物*/
@Test
public void insetTest() {//用jdbc 增加一个宠物
String sql = "insert into animal(name,health,love,strain) values(?,?,?,?)";
Object[] objects = {"大白", 16, 15, "肥猫"};
int i = BaseDao.update(sql, objects);
if (i > 0) {
System.out.println("成功");
}
}
@Test
public void insertsTest() {//添加多条数据
String sql = "insert into animal(name,health,love,strain) " +
"values(?,?,?,?)" +
",(?,?,?,?)" +
",(?,?,?,?)" +
",(?,?,?,?)" +
",(?,?,?,?)";
Object[] objects = {"一白", 16, 15, "一猫",
"二白", 4, 16, "二猫",
"三白", 3, 17, "三猫",
"四白", 2, 18, "四猫",
"五白", 1, 19, "五猫",
};
int i = BaseDao.update(sql, objects);
if (i > 0) {
System.out.println("成功");
}
}
@Test
public void updateTest() {//根据 id修改宠物信息
String sql = "update animal set name=? where id=?";
Object[] objects = {"程序员", 1};
int i = BaseDao.update(sql, objects);
if (i > 0) {
System.out.println("成功");
}
}
@Test
public void deleteTest() {//删除 id为2的宠物
String sql = "delete from animal where id=?";
Object[] objects = {2};
int i = BaseDao.update(sql, objects);
if (i > 0) {
System.out.println("成功");
}
}
@Test
public void limitTest() {//分页查询前五条信息
String sql = "select * from animal limit ?,?";
Object[] objects = {0, 5};
List<Animal> animals = BaseDao.selectUtil(sql, objects);
for (Animal ani : animals) {
System.out.println(ani.toString());
}
}
@Test
public void likeTest(){//使用模糊查询 宠物名字为花的宠物
String sql = "select * from animal where name like ?";
Object[] objects = {"%花%"};
List<Animal> animals = BaseDao.selectUtil(sql, objects);
for (Animal ani : animals) {
System.out.println(ani.toString());
}
}
}