JDBC之全面解析

1.什么是JDBC?

就是用来操作sql语句,程序与数据库服务器交互的桥梁。

2.JDBC核心API

|- Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。

                                    |-connect(url, properties):  连接数据库的方法。

                                                        url:连接数据库的URL

                                                                 URL语法: jdbc协议:数据库子协议://主机:端口/数据库

                                                                 user:数据库的用户名

                                                                 password:数据库用户密码

                            |-DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序

                                     |-registerDriver(driver)  : 注册驱动类对象

                                     |-ConnectiongetConnection(url,user,password);  获取连接对象

                            |-Connection接口: 表示java程序和数据库的连接对象。

                                               |-Statement createStatement() : 创建Statement对象

                                               |-PreparedStatement prepareStatement(String sql) 创建PreparedStatement对象

                                               |-CallableStatement prepareCall(String sql) 创建CallableStatement对象

                            |-Statement接口: 用于执行静态的sql语句

                                               |-int executeUpdate(String sql)  :执行静态的更新sql语句(DDL,DML)

                                               |-ResultSet executeQuery(String sql)  :执行的静态的查询sql语句(DQL)

                                     |-PreparedStatement接口:用于执行预编译sql语句

                                                        |- int executeUpdate() :执行预编译的更新sql语句(DDL,DML)

                                                        |-ResultSet executeQuery()  : 执行预编译的查询sql语句(DQL)

                                               |-CallableStatement接口:用于执行存储过程的sql语句(call xxx)

                                                                 |-ResultSetexecuteQuery()  :调用存储过程的方法

                            |-ResultSet接口:用于封装查询出来的数据

                                               |-boolean next() : 将光标移动到下一行

                                               |-getXX(): 获取列的值

3.数据库连接

需要导入jdbc的驱动包:

实现:

public class ConnJdbc {
	private String url="jdbc:mysql://localhost:3306/basicjdbc?characterEncoding=utf-8";
	private String user="root";
	private String password="";
	/*
	 * 第一种连接数据的方法
	 * */
	@Test
	public void test1() throws Exception{
//		Driver driver= new org.gjt.mm.mysql.Driver();
		Driver driver= new com.mysql.jdbc.Driver();
		Properties props=new Properties();
		props.setProperty("user", user);
		props.setProperty("password", password);
		
		Connection conn=driver.connect(url, props);
		System.out.println(conn);
	}
	/*
	 * 第二种连接数据库的方法(推荐)
	 * */
	@Test
	public void test2() throws Exception{
		Class.forName("com.mysql.jdbc.Driver");
		Connection conn=DriverManager.getConnection(url,user,password);
		System.out.println(conn);
	}
}
结果:

com.mysql.jdbc.JDBC4Connection@592021b7

4.JDBC工具类

文件目录结构:

db.properties:

url=jdbc:mysql://localhost:3306/basicjdbc?characterEncoding=utf-8
username=root
password=
driverClass=com.mysql.jdbc.Driver

实现:

public class JdbcUtil {
	private static String url=null;
	private static String username=null;
	private static String password=null;
	private static String driverClass=null;
	static{
		try{
			Properties props=new Properties();
			FileInputStream fis=new FileInputStream("./src/db.properties");
			props.load(fis);
			url=props.getProperty("url");
			username=props.getProperty("username");
			password=props.getProperty("password");
			driverClass=props.getProperty("driverClass");
			//注册驱动程序
			Class.forName(driverClass);
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("驱动程序注册失败!");
		}
	}
	//获取对象的连接
	public static Connection getConnection(){
		try {
			Connection conn=DriverManager.getConnection(url, username, password);
			return conn;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	//释放对象的连接
	public static void close(Connection conn,Statement stmt,ResultSet rs){
		if(rs !=null){
			try{
				rs.close();
			}catch(SQLException e){
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		if(stmt !=null){
			try{
				stmt.close();
			}catch(SQLException e){
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}	
		if(conn !=null){
			try{
				conn.close();
			}catch(SQLException e){
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
}

5.Statement接口的操作(DDL、DML、条件查询)

public class StatementJdbc {
	private Connection conn=null;
	private Statement stmt=null;
	private ResultSet rs=null;
	/*
	 * 执行DDL语句:创建一个表
	 * */
	@Test
	public void test1() throws Exception{
		conn=JdbcUtil.getConnection();
		stmt=conn.createStatement();
		String sql="CREATE TABLE myUser(id INT PRIMARY KEY NOT NULL,username VARCHAR(20),gender VARCHAR(2))";
		stmt.executeUpdate(sql);
		JdbcUtil.close(conn, stmt, null);
	}
	/*
	 * 执行DML语句:向数据库插入一条数据
	 * */
	@Test
	public void test2() throws Exception{
		conn=JdbcUtil.getConnection();
		stmt=conn.createStatement();
		String sql="INSERT INTO myuser VALUES(2,'李四','女')";
		int row=stmt.executeUpdate(sql);
		System.out.println(row);
		JdbcUtil.close(conn, stmt, null);
	}
	/*
	 * 条件查询
	 * */
	@Test
	public void test3() throws Exception{
		String gender="男";
		conn=JdbcUtil.getConnection();
		stmt=conn.createStatement();
		String sql="SELECT * FROM myuser WHERE gender='"+gender+"'";
		rs=stmt.executeQuery(sql);
		while(rs.next()){
			System.out.println(rs.getString("username"));
		}
		JdbcUtil.close(conn, stmt,rs);
	}
}

6.PreparedStatement接口

使用这个接口可以避免了那个sql的拼接,同时也防止了sql注入。

public class PreparedStatementJdbc {
	private Connection conn=null;
	private PreparedStatement ps=null;
	private ResultSet rs=null;
	@Test
	public void test1(){
		String username="张三";
		String gender="男";
		try {
			conn=JdbcUtil.getConnection();
			String sql="select * from myuser where username=? and gender=?";
			ps=conn.prepareStatement(sql);//对sql语句进行预编译,防止非法字符(防止sql注入)。
			ps.setString(1, username);
			ps.setString(2, gender);
			rs=ps.executeQuery();
			while(rs.next()){
				System.out.println("登录成功 ,"+rs.getInt("id"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			JdbcUtil.close(conn,ps,rs);
		}
	}
}
结果:

登录成功 ,1

7.CallableStatement实现存储过程

首先要在SQLyog中创建存储过程:

DELIMITER $$
CREATE PROCEDURE myProcedure()
BEGIN
SELECT * FROM myuser;
END $$

CALL myProcedure();

经过数据库服务器测试,然后此存储过程测试成功。

实现:

public class Jdbc_Call {
	
	private Connection conn=null;
	private CallableStatement cs=null;
	private ResultSet rs=null;
	@Test
	public void testCall(){
		
		try {
			conn=JdbcUtil.getConnection();
			cs=conn.prepareCall("CALL proc_login()");
			rs=cs.executeQuery();
			while(rs.next()){
				String name=rs.getString("username");
				String gender=rs.getString("gender");
				System.out.println(name+":"+gender);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			JdbcUtil.close(conn, cs, rs);
		}
	}
}
结果:


至于带参数的存储过程,可以看我的使用CallableStatement调用存储过程   将会详细解释。

8.JDBC之记录批处理

使用PreparedStatement实现批处理数据时主要是以下几个方法:






实现:

public class User {
    private Integer id;
    private String username;
    private String gender;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
}

public class BatchJdbc {
	private Connection conn=null;
	private PreparedStatement ps=null;
	private ResultSet rs=null;
	@Test
	public void testBatch(){
		List<User> list=new ArrayList<User>();
		for(int i=1;i<21;i++){
			User user=new User();
			user.setId(i);
			user.setUsername("Bryant"+i);
			user.setGender("男");
			list.add(user);	
		}
		save(list);
	}
	
	public void save(List<User> list){
		String sql="insert into myuser(id,username,gender) values(?,?,?)";
		try{
			conn= JdbcUtil.getConnection();
			ps= conn.prepareStatement(sql);
			for(int i=1;i<list.size();i++){
				User user=list.get(i);
				ps.setInt(1, user.getId());
				ps.setString(2, user.getUsername());
				ps.setString(3, user.getGender());
				ps.addBatch();
			}
			ps.executeBatch();
			ps.clearBatch();
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally{
			JdbcUtil.close(conn, ps, rs);
		}	
	}
}
结果:


解释:由于没有设置判断顺序插入,所以数据库中的记录是乱序的。

9.插入数据后获取自增长的键

在数据库中我们新建表时都会在主键处设置auto_increment作为自增长的键。在插入数据时就不必插入自增长的键了。

实现在插入数据后,获取当前记录的自增长主键:

public class Auto_increment_PrimaryKey {
	
	private Connection conn=null;
	private PreparedStatement pstmt=null;
	private ResultSet rs =null;
	@Test
	public void testGetAutoIncrement(){
		String sql="INSERT INTO fruit(apple,banana,orange) VALUES(?,?,?)";
		try{
			conn=JdbcUtil.getConnection();
			pstmt=conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
			pstmt.setString(1, "苹果2");
			pstmt.setString(2, "香蕉2");
			pstmt.setString(3, "橘子2");
			pstmt.executeUpdate();
			rs=pstmt.getGeneratedKeys();
			if(rs.next()){
				System.out.println(rs.getInt(1));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JdbcUtil.close(conn, pstmt, null);
		}
	}
}
结果:


解释:更新记录操作要在获取自增长主键之前,先更新记录了,才会产生自增长的主键,才会获取到。

10.JDBC之事务管理

事务是指使一组最小逻辑操作单元,里面有多个操作组成。组成事务的每一部分必须要同时提交成功,否则整个操作就需要回滚。


表数据:


实现:

public class JdbcTransaction {
	private Connection conn =null;
	private PreparedStatement pstmt =null;
	private ResultSet rs =null;
	@Test
	public void testTransaction(){
		String sql_zs="UPDATE personInfo SET money=money-1000 WHERE NAME='张三'";
		String sql_ls="UPDATE personInfo SET money=money+1000 WHERE NAME='李四'";
		try{
			conn=JdbcUtil.getConnection();
			conn.setAutoCommit(false);//设置手动开启jdbc的事务管理
			pstmt=conn.prepareStatement(sql_zs);
			pstmt.executeUpdate();
			pstmt=conn.prepareStatement(sql_ls);
			pstmt.executeUpdate();	
			conn.commit();
		}catch(Exception e){
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			try{
				JdbcUtil.close(conn, pstmt, rs);
			}catch(Exception e){
				e.printStackTrace();
			}
			
		}
	}
}
结果:








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值