1. 程式人生 > >資料庫元資料、jdbcTemplate

資料庫元資料、jdbcTemplate

資料庫元資料

什麼是元資料:

  • 用來定義資料庫,資料表的資料。

JDBC中元資料的分類

三種元資料 如何得到元資料
資料庫元資料 通過Connection物件獲取
引數元資料 通過PreparedStatement物件獲取
結果集元資料 通過ResultSet物件獲取
  • 所有的元資料都被封裝成了類的物件。

什麼是資料庫的元資料:

  • 描述資料庫表的列名,屬性型別,結果集的資料,為了更好理解別人資料庫工具類底層的原理。

引數元資料:ParameterMetaData

ParameterMetaData物件的作用:

  1. 獲得佔位符問號的個數。
  2. 佔位符?的資料型別。

通過PrepareStatement物件的方法:

ParameterMetaData getParameterMetaData()

  • 獲取ParameterMetaData物件

ParameterMetaData介面常用方法:

int getParameterCount()

  • 獲得引數的個數(佔位符問號的個數)。

String getParameterTypeName(int param) 

  • 獲得指定位置引數的資料型別。從1開始。
  • 預設情況下:因為MySQL驅動的原因,不支援得到引數元資料的型別。

示例程式碼:

public class ParamterMetaDataDemo01 {
public static void main(String[] args) throws Exception {
// 獲得連線物件
Connection conn = DruidDataSourceUtils.getConnection();
// 獲得預編譯物件
PreparedStatement ps = conn.prepareStatement("insert into " +
"student values(null,?,?,?)");
// 給佔位符引數賦值
ps.setString(1, "⼩澤");
ps.setString(2, "⼥");
ps.setDate(3, Date.valueOf("1999-10-20"));
// 獲得引數元資料物件
ParameterMetaData pmd = ps.getParameterMetaData();
// 獲得引數的個數
int count = pmd.getParameterCount();
System.out.println("引數個數:" + count);
// 獲得指定位置引數的資料型別
String typeName = pmd.getParameterTypeName(3);
System.out.println("引數型別:" + typeName);
// 執行Sql語句
int row = ps.executeUpdate();
System.out.println(row);
// 關閉資源
DruidDataSourceUtils.close(ps, conn);
}
}

ResultSetMetaData

ResultSetMetaData結果集元資料的作用:

  1. 用來獲得結果集中的列數。
  2. 用來獲得列的資料型別。
  3. 用來獲得列的名字。

通過ResultSet物件的方法:

ResultSetMetaData getMetaData()

  • 獲得ResultSetMetaData物件。

ResultSetMetaData類常用方法:

int getColumnCount()

  • 獲得列的數量。

String getColumnName(int column) 

  • 獲得指定列的列名。

String getColumnTypeName(int column)

  • 獲得指定列的型別名稱。

示例程式碼:

public class ResultSetMetaDemoDemo01 {
public static void main(String[] args)throws Exception{
// 獲得連線物件
Connection conn = DruidDataSourceUtils.getConnection();
// 獲得預編譯物件
PreparedStatement ps = conn.prepareStatement("SELECT * FROM student;");
// 執行查詢操作並獲得結果集物件
ResultSet rs = ps.executeQuery();
// 獲得結果集元資料物件
ResultSetMetaData rsm = rs.getMetaData();
System.out.println("總列數:" + rsm.getColumnCount());
int colums = rsm.getColumnCount();
for (int i = 1; i <= colums; i++) {
System.out.println("列名:" + rsm.getColumnName(i));
System.out.println("列的型別:" + rsm.getColumnTypeName(i));
}
// 關閉資源
DruidDataSourceUtils.close(rs,ps,conn);
}
}

JdbcTemplate

概述:

  1. JdbcTemplate就是Spring對JDBC的封裝,目的是使JDBC更加易於使用。JdbcTemplate是Spring的一部分。
  2. 處理了資源的建立和釋放。

JdbcTemplate的好處:

  1. 不需要我們管理連線了。
  2. 不需要我們設定引數了。
  3. 查詢時候可以直接返回對應的實體類。

JdbcTemplate的使用步驟:

  1. 匯入jdbcTemplate的5個jar包。
  2. 建立JdbcTemplate物件,傳入Druid連線池。
  3. 呼叫execute、update、queryXxx等方法。

如何建立JDBCTemplate的核心類:JdbcTemplate

public JdbcTemplate( DataSource dataSource );

  • 建立JdbcTemplate物件,方便執行SQL語句。

JdbcTemplate實現建立表:

public void execute( String sql );

  • execute可以執行所有SQL語句,因為沒有返回值,一般用於執行DDL語句。  

示例程式碼:

public class JDBCTemplateDemo01 {
public static void main(String[] args){
// 建立JDBCTemplate物件
JdbcTemplate jt = new JdbcTemplate(DruidDataSourceUtils.getDataSource());
// 執行SQL語句句
jt.execute("CREATE table product(id int primary key auto_increment," +
"pname varchar(20)," +
"price double);");
}
}

Jdbctemplate實現增刪改:

int update(String sql,Object...params);

  • 用於執行增刪改等DML語句。

總結:

JdbcTemplate的update方法用於執行DML語句。同時還可以在SQL語句中使用佔位,在update方法的object...args可變引數中傳入對應的引數。

JdbcTemplate實現查詢

注意事項:

  • ​​​​​​​queryForObject與queryForMap如果查詢不到結果,都會出現異常。我們需要抓取異常。
  • 異常是:EmptyResultDataAccessException

queryForObject查詢單個欄位

public <T> T queryForObject(String sql, Class<T> requiredType ,Object...params)

  • 執行查詢語句,返回一個指定型別的資料。

​​​​​​​引數說明:

  • sql:執行的sql語句。
  • requiredType:查詢結果的型別。
  • params:sql需要的引數。

queryForMap查詢單個物件

public Map<String, Object> queryForMap(String sql,Object...args)

  • queryForMap會把一行的資料儲存到Map物件中,一個Map物件就儲存一行記錄,key儲存的是列名,value是儲存該行資料的值。

拓展

  • 查詢多個表返回一條記錄使用Map封裝結果。

示例程式碼:

public Route findRouteByRid(String rid) throws Exception {
        Map<String,Object> map = routeDao.findRouteByRid(rid);
        List<RouteImg> list = routeDao.findRouteImgsByRid(rid);
        Route route = new Route();
        Category category = new Category();
        Seller seller = new Seller();
        BeanUtils.populate(route,map);
        BeanUtils.populate(category,map);
        BeanUtils.populate(seller,map);
        route.setCategory(category);
        route.setSeller(seller);
        route.setRouteImgList(list);
        return route;
    }
public Map<String,Object> findRouteByRid(String rid) {
        String sql = "SELECT * FROM tab_route r,tab_category c,tab_seller s WHERE r.`cid` = c.`cid` AND r.`sid` = s.`sid` AND r.rid = ?";
        try {
            Map<String, Object> map = jdbcTemplate.queryForMap(sql, rid);
            return map;
        } catch (DataAccessException e) {
            return null;
        }
    }

queryForObject查詢單個物件

public <T> List<T> queryForObject(String sql, RowMapper<T> rowMapper,object...args)​​​​​​​

  • 返回指定的類。

queryForList查詢多個物件

  • 適用於單表查詢,也適用於多表查詢。

public List<Map<String, Object>> queryForList(String sql,object...args)

  • 執行查詢語句,返回一個List集合,List中存放的是Map型別的資料。

示例程式碼:

 public List<Map<String, Object>> findFavoriteListByPage(int uid, int start, int length) throws SQLException {
        String sql = "SELECT * FROM tab_favorite f,tab_route r WHERE f.`rid` = r.`rid` AND uid = ? ORDER BY f.`date` DESC LIMIT ?,?";
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, uid, start, length);
        return mapList;
    }
 public PageBean<Favorite> getPageBean(int uid, String curPage) throws Exception {
        int curpage = Integer.parseInt(curPage);
        PageBean<Favorite> pageBean = new PageBean<>();
        pageBean.setCurPage(curpage);
        int pageSize = 3;
        pageBean.setPageSize(pageSize);
        int count = iFavoriteDao.getCount(uid);
        pageBean.setCount(count);
        int start = (curpage-1)*pageSize;
        int length = pageSize;
        List<Map<String,Object>> mapList = iFavoriteDao.findFavoriteListByPage(uid,start,length);
        List<Favorite> list = null;
        if(mapList!=null&&mapList.size()>0){
            list = new ArrayList<>();
            for (Map<String, Object> map : mapList) {
                Favorite favorite = new Favorite();
                Route route = new Route();
                BeanUtils.populate(favorite,map);
                BeanUtils.populate(route,map);
                favorite.setRoute(route);
                list.add(favorite);
            }
        }
        pageBean.setDataList(list);
        return pageBean;
    }

query查詢多個物件,使用RowMapper做對映返回物件

  • 此重寫介面的方法,適用於多表查詢,也適用於單表查詢。

public <T> List<T> query(String sql, RowMapper<T> rowMapper,object...args)

  • 執行查詢語句,返回一個List集合,List中存放的是RowMapper指定型別的資料。
  • RowMapper的引數寫:類名

RowMapper介面的抽象方法:

mapRow( ResultSet resultSet, int i)

  • resultSet:JdbcTemplate每得到一行資料,都會直接給了resultSet物件。
  • i:當前是第幾行。

​​​​​​​在抽象方法內的具體操作:

  1. 建立實現類物件。
  2. 用ResultSet裡的值對建立的類賦值。
  3. 返回類物件。

示例程式碼:

@Test
public void test06() throws Exception {
// 建立JDBCTemplate物件
JdbcTemplate jt = new JdbcTemplate(DruidDataSourceUtils.getDataSource());
// 執⾏行行查詢操作
List<Product> products = jt.query("select * from product;", new
RowMapper<Product>() {
@Override
public Product mapRow(ResultSet rs, int i) throws SQLException {
// 建立產品物件
Product p = new Product();
// System.out.println("i = " + i);
p.setId(rs.getInt("id"));
p.setPname(rs.getString("pname"));
p.setPrice(rs.getDouble("price"));
return p;
}
});
for (Product product : products) {
System.out.println(product);
}
}

query查詢多個物件,使用BeanPropertyRowMapper做對映返回物件

  • 此用實現類實現介面的方法,適用於單表查詢,不適用於多表查詢。

​​​​​​​​​​​​​​public <T> List<T> query(String sql, RowMapper<T> rowMapper,object...args)

  • 執行查詢語句,返回一個List集合,List中存放的是RowMapper指定型別的資料。
  • RowMapper的引數寫:類名.class

​​​​​​​public class BeanPropertyRowMapper<T> implements RowMapper<T>

  • BeanPropertyRowMapper類實現了RowMapper介面

表的欄位名與實體類屬性名對映的規則:

  1. 表的欄位名與類中的屬性名相同,表的欄位名大小寫不區分。
  2. 表的欄位名如果有多個單詞使用下劃線隔開,與java中駝峰命名的屬性相對應。
  • ​​​​​​​示例:dept_name 對應  deptName

示例程式碼:

@Test
public void test07() throws Exception {
// 建立JDBCTemplate物件
JdbcTemplate jt = new JdbcTemplate(DruidDataSourceUtils.getDataSource());
// 執行查詢操作獲得List集合
List<Product> products = jt.query("select * from product where id < ?;", new
BeanPropertyRowMapper<>(Product.class),5);
for (Product product : products) {
System.out.println(product);
}
}