主頁 > 資料庫 > JDBC

JDBC

2020-09-19 12:11:21 資料庫

今天對JDBC的內容又進行了一下復習,并學了一些新的知識如資料庫連接池,Spring JDBC等,

主要內容

1. JDBC基本概念
2. 快速入門
3. 對JDBC中各個介面和類詳解
    4. 資料庫連接池
5. Spring JDBC : JDBC Template

JDBC

1. 概念:Java DataBase Connectivity  Java 資料庫連接, Java語言操作資料庫
	* JDBC本質:其實是官方(sun公司)定義的一套操作所有關系型資料庫的規則,即介面,各個資料庫廠商去實作這套介面,提供資料庫驅動jar包,我們可以使用這套介面(JDBC)編程,真正執行的代碼是驅動jar包中的實作類,

2. 快速入門:
	* 步驟:
		1. 匯入驅動jar包 mysql-connector-java-5.1.37-bin.jar
			1.復制mysql-connector-java-5.1.37-bin.jar到專案的libs目錄下
			2.右鍵-->Add As Library
		2. 注冊驅動
		3. 獲取資料庫連接物件 Connection
		4. 定義sql
		5. 獲取執行sql陳述句的物件 Statement
		6. 執行sql,接受回傳結果
		7. 處理結果
		8. 釋放資源

	* 代碼實作:
	  	//1. 匯入驅動jar包
        //2.注冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        //3.獲取資料庫連接物件
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
        //4.定義sql陳述句
        String sql = "update account set balance = 500 where id = 1";
        //5.獲取執行sql的物件 Statement
        Statement stmt = conn.createStatement();
        //6.執行sql
        int count = stmt.executeUpdate(sql);
        //7.處理結果
        System.out.println(count);
        //8.釋放資源
        stmt.close();
        conn.close();

3. 詳解各個物件:
	1. DriverManager:驅動管理物件
		* 功能:
			1. 注冊驅動:告訴程式該使用哪一個資料庫驅動jar
				static void registerDriver(Driver driver) :注冊與給定的驅動程式 DriverManager , 
				寫代碼使用:  Class.forName("com.mysql.jdbc.Driver");
				通過查看原始碼發現:在com.mysql.jdbc.Driver類中存在靜態代碼塊
				 static {
				        try {
				            java.sql.DriverManager.registerDriver(new Driver());
				        } catch (SQLException E) {
				            throw new RuntimeException("Can't register driver!");
				        }
					}

				注意:mysql5之后的驅動jar包可以省略注冊驅動的步驟,
			2. 獲取資料庫連接:
				* 方法:static Connection getConnection(String url, String user, String password) 
				* 引數:
					* url:指定連接的路徑
						* 語法:jdbc:mysql://ip地址(域名):埠號/資料庫名稱
						* 例子:jdbc:mysql://localhost:3306/db3
						* 細節:如果連接的是本機mysql服務器,并且mysql服務默認埠是3306,則url可以簡寫為:jdbc:mysql:///資料庫名稱
					* user:用戶名
					* password:密碼 
	2. Connection:資料庫連接物件
		1. 功能:
			1. 獲取執行sql 的物件
				* Statement createStatement()
				* PreparedStatement prepareStatement(String sql)  
			2. 管理事務:
				* 開啟事務:setAutoCommit(boolean autoCommit) :呼叫該方法設定引數為false,即開啟事務
				* 提交事務:commit() 
				* 回滾事務:rollback() 
	3. Statement:執行sql的物件
		1. 執行sql
			1. boolean execute(String sql) :可以執行任意的sql 了解 
			2. int executeUpdate(String sql) :執行DML(insert、update、delete)陳述句、DDL(create、alter、drop)陳述句
				* 回傳值:影響的行數,可以通過這個影響的行數判斷DML陳述句是否執行成功 回傳值>0的則執行成功,反之,則失敗,
			3. ResultSet executeQuery(String sql)  :執行DQL(select)陳述句
		2. 練習:
			1. account表 添加一條記錄
			2. account表 修改記錄
			3. account表 洗掉一條記錄

			代碼:
				Statement stmt = null;
		        Connection conn = null;
		        try {
		            //1. 注冊驅動
		            Class.forName("com.mysql.jdbc.Driver");
		            //2. 定義sql
		            String sql = "insert into account values(null,'王五',3000)";
		            //3.獲取Connection物件
		            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
		            //4.獲取執行sql的物件 Statement
		            stmt = conn.createStatement();
		            //5.執行sql
		            int count = stmt.executeUpdate(sql);//影響的行數
		            //6.處理結果
		            System.out.println(count);
		            if(count > 0){
		                System.out.println("添加成功!");
		            }else{
		                System.out.println("添加失敗!");
		            }
		
		        } catch (ClassNotFoundException e) {
		            e.printStackTrace();
		        } catch (SQLException e) {
		            e.printStackTrace();
		        }finally {
		            //stmt.close();
		            //7. 釋放資源
		            //避免空指標例外
		            if(stmt != null){
		                try {
		                    stmt.close();
		                } catch (SQLException e) {
		                    e.printStackTrace();
		                }
		            }
		
		            if(conn != null){
		                try {
		                    conn.close();
		                } catch (SQLException e) {
		                    e.printStackTrace();
		                }
		            }
		        }
			
			修改洗掉與添加操作流程一樣,只需更改sql陳述句即可,
			
	4. ResultSet:結果集物件,封裝查詢結果
		* boolean next(): 游標向下移動一行,判斷當前行是否是最后一行末尾(是否有資料),如果是,則回傳false,如果不是則回傳true
		* getXxx(引數):獲取資料
			* Xxx:代表資料型別   如: int getInt() ,	String getString()
			* 引數:
				1. int:代表列的編號,從1開始   如: getString(1)
				2. String:代表列名稱, 如: getDouble("balance")
		
		* 注意:
			* 使用步驟:
				1. 游標向下移動一行
				2. 判斷是否有資料
				3. 獲取資料

			   //回圈判斷游標是否是最后一行末尾,
	            while(rs.next()){
	                //獲取資料
	                int id = rs.getInt(1);
	                String name = rs.getString("name");
	                double balance = rs.getDouble(3);
	
	                System.out.println(id + "---" + name + "---" + balance);
	            }

					
	5. PreparedStatement:執行sql的物件
		1. SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字串的拼接,會造成安全性問題
			1. 輸入用戶隨便,輸入密碼:a' or 'a' = 'a
			2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

		2. 解決sql注入問題:使用PreparedStatement物件來解決
		3. 預編譯的SQL:引數使用?作為占位符
		4. 步驟:
			1. 匯入驅動jar包 mysql-connector-java-5.1.37-bin.jar
			2. 注冊驅動
			3. 獲取資料庫連接物件 Connection
			4. 定義sql
				* 注意:sql的引數使用?作為占位符, 如:select * from user where username = ? and password = ?;
			5. 獲取執行sql陳述句的物件 PreparedStatement  Connection.prepareStatement(String sql) 
			6. 給?賦值:
				* 方法: setXxx(引數1,引數2)
					* 引數1:?的位置編號 從1 開始
					* 引數2:?的值
			7. 執行sql,接受回傳結果,不需要傳遞sql陳述句
			8. 處理結果
			9. 釋放資源

			例子:
				String sql = "select * from user where username = ? and password = ?";
                pstmt = conn.prepareStatement(sql);
                pstmt.setString(1, username);
                pstmt.setString(2, password);
                rs = pstmt.executeQuery();


		5. 注意:后期都會使用PreparedStatement來完成增刪改查的所有操作
			1. 可以防止SQL注入
			2. 效率更高

抽取JDBC工具類 : JDBCUtils

* 目的:簡化書寫
* 分析:
	1. 注冊驅動也抽取
	2. 抽取一個方法獲取連接物件
		* 需求:不想傳遞引數(麻煩),還得保證工具類的通用性,
		* 解決:組態檔
			jdbc.properties
				url=
				user=
				password=
		  例如:
				url=jdbc:mysql:///db3
				user=root
				password=root
				driver=com.mysql.jdbc.Driver
		  注意:
				等號兩邊沒有空格
				等號右邊不用加引號

	3. 抽取一個方法釋放資源

* 代碼實作:
	public class JDBCUtils {
	    private static String url;
	    private static String user;
	    private static String password;
	    private static String driver;
	    /**
	     * 檔案的讀取,只需要讀取一次即可拿到這些值,使用靜態代碼塊
	     */
	    static{
	        //讀取資源檔案,獲取值,
	
	        try {
	            //1. 創建Properties集合類,
	            Properties pro = new Properties();
	
	            //獲取src路徑下的檔案的方式--->ClassLoader 類加載器
	            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
	            URL res  = classLoader.getResource("jdbc.properties");
	            String path = res.getPath();//得到絕對路徑
	            System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
	            //2. 加載檔案
	            // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
	            pro.load(new FileReader(path));
	
	            //3. 獲取資料,賦值
	            url = pro.getProperty("url");
	            user = pro.getProperty("user");
	            password = pro.getProperty("password");
	            driver = pro.getProperty("driver");
	            //4. 注冊驅動
	            Class.forName(driver);
	        } catch (IOException e) {
	            e.printStackTrace();
	        } catch (ClassNotFoundException e) {
	            e.printStackTrace();
	        }
    	}


    /**
     * 獲取連接
     * @return 連接物件
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 釋放資源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt,Connection conn){
        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 釋放資源
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs,Statement stmt, Connection conn){
        if( rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

* 練習:
	* 需求:
		1. 通過鍵盤錄入用戶名和密碼
		2. 判斷用戶是否登錄成功
			* select * from user where username = "" and password = "";
			* 如果這個sql有查詢結果,則成功,反之,則失敗

	* 步驟:
		1. 創建資料庫表 user
			CREATE TABLE USER(
				id INT PRIMARY KEY AUTO_INCREMENT,
				username VARCHAR(32),
				PASSWORD VARCHAR(32)
			
			);

			INSERT INTO USER VALUES(NULL,'zhangsan','123');
			INSERT INTO USER VALUES(NULL,'lisi','234');

		2. 代碼實作:
			public class JDBC_Demo {
			    public static void main(String[] args) {
			        Scanner sc = new Scanner(System.in);
			        System.out.println("請輸入用戶名:");
			        String username = sc.nextLine();
			        System.out.println("請輸入密碼:");
			        String password = sc.nextLine();
			        boolean flag = new JDBC_Demo().login(username, password);
			        if (flag) {
			            System.out.println("登陸成功!");
			        } else {
			            System.out.println("用戶名或密碼錯誤!");
			        }
			
			    }
			    public boolean login(String username,String password) {
			        if (username == null || password == null) {
			            return false;
			        }
			        Connection conn = null;
			        PreparedStatement pstmt = null;
			        ResultSet rs = null;
			
			        try {
			            conn = JDBCUtils.getConnection();
			            String sql = "select * from user where username = ? and password = ?";
			            pstmt = conn.prepareStatement(sql);
			            pstmt.setString(1, username);
			            pstmt.setString(2, password);
			            rs = pstmt.executeQuery();
			            return rs.next();
			        } catch (SQLException e) {
			            e.printStackTrace();
			        } finally {
			            JDBCUtils.close(rs, pstmt, conn);
			        }
			        return false;
			    }
			}

ps:實作這個樣例時遇到了一個問題,運行時會報錯找不到properties檔案,檢查了代碼沒有bug,認為問題可能是因為專案所在路徑檔案夾名稱中有空格,將專案移到另外一個目錄即可正常運行,

JDBC控制事務

1. 事務:一個包含多個步驟的業務操作,如果這個業務操作被事務管理,則這多個步驟要么同時成功,要么同時失敗,
2. 操作:
	1. 開啟事務
	2. 提交事務
	3. 回滾事務
3. 使用Connection物件來管理事務
	* 開啟事務:setAutoCommit(boolean autoCommit) :呼叫該方法設定引數為false,即開啟事務
		* 在執行sql之前開啟事務
	* 提交事務:commit() 
		* 當所有sql都執行完提交事務
	* 回滾事務:rollback() 
		* 在catch中回滾事務

4. 代碼:
	public class JDBCDemo10 {

	    public static void main(String[] args) {
	        Connection conn = null;
	        PreparedStatement pstmt1 = null;
	        PreparedStatement pstmt2 = null;
	
	        try {
	            //1.獲取連接
	            conn = JDBCUtils.getConnection();
	            //開啟事務
	            conn.setAutoCommit(false);
	
	            //2.定義sql
	            //2.1 張三 - 500
	            String sql1 = "update account set balance = balance - ? where id = ?";
	            //2.2 李四 + 500
	            String sql2 = "update account set balance = balance + ? where id = ?";
	            //3.獲取執行sql物件
	            pstmt1 = conn.prepareStatement(sql1);
	            pstmt2 = conn.prepareStatement(sql2);
	            //4. 設定引數
	            pstmt1.setDouble(1,500);
	            pstmt1.setInt(2,1);
	
	            pstmt2.setDouble(1,500);
	            pstmt2.setInt(2,2);
	            //5.執行sql
	            pstmt1.executeUpdate();
	            // 手動制造例外
	            int i = 3/0;
	
	            pstmt2.executeUpdate();
	            //提交事務
	            conn.commit();
	        } catch (Exception e) {
	            //事務回滾
	            try {
	                if(conn != null) {
	                    conn.rollback();
	                }
	            } catch (SQLException e1) {
	                e1.printStackTrace();
	            }
	            e.printStackTrace();
	        }finally {
	            JDBCUtils.close(pstmt1,conn);
	            JDBCUtils.close(pstmt2,null);
	        }
	    }	
	}

資料庫連接池

1. 概念:其實就是一個容器(集合),存放資料庫連接的容器,
	    當系統初始化好后,容器被創建,容器中會申請一些連接物件,當用戶來訪問資料庫時,從容器中獲取連接物件,用戶訪問完之后,會將連接物件歸還給容器,

2. 好處:
	1. 節約資源
	2. 用戶訪問高效

3. 實作:
	1. 標準介面:DataSource   javax.sql包下的
		1. 方法:
			* 獲取連接:getConnection()
			* 歸還連接:Connection.close(),如果連接物件Connection是從連接池中獲取的,那么呼叫Connection.close()方法,則不會再關閉連接了,而是歸還連接,

	2. 一般我們不去實作它,有資料庫廠商來實作
		1. C3P0:資料庫連接池技術
		2. Druid:資料庫連接池實作技術,由阿里巴巴提供的


4. C3P0:資料庫連接池技術
	* 使用步驟:
		1. 匯入jar包 (兩個) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
			* 不要忘記匯入資料庫驅動jar包
		2. 定義組態檔:
			* 名稱: c3p0.properties 或者 c3p0-config.xml
			* 路徑:直接將檔案放在src目錄下即可,
			* 引數:
				* 連接引數: driverClass 例如:com.mysql.jdbc.Driver
							jdbcUrl 例如:jdbc:mysql://localhost:3306/db3
							user 例如:root
							password 例如: root
				* 連接池引數: initialPoolSize 初始連接池大小(也就是可以獲取連接的Connection數量)
							 maxPoolSize 連接池最大連接數量
							 checkoutTimeout 報錯的等待時間

		3. 創建核心物件 資料庫連接池物件 ComboPooledDataSource
		4. 獲取連接: getConnection
	
	* 代碼:
		 //1.創建資料庫連接池物件
         DataSource ds  = new ComboPooledDataSource();
         //2. 獲取連接物件
         Connection conn = ds.getConnection();
5. Druid:資料庫連接池實作技術,由阿里巴巴提供的
	* 使用步驟:
		1. 匯入jar包 druid-1.0.9.jar
		2. 定義組態檔:
			* 是properties形式的
			* 可以叫任意名稱,可以放在任意目錄下
		3. 加載組態檔,Properties
		4. 獲取資料庫連接池物件:通過工廠類來獲取  DruidDataSourceFactory
		5. 獲取連接:getConnection
	
	* 代碼:
		//3.加載組態檔
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //4.獲取連接池物件
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.獲取連接
        Connection conn = ds.getConnection();
	
	* 定義工具類
		1. 定義一個類 JDBCUtils
		2. 提供靜態代碼塊加載組態檔,初始化連接池物件
		3. 提供方法
			1. 獲取連接方法:通過資料庫連接池獲取連接
			2. 釋放資源
			3. 獲取連接池的方法


	* 代碼:
		public class JDBCUtils {

		    //1.定義成員變數 DataSource
		    private static DataSource ds ;
		
		    static{
		        try {
		            //1.加載組態檔
		            Properties pro = new Properties();
		            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
		            //2.獲取DataSource
		            ds = DruidDataSourceFactory.createDataSource(pro);
		        } catch (IOException e) {
		            e.printStackTrace();
		        } catch (Exception e) {
		            e.printStackTrace();
		        }
		    }
		
		    /**
		     * 獲取連接
		     */
		    public static Connection getConnection() throws SQLException {
		        return ds.getConnection();
		    }
		
		    /**
		     * 釋放資源
		     */
		    public static void close(Statement stmt,Connection conn){
		       /* if(stmt != null){
		            try {
		                stmt.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		        if(conn != null){
		            try {
		                conn.close();//歸還連接池
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }*/
		
		       close(null,stmt,conn);
		    }
		
		
		    public static void close(ResultSet rs , Statement stmt, Connection conn){
		
		
		        if(rs != null){
		            try {
		                rs.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		
		        if(stmt != null){
		            try {
		                stmt.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		        if(conn != null){
		            try {
		                conn.close();//歸還連接池
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		    }
		
		    /**
		     * 獲取連接池方法
		     */
		
		    public static DataSource getDataSource(){
		        return  ds;
		    }
		
		}

Spring JDBC

* Spring框架對JDBC的簡單封裝,提供了一個JDBCTemplate物件簡化JDBC的開發
* 步驟:
	1. 匯入jar包
	2. 創建JdbcTemplate物件,依賴于資料源DataSource
		* JdbcTemplate template = new JdbcTemplate(ds);

	3. 呼叫JdbcTemplate的方法來完成CRUD的操作
		* update():執行DML陳述句,增、刪、改陳述句
		* queryForMap():查詢結果將結果集封裝為map集合,將列名作為key,將值作為value 將這條記錄封裝為一個map集合
			* 注意:這個方法查詢的結果集長度只能是1
		* queryForList():查詢結果將結果集封裝為list集合
			* 注意:將每一條記錄封裝為一個Map集合,再將Map集合裝載到List集合中
		* query():查詢結果,將結果封裝為JavaBean物件
			* query的引數:RowMapper
				* 一般我們使用BeanPropertyRowMapper實作類,可以完成資料到JavaBean的自動封裝
				* new BeanPropertyRowMapper<型別>(型別.class)
		* queryForObject:查詢結果,將結果封裝為物件
			* 一般用于聚合函式的查詢

	4. 練習:
		* 需求:
			1. 修改1號資料的 salary 為 10000
			2. 添加一條記錄
			3. 洗掉剛才添加的記錄
			4. 查詢id為1001的記錄,將其封裝為Map集合
			5. 查詢所有記錄,將其封裝為List
			6. 查詢所有記錄,將其封裝為Emp物件的List集合
			7. 查詢總記錄數

		* 代碼:
			
			import cn.itcast.domain.Emp;
			import cn.itcast.utils.JDBCUtils;
			import org.junit.Test;
			import org.springframework.jdbc.core.BeanPropertyRowMapper;
			import org.springframework.jdbc.core.JdbcTemplate;
			import org.springframework.jdbc.core.RowMapper;
			
			import java.sql.Date;
			import java.sql.ResultSet;
			import java.sql.SQLException;
			import java.util.List;
			import java.util.Map;
			
			public class JdbcTemplateDemo2 {
			
			    //Junit單元測驗,可以讓方法獨立執行
			
			
			    //1. 獲取JDBCTemplate物件
			    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
			    /**
			     * 1. 修改1號資料的 salary 為 10000
			     */
			    @Test
			    public void test1(){
			
			        //2. 定義sql
			        String sql = "update emp set salary = 10000 where id = 1001";
			        //3. 執行sql
			        int count = template.update(sql);
			        System.out.println(count);
			    }
			
			    /**
			     * 2. 添加一條記錄
			     */
			    @Test
			    public void test2(){
			        String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
			        int count = template.update(sql, 1015, "郭靖", 10);
			        System.out.println(count);
			
			    }
			
			    /**
			     * 3.洗掉剛才添加的記錄
			     */
			    @Test
			    public void test3(){
			        String sql = "delete from emp where id = ?";
			        int count = template.update(sql, 1015);
			        System.out.println(count);
			    }
			
			    /**
			     * 4.查詢id為1001的記錄,將其封裝為Map集合
			     * 注意:這個方法查詢的結果集長度只能是1,若查詢長度大于1則會報錯
			     */
			    @Test
			    public void test4(){
			        String sql = "select * from emp where id = ?";
			        Map<String, Object> map = template.queryForMap(sql, 1001);
			        System.out.println(map);
			        //{id=1001, ename=孫悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
			    }

			
			    /**
			     * 5. 查詢所有記錄,將其封裝為List
			     */
			    @Test
			    public void test5(){
			        String sql = "select * from emp";
			        List<Map<String, Object>> list = template.queryForList(sql);
			
			        for (Map<String, Object> stringObjectMap : list) {
			            System.out.println(stringObjectMap);
			        }
			    }
			
			    /**
			     * 6. 查詢所有記錄,將其封裝為Emp物件的List集合
			     */
			
			    @Test
			    public void test6(){
			        String sql = "select * from emp";
			        List<Emp> list = template.query(sql, new RowMapper<Emp>() {
			
			            @Override
			            public Emp mapRow(ResultSet rs, int i) throws SQLException {
			                Emp emp = new Emp();
			                int id = rs.getInt("id");
			                String ename = rs.getString("ename");
			                int job_id = rs.getInt("job_id");
			                int mgr = rs.getInt("mgr");
			                Date joindate = rs.getDate("joindate");
			                double salary = rs.getDouble("salary");
			                double bonus = rs.getDouble("bonus");
			                int dept_id = rs.getInt("dept_id");
			
			                emp.setId(id);
			                emp.setEname(ename);
			                emp.setJob_id(job_id);
			                emp.setMgr(mgr);
			                emp.setJoindate(joindate);
			                emp.setSalary(salary);
			                emp.setBonus(bonus);
			                emp.setDept_id(dept_id);
			
			                return emp;
			            }
			        });
			
			
			        for (Emp emp : list) {
			            System.out.println(emp);
			        }
			    }
			
			    /**
			     * 6. 查詢所有記錄,將其封裝為Emp物件的List集合
			     */
				//此方法需要類中定義的屬性改為參考資料型別,否則會報錯
			    @Test
			    public void test6_2(){
			        String sql = "select * from emp";
			        List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
			        for (Emp emp : list) {
			            System.out.println(emp);
			        }
			    }
			
			    /**
			     * 7. 查詢總記錄數
			     */
			
			    @Test
			    public void test7(){
			        String sql = "select count(id) from emp";
			        Long total = template.queryForObject(sql, Long.class);
			        System.out.println(total);
			    }		
			}

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/81222.html

標籤:MySQL

上一篇:使用JDBC獲取資料庫中的一條記錄并封裝為Bean

下一篇:掌握這13個MySQL索引知識點,讓你面試通過率翻倍

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more