JDBC简单入门
在工作中,程序员可能会需要用到很多数据库,若没有相应的工具,程序员每用到一个数据库就需要掌握一条与之对应的方法调用,当换数据库时,代码也需要做相应改动,这样极其不利于开发,效率很低,这时JDBC接口就应运而生。JDBC(java Database Connectivity) java数据库连接,实际上JDBC是sun公司提供一套连接数据库的APIsun公司提供JDBC接口,让各个数据库厂商根据此接
在工作中,程序员可能会需要用到很多数据库,若没有相应的工具,程序员每用到一个数据库就需要掌握一条与之对应的方法调用,当换数据库时,代码也需要做相应改动,这样极其不利于开发,效率很低,这时JDBC接口就应运而生。
JDBC(java Database Connectivity) java数据库连接,实际上JDBC是sun公司提供一套连接数据库的API
sun公司提供JDBC接口,让各个数据库厂商根据此接口写实现类(驱动),这样java程序员只需要掌握JDBC接口中的方法的调用,就可以访问任何数据,而且换数据库时代码不需要做任何的改动。
本文目录
一、初步建立JDBC
1、建立一个普通Java工程
2、创建一个包,将java数据库连接的jar包导入
3、找到idea中的项目结构选项点击进入,找到libraries
4、进入libraries并找到“+”,后续照图示进行点击
5、找到之前导入的jar包,点击确定
6、点击应用后,确定。
7、先前导入的jar包可以打开了,我们可以使用其中的接口方法了
8、可以在idea中写数据库相关语句了
public class Demo01 {
public static void main(String[] args) {
//通过java来操作数据库
// 1.加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 2.获取链接
Connection connection=null;
try {
connection=DriverManager.getConnection("数据库驱动地址","数据库用户名","数据库密码");
} catch (SQLException e) {
e.printStackTrace();
}
// 3.获取对象 执行sql语句
Statement statement=null;
try {
statement=connection.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
// 4.执行sql
try {
boolean bo=statement.execute("sql语句");
} catch (SQLException e) {
e.printStackTrace();
}
// 5.关闭数据库
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
statement.execute(“sql语句”);可以执行所有sql语句 增删改查
statement.executeQuery(“查操作”);
statement.executeUpdate(“改操作”);
二、配置工具类与外部文件
在实际开发时,如果我们每用一次数据库就写一遍连接数据库的代码,这样是很浪费时间的,为了便于开发随去随用,我们可以把重复的一样的代码都封装在一个工具类中,每当我们要用时,直接引用即可。
而类似数据库驱动地址、数据库用户名、数据库密码这些变量,如果当我们要换数据库时,就需要对其做出调整,我们就需要在java代码中去找这些变量,这样也是很不方便的。这时我们可以把这些变量都封装在一个外部文件中,通过外部文件给java代码中这些变量赋上值,当我们要修改数据库时,只需修改外部文件中的内容即可,实现一种动态赋值。
工具类:
public class DBUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
static{
Properties properties=new Properties();
InputStream is=DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=properties.getProperty("db.driver");
url=properties.getProperty("db.url");
username=properties.getProperty("db.username");
password=properties.getProperty("db.password");
}
public static Connection getConnection() {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection= null;
try {
connection = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void close(Connection connection) {
if(connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
配置文件:
配置文件需要放在资源目录下才能被找到。
案例:查找用户
从数据库中拿取的数据可以通过类的包装来保存
包装类:
```java
public class DBemp {
private int id;
private String name;
public DBemp(){
}
public DBemp(int id, String name){
this.id=id;
this.name=name;
}
public void setId(int id){
this.id=id;
}
public int getId(){
return id;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public String toString(){
return "id="+id+" name="+name;
}
}
主方法:
public class GetUser {
public static void main(String[] args) throws Exception {
Connection conn= DBUtil.getConnection();
Statement st=conn.createStatement();
String s="select * from emp";
ResultSet rs=st.executeQuery(s);
List<DBemp> list=new ArrayList<>();
while(rs.next()){
int id=rs.getInt("id");
String name=rs.getString("name");
DBemp db=new DBemp(id,name);
list.add(db);
}
System.out.println(list);
DBUtil.close(conn);
}
}
三、数据库连接池
每次用到数据库时,都涉及到了开启数据库–连接数据库–关闭数据库的流程,如果我们需要多次使用数据库时,重复做这个流程是十分耗费计算机性能的。我们可以借助数据库连接池来解决这个问题。
1、导入数据库连接池
导入数据库连接池的方法和导入JDBC的步骤基本一样,可根据图示进行操作:
现在导入完成的是一个第三方的jar包,我们还需导入一个他依赖的jar包来为他提供一些他没有的类
因为导入步骤和dbcp完全一样,这里就不做演示了(偷个懒~~)
导入完成
2、设置数据库连接池
配置文件
主方法
public class DBUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
private static int initnum;
private static int maxNum;
private static BasicDataSource basicDataSource;
static{
basicDataSource=new BasicDataSource();
Properties properties=new Properties();
InputStream is=DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=properties.getProperty("db.driver");
url=properties.getProperty("db.url");
username=properties.getProperty("db.username");
password=properties.getProperty("db.password");
//连接池:
initnum=Integer.parseInt(properties.getProperty("db.initnum"));
maxNum=Integer.parseInt(properties.getProperty("db.maxunm"));
basicDataSource.setDriverClassName(driver);
basicDataSource.setUrl(url);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
basicDataSource.setMaxActive(maxNum);
basicDataSource.setInitialSize(initnum);
}
public static Connection getConnection() {
Connection connection= null;
try {
connection = basicDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void close(Connection connection) {
if(connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
四、通过maven构建JDBC
以上我们都是通过手动的方式来获取jar包并解压,操作后我们可以发现这种方式是十分麻烦的、而且很多jar包是存在依赖关系的,例如我们上面配置的commons-dbcp的jar包,需要在其他jar包的支持下才能正常使用,这时我们就面临了一个问题,当我们使用一个新的、我们从来没用过的jar包时,我们如何知道它是否需要依赖、需要依赖哪些jar包,如果让我们把所有jar包都记住,大家也都明白这是不可能的,若是每次使用jar都要上网上去搜索这个jar包的特性,也是十分耗时耗力的。
而Java为我们提供的项目管理工具maven可以很好的解决这个问题。我们只需要在maven中提供一个坐标,maven就会帮我们获取到这个jar包,并添加到项目中,无需我们自己操作配置了。而且引入maven后,maven就可以自动帮我们将当前jar包所依赖的其他所有jar包全部导入进来,也不需要我们自己去判断这个jar包需要哪些jar包了,节省了很大的精力,提升了我们项目的效率。
下面我们来演示一下通过maven来获取jar包。
1、创建一个maven工程
2、在pom.xml文件中导入所需依赖的坐标,刷新pom文件
3、我们可以在外部库中找到我们想要的jar包,代表这个项目需要的依赖已经被我们配置进去了,而且jar包需要的依赖也一并被配置。
案例:用户登录
工具类同上
封装类
public class Emp {
private int password;
private String username;
public Emp(){
}
public Emp(String username,int password){
this.password=password;
this.username=username;
}
public void setPassword(int password){
this.password=password;
}
public int getPassword(){
return password;
}
public void setUsername(String username){
this.username=username;
}
public String getUsername(){
return username;
}
public String toString(){
return "username="+username+" password="+password;
}
}
主方法
public class Demo01 {
public static void main(String[] args) throws SQLException {
Connection con=HomeDBUtil.getConnection();
Statement sta=con.createStatement();
String st="select * from emp";
ResultSet rs=sta.executeQuery(st);
ArrayList<String> list=new ArrayList();
while(rs.next()){
String username=rs.getString("ename");
int password=rs.getInt("empno");
Emp emp=new Emp(username,password);
list.add(emp.toString());
}
HomeDBUtil.close(con);
Scanner sc=new Scanner(System.in);
while(true){
System.out.print("username=");
String name=sc.next();
System.out.print("password=");
String password=sc.next();
int sum=0;
for(String s:list){
sum++;
if(s.equals("username="+name+" password="+password)){
System.out.println("登录成功");
break;
}
if(sum==list.size()){
System.out.println("用户名或密码错误");
}
}
}
}
}
此案例仅是浅用一下JDBC作为测试,严格的用户登录应更精密的查询,例如应该先查一下用户名,看数据库中是否有此用户,再看密码,判断密码是否一致。
五、sql注入
1、防止sql注入
sql注入是一种代码漏洞,程序员可以通过sql注入非法获取数据库中的信息。
例:用户登录
select * from user where username=‘张三’ and password=123456;
通过这个语句可以在数据库中查找是否有相应用户,判断是否可以登录。这时当我们在后面拼接一个字符串:
sql注入:
select * from user where username=‘张三’ and password=123456 or 1=1;
程序员只需要在sql语句后面拼接 or 1=1 就可以让这个语句成为一个恒成立的句子,这是十分危险,很容易造成数据库中数据被窃取,我们需要避免sql注入的发生。
为了防止sql注入的发生,我们可以使用预编译对象PreparedStatement
String st="select * from emp where ename=? and empno=?";
PreparedStatement ps=con.prepareStatement(st);
ps.setInt(2,7521);
ps.setString(1,"WARD");
ResultSet rs=ps.executeQuery();
在创建对象时就会对sql语句进行预编译,将sql语句的逻辑锁死,从而实现防止sql注入的作用。
只要sql语句中出现变量时,为了保证安全我们需要使用PreparedStatement
2、批量操作
PreparedStatement
//执行批量删除
Connection con=HomeDBUtil.getConnection();
String st="delete from userinfo where user_id=?";
PreparedStatement ps=con.prepareStatement(st);
for(int i=1;i<=3;i++) {
ps.setInt(1, i);
ps.addBatch();
}
ps.executeBatch();
Statement
//执行批量删除
Connection con=HomeDBUtil.getConnection();
Statement statement=con.createStatement();
for(int i=0;i<3;i++){
String st="delete from userinfo where user_id="+i;
statement.addBatch(st);
}
statement.executeBatch();
每次执行到addBatch方法时,都会将当前执行的sql语句放在缓冲池,等待executeBatch()方法批量执行。
3、分页查询
public class Demo04 {
public static void main(String[] args) throws SQLException {
Scanner sc=new Scanner(System.in);
Connection con=HomeDBUtil.getConnection();
int pageSize=2;
System.out.println("要第几页:");
int num=sc.nextInt();
String st="select * from emp limit ?,?";
PreparedStatement ps=con.prepareStatement(st);
int startLine=(num-1)*pageSize;
ps.setInt(1,startLine);
ps.setInt(2,pageSize);
ResultSet rs=ps.executeQuery();
while(rs.next()){
int empno= rs.getInt("empno");
String ename=rs.getString("ename");
System.out.println("empno:"+empno+";ename:"+ename);
}
HomeDBUtil.close(con);
}
}
第一个?表示请求第几页,第二个?表示一页有几条数据。
4、常规事务操作
事务相关方法
con.setAutoCommit(false);//关闭事务自动提交
con.setAutoCommit(true);//开启事务自动提交
con.commit();//提交事务
con.rollback();//回滚事务
如果自动提交关闭了,我们需要手动提交。
5、获取自增主键
PreparedStatement ps=con.prepareStatement(st, Statement.RETURN_GENERATED_KEYS);
Statement.RETURN_GENERATED_KEYS 指的是能返回当前表的自增主键
ResultSet rs=ps.getGeneratedKeys();
getGeneratedKeys()方法能获取刚刚插入的自增主键,若是批量插入,就会获取批量插入的所有自增主键。
6、获取元数据
能够获取数据库相关的信息
//得到数据库的元数据
Connection conn=DBUtil.getConnection();
Statement stat=conn.createStatement();
DatabaseMetaData dbmd = conn.getMetaData();
System.out.println("数据库版本:"+ dbmd.getDriverVersion());
System.out.println("用户名:"+ dbmd.getUserName());
System.out.println("数据库地址:"+ dbmd.getURL());
System.out.println("数据库厂商:"+ dbmd.getDatabaseProductName());
能够获取表相关的信息
//得到表相关的源数据
Connection conn=DBUtil.getConnection();
Statement stat=conn.createStatement();
ResultSet rs = stat.executeQuery("select * from emp");
ResultSetMetaData rsmd = rs.getMetaData();
//得到表的字段数量
int count = rsmd.getColumnCount();
for (int i = 0; i < count; i++) {
System.out.println("字段名" +rsmd.getColumnName(i+1));
System.out.println("字段类型" +rsmd.getColumnTypeName(i+1));
}
六、在哪儿下载jar包和获取依赖坐标
更多推荐
所有评论(0)