第一步建表:
第二步:編寫product表的實體類
public class produce { private int id; private String name; private String price; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the price */ public String getPrice() { return price; } /** * @param price the price to set */ public void setPrice(String price) { this.price = price; } }
第三步:編寫productDao,完成基本的常見操作。
這立即有個問題,我們想要使用的是Spring的JdbcTemplate來操作數據庫,那么我們應該在productDao類注入JdebcTemplate,我們想到的方式是定義一個成員變量,然后
注入,但是Spring 已經為我們考慮了這種情況,所以提供了一個JdbcDaoSupport類來幫助我們。這個類里面提供了setjdbcTempalte這樣的方法。
/* * 我們要用Spring的JDBC模板(JdbcTemplate)第一想法是在這個類中 * 定義一個成員變量,然后用set方法,用Spring去注入。但是Spring已經為我們 * 考慮好了這個情況。我們不需要自己去寫什么setJdbcTemplate這個方法,只要去 * 繼承jdbcDaoSupport這個類就可以了。在這個類里面已經有了setJdbcTemplate這個方法。 * */ public class ProductDao extends JdbcDaoSupport {
//增
public void save(produce produce1 )
{
String sql="insert into product values(null,?,?)";
this.getJdbcTemplate().update(sql, produce1.getName(),produce1.getPrice());
}
//改
public void update(produce produce1)
{
String sql="update product set name=?,price=? where id=?";
this.getJdbcTemplate().update(sql, produce1.getName(),produce1.getPrice(),produce1.getId());
}
//刪
public void delete( produce produce1)
{String sql="delete from product where id=?";
this.getJdbcTemplate().update(sql, produce1.getId());
}
}
第四步:配置Spring的ApplicationContext.xml文件。
<!-- 引入peoperties文件 --> <!-- <context:property-placeholder location="classpath:db.properties"/> --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="classpath:db.properties"/> </bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driver}"/> <property name="jdbcUrl" value="${url}"></property> <property name="user" value="${username}"></property> <property name="password" value="${password}"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 給 ProductDao的父類里面的jdbcTemplate注入值--> <bean id="ProductDao" class="cn.itcast.spring.c_jdbc.ProductDao"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean>
第五步:編寫Junit測試代碼
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class ProductTest { @Autowired private ProductDao productDao; //@Test public void testsave() { produce produce1=new produce(); produce1.setName("愛"); produce1.setPrice("100"); this.productDao.save(produce1); } //@Test public void testupdate() { produce produce2=new produce(); produce2.setId(1); produce2.setName("愛2"); produce2.setPrice("200"); this.productDao.update(produce2); } @Test public void testdelete() { produce produce1Produce=new produce(); produce1Produce.setId(2); this.productDao.delete(produce1Produce); } }
上面對增刪改都講解了,下面對查找單獨拿出來講解。查找分為兩塊講解,簡單的查找和復雜的查找。
簡單的查找:
如果返回結果 是一個簡單值,使用jdbcTemplate 提供 queryForXXX 方法
比如:queryForInt 返回結果是int
queryForLong 返回結果是long
queryForObject 返回結果是Object (返回String )
針對上面三種方法,分別寫兩個方法。
查找商品的數量和查找商品的名字
//查找商品的數量 public long findTotleCount() { String sql="select count(*) from produce"; return this.getJdbcTemplate().queryForLong(sql); } //查找商品的名稱 public String findNamebyId(int id) { String sql="select name from product where id=?"; return this.getJdbcTemplate().queryForObject(sql, String.class, id); }
在Junit中編寫相應的測試代碼:
//測試查找商品的名稱
//@Test public void testfindNameById() { String name=this.productDao.findNamebyId(1); System.out.print(name); }
//測試查找商品的總數 @Test public void testTotleCount() { long count=this.productDao.findTotleCount(); System.out.print("aaaaaaa"+count); }
結果:輸出都是對的。
題外話:
通用的多表查詢其實有個致命的缺點。以馬成老師的DataBaseClass類為例。這個類有一個致命的缺點,那就是在多表查詢的時候,比如
select * from custom,order where custom.orderid=orider.id and custom.id=? 這里涉及到兩張表,查詢得到的字段有兩張表的所有的字段。那么就有一個問題了。
我並沒有針對兩個表的字段的實體類啊,為了這個我還要重新創建對應的實體類,萬一我以后的字段在少一個,那不是要經常改變了啊。這就是他的致命缺點。
但是Hibernate就很好的解決了這個問題。因為Hibernate中每個實體類都有相應的.hbm.xml所以查出來的結果都是保存在各自的實體類中的。
復雜查詢放在最后講:
復雜查詢返回對象:
JdbcTemplate 並沒有提供 像Apache DbUtils框架 那樣Handler ,而是需要手動封裝結果集(就是說我們要自己從數據庫把一個一個數據拿出來,
自己再把它封裝成一個對象。)
------------ 通常企業開發中, 開發人員會為每個表,編寫單獨結果集封裝程序 (RowMapper)
所以我們要自己手動封裝結果集(RowMapper)。注意用了RowMapper,我們只要關心一行數據的每一個值的封裝,不要關心怎么換行。
rs.next()什么的,都不用我們關心。
第一步:先寫一個內部類繼承RowMapper<>
第二步:再寫相應的查找結果的方法。
//第一步: private class ProductRowMapper implements RowMapper<produce> { public produce mapRow(ResultSet rs, int rowNum) throws SQLException { produce produce1=new produce(); produce1.setId(rs.getInt("id")); produce1.setName(rs.getString("name")); produce1.setPrice(rs.getString("price")); return produce1; } } //第二步:根據id把數據庫中的其中一個product對象找出來持久化。 public produce findproduceById(int id) { String sql="select * from product where id=?"; return this.getJdbcTemplate().queryForObject(sql, new ProductRowMapper(),id); }
第三步:編寫Junit測試代碼:
@Test public void testfindProduct() { produce produce1=this.productDao.findproduceById(1); //測試得到的結果是不是對的 System.out.print(produce1.getId()+produce1.getName()+produce1.getPrice()); }
結果:對的。
這里最核心的就是RowMapper。
