Spring JdbcTemplate增強:JdbcTemplateTool

jopen 10年前發布 | 78K 次閱讀 Spring JEE框架 JdbcTemplateTool

Spring 出品的 JdbcTemplate 對于不想使用hibernate或者ibatis那樣需要大量學習成本而且還想獲得對象化的人來說是很好用的。但是 JdbcTemplate還是有很多不足之處或者說是缺點。比如你沒法像hibernate那樣直接傳一個對象給它讓他拆分成sql并保存起來,當然這也是可以理解的,畢竟它并沒有要求你去寫 hbm.xml 文件所以無法知道你哪些字段要映射,哪些不要等等。又比如JdbcTemplate 可以幫忙把一個查詢結果傳化為一個對象列表,但是你需要查閱一些資料才知道要用 BeanPropertyRowMapper 。如果下次要用的時候又忘記了這個類,又要查一次或者翻以前的代碼來看,其實完全可以提供一個方法直接傳一個PO類進去自動創建BeanPropertyRowMapper 。基于以上的一些不足之處,我建立了 JdbcTemplateTool 它有以下特性:

  • 把查詢結果轉換為PO列表,不需要調用BeanPropertyRowMapper

  • 傳一條統計sql比如 aselect count(1) from table可以直接返回一個數字作為結果,不需要自己實現中間步驟。

  • 可以直接把一個PO類存到數據庫

  • 通過PO類和一個id可以獲取到該對象

  • 通過PO類可以直接update數據庫記錄

  • 不需要實現 BatchPreparedStatementSetter, 就可以批量update

  • 通過一個對PO對象刪除對應的數據庫記錄

  • 依然可以使用原始的JdbcTemplate

目前只在mysql上測試.

Maven 依賴

<dependency>
  <groupId>org.crazycake</groupId>
  <artifactId>jdbctemplatetool</artifactId>
  <version>1.0.4-RELEASE</version>
</dependency>

快速開始

STEP 1. 創建一個maven項目

    創建一個maven項目叫testjtt. 添加jdbctemplatetool 依賴到pom.xml. 再添加以下依賴到 pom.xml.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.2.2.RELEASE</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.2.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.19</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>3.2.2.RELEASE</version>
    <scope>test</scope>
</dependency>


最好使用 1.6+ jdk. 我并沒有在 1.5 下測試

STEP 2. 創建測試數據庫

    創建一個測試的數據庫叫jtt_test創建一個用戶travis不要分配密碼. 賦予jtt_test的權限給travis.

CREATE USER 'travis'@'%' IDENTIFIED BY '';
GRANT ALL ON jtt_test.* TO 'travis'@'%';
flush privileges;

創建一張表employee插入一些測試數據.

DROP TABLE IF EXISTS `employee`;

CREATE TABLE `employee` (
  `id` int(11) NOT NULL,
  `name` varchar(300) NOT NULL,
  `join_date` datetime NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `employee` */

insert  into `employee`(`id`,`name`,`join_date`,`age`) values (1,'jack','2014-09-22 00:00:00',23),(2,'ted','2014-08-30 00:00:00',25),(3,'jim','2014-06-22 00:00:00',33);

STEP 3. 配置一下spring

    在test文件夾下創建resources文件夾. 添加resources到 source folder 修改輸出為target/test-classes創建spring.xml在 test/resources 里面

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="jdbcUrl"><value>jdbc:mysql://localhost:3306/jtt_test?characterEncoding=utf8</value></property>
        <property name="driverClass"><value>com.mysql.jdbc.Driver</value></property>
        <property name="user"><value>travis</value></property>
        <property name="password"><value></value></property>
    </bean>

    <bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate">   
         <property name = "dataSource" ref="dataSource"/>   
    </bean>

    <bean id="jdbcTemplateTool" class="org.crazycake.jdbcTemplateTool.JdbcTemplateTool">
        <property name = "jdbcTemplate" ref="jdbcTemplate" />
    </bean>
</beans>

STEP 4. 創建PO類

    創建Employee.java

import java.sql.Timestamp;
import javax.persistence.Id;

public class Employee {

    private Integer id;
    private String name;
    private Timestamp joinDate;
    private Integer age;

    @Id
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Timestamp getJoinDate() {
        return joinDate;
    }
    public void setJoinDate(Timestamp joinDate) {
        this.joinDate = joinDate;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

STEP 5. 創建測試用例

    創建HelloJTTTest.java

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import java.util.List;

import org.crazycake.jdbcTemplateTool.JdbcTemplateTool;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations={"classpath:spring.xml"})
public class HelloJTTTest extends AbstractJUnit4SpringContextTests{

    @Test
    public void testSave(){
        JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);

        Employee e = new Employee();
        e.setId(4);
        e.setName("billy");
        Date now = new Date();
        e.setJoinDate(new Timestamp(now.getTime()));
        e.setAge(33);

        try {
            jtt.save(e);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

STEP 6. 啟動!

    運行測試用例,等待綠色條。然后去數據庫會看到多了一條記錄 :

id name join_date age
4 billy 2014-09-24 22:51:20 33

高級教程

    以下是各個方法的詳細介紹

list

把查詢結果轉換為PO列表,不需要調用BeanPropertyRowMapper。 自動根據數據庫的列將下劃線轉為駝峰命名規則映射類的屬性.

@Test
public void testList(){
    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);
    List<Employee> es = jtt.list("select * from employee where age < ? order by id desc", new Object[]{30}, Employee.class);

    assertThat(new Integer(es.size()),is(2));
    assertThat(es.get(1).getName(),is("jack"));
}

count

    傳一條統計sql比如 aselect count(1) from table可以直接返回一個數字作為結果,不需要自己實現中間步驟。

@Test
public void testCount() throws IOException, SQLException {

    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);
    int total = jtt.count("select count(1) from employee", null);
    assertThat(total,is(4));
    }

save

可以直接把一個PO類存到數據庫。如果你不想把某個列映射為數據庫字段可以使用 @Trasient 注解在getter上

public class Student {

    private Integer id;
    private String name;
    private String nothing;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Transient
    public String getNothing() {
        return nothing;
    }
    public void setNothing(String nothing) {
        this.nothing = nothing;
    }
}

這個字段會被跳過

@Test
public void testSave() throws Exception {

    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);

    Student s = new Student();
    s.setName("michael");
    s.setNothing("nothing");
    jtt.save(s);
}

get

    通過PO類和一個id可以獲取到該對象。但是前提是需要在主鍵的getter上標上 @Id 注解

@Id
public Integer getId() {
    return id;
}

例子

@Test
public void testGet() throws NoIdAnnotationFoundException, NoColumnAnnotationFoundException, IOException, SQLException {

    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);

    Employee e = jtt.get(Employee.class, 3);
    assertThat(e.getName(),is("jim"));
}

update

    自動根據PO類更新數據庫. 記得增加@Id.

@Test
public void testUpdate() throws Exception {

    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);

    Employee e = jtt.get(Employee.class, 1);
    e.setAge(23);
    jtt.update(e);
}

batchUpdate

    批量更新

@Test
public void testBatchUpdate() throws SQLException, IOException {
    build();

    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);

    List<Object[]> params = new ArrayList<Object[]>();
    Object[] p1 = new Object[]{23,"jack"};
    params.add(p1);
    Object[] p2 = new Object[]{29,"tim"};
    params.add(p2);

    jtt.batchUpdate("update employee set age = ? where name = ?", params);

}

delete

    刪除數據庫對象

@Test
public void testDelete() throws Exception {
    JdbcTemplateTool jtt = super.applicationContext.getBean("jdbcTemplateTool",JdbcTemplateTool.class);
    Employee e = new Employee();
    e.setId(1);
    jtt.delete(e);
}

getJdbcTemplate

    你依然可以使用原始的JdbcTemplate. 調用JdbcTemplateTool.getJdbcTemplate()to getJdbcTemplate就可以了。

項目主頁:http://www.baiduhome.net/lib/view/home/1411716502234

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!