Spring(七)持久層


一、Spring對DAO的支持

 DAO:Data Access Object

Spring提供了DAO框架,讓開發人員無須耦合特定的數據庫技術,就能進行應用程序的開發。

Spring封閉了操作Oracle,MySql,DB2,SQL等數據庫的用法。

它們都實現同一接口,方法也是一樣的。

優勢:

由於依賴於接口,可以通過依賴注入隨時替換DAO接口的實現類,而應用程序完全不用了解接口與底層數據庫操作細節。

應用程序----調用-----》DAO接口《---實現--DAO接口實現類----操作------》數據庫

二、Spring注入數據源

2.1、 DataSource(數據源)

連接數據的方式稱為“數據庫”。比如JDBC,連接池或者JNDI

Spring通過依賴注入方式配置數據源

不同系統,數據源的管理更多是針對底層的行為,這些行為不應該影響業務。

更換數據只需修改Bean定義的內容,而不需要修改任何一行代碼。

2.2、配置數據源

applicationContext.xml配置數據源

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!--數據源  -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--URL  -->
<property name="url" value="jdbc:oracl:thin:@localhost:1521:orcl"/>
<!--連接的用戶名  -->
<property name="username" value="accp"></property>
<!--連接的密碼  -->
<property name="password" value="accp"></property>
</bean>

</beans>

 JDBC操作:

package com.pb.jdbc.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.pb.entity.Person;
import com.pb.jdbc.dao.PersonDao;

public class PersonDaoImpl implements PersonDao {
    private DataSource dataSource;
    @Override
    public Person findById(Integer id) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Person p=null;
        String sql="select * from person where id=?";
        Object [] params={id};
        //獲取連接
        try {
            con=dataSource.getConnection();
            ps=con.prepareStatement(sql);
            if(params!=null){
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            }
            rs=ps.executeQuery();
            if(rs!=null){
                p=new Person();
                while(rs.next()){
                    p.setId(rs.getInt("id"));
                    p.setName(rs.getString("name"));
                    p.setAge(rs.getInt("age"));
                }
            }
            return p;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            
                try {
                    if(rs!=null)
                    rs.close();
                    if(ps!=null)
                        ps.close();
                    if(con!=null)
                        con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
        
        
        return null;
    }
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

}

更新applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!--數據源  -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--URL  -->
<property name="url" value="jdbc:oracl:thin:@localhost:1521:orcl"/>
<!--連接的用戶名  -->
<property name="username" value="accp"></property>
<!--連接的密碼  -->
<property name="password" value="accp"></property>
</bean>
<!-- PersonDao接口實現類 -->
<bean id="personDaoImpl" class="com.pb.jdbc.dao.impl.PersonDaoImpl">
<!-- 屬性關聯 -->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>

 

三、JDBC Template

 為什么需要JDBCTemplate(JDBC模板)?

使用JDBC時,總是需要進行固定的步驟,比如Connection,Statement的獲取、關閉,異常處理等。

JDBCTemplate作用:

Spring將JDBC常用的操作封裝到JDBCTemplate中簡化了使用JDBC的開發流程,開發人員不需要關心,獲得連接和關閉連接

更改上面的代碼

package com.pb.jdbc.dao.impl;


import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

import com.pb.entity.Person;
import com.pb.jdbc.dao.PersonDao;

public class JdbcTemplatePersonDaoImpl implements PersonDao {
    private JdbcTemplate jdbcTemplate;
    //根據ID查找
    @Override
    public Person findById(Integer id) {
        Person p=null;
        //返回的是集合,但集合的每個元素都是一個map
        String sql="select * from person where id=?";
        //占位符
        Object [] params={id};
        //調用SQL和占位
        List results=jdbcTemplate.queryForList(sql,params);
        for (Object object : results) {
            Map personMap=(Map) object;
            //獲取每個map的值
            Long p_id=((BigDecimal) personMap.get("ID")).longValue();
            String p_name=(String) personMap.get("NAME");
            Integer p_age=((BigDecimal) personMap.get("AGE")).intValue();
            
            //聲明
            p=new Person();
            p.setAge(p_age);
            p.setId(p_id);
            p.setName(p_name);
        }
        
        return p;
    }
    //通過設置數據獲取JdbcTemplate的實例
    public void setDataSource(DataSource dataSource) {
        jdbcTemplate=new JdbcTemplate(dataSource);
    }

}

 

四、JDBC Template

要使用Jdbctemplate 對象來完成jdbc 操作。通常情況下,有三種種方式得到JdbcTemplate 對象。 

  •       第一種方式:我們可以在自己定義的DAO 實現類中注入一個DataSource 引用來完 成JdbcTemplate 的實例化。也就是它是從外部“注入” DataSource   到DAO 中,然后 自己實例化JdbcTemplate,然后將DataSource 設置到JdbcTemplate 對象中。 
  •       第二種方式: 在 Spring 的 IoC 容器中配置一個 JdbcTemplate 的 bean,將 DataSource 注入進來,然后再把JdbcTemplate 注入到自定義DAO 中。 
  •       第三種方式: Spring 提供了 org.springframework.jdbc.core.support.JdbcDaoSupport 類 , 這 個 類 中 定 義 了 JdbcTemplate 屬性,也定義了DataSource 屬性,當設置DataSource 屬性的時候,會創 建jdbcTemplate 的實例,所以我們自己編寫的DAO 只需要繼承JdbcDaoSupport 類, 然后注入DataSource 即可

 第一種

public class UserServiceImpl implements UserService {  
  
    private JdbcTemplate jdbcTemplate;  
      
    public JdbcTemplate getJdbcTemplate() {  
        return jdbcTemplate;  
    }  
  
                //注入方法1     
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
        this.jdbcTemplate = jdbcTemplate;  
    }  
  
               //其它方法這里省略……  
}  

application.xml   前提是已經配置了dataSource 2.2配置數據源

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name = "dataSource" ref="dataSource">  
</bean>  
<bean id="userService" class="com.hxzy.account.jdbcTemplate.UserServiceImpl">  
     <property name="jdbcTemplate" ref="jdbcTemplate"/>  
</bean>  

第二種 通過數據庫實例化JdbcTemplate

public class UserServiceImpl implements UserService {  
  
        private JdbcTemplate jdbcTemplate;  
          
        //注入方法2  
        public void setDataSource(DataSource dataSource) {  
                   this.jdbcTemplate = new JdbcTemplate(dataSource);  
        }  
       
       //其它方法省略……  
}  

applicationContext.xml

前提是已經配置了dataSource  2.2配置數據源

spring配置文件為:

Xml代碼  
<bean id="userService" class="com.hxzy.account.jdbcTemplate.UserServiceImpl">  
       <property name="dataSource" ref="dataSource"/>  
</bean>  

第三種:

繼承JdbcDaoSupport,其內部有個JdbcTemplate ,需要注入DataSource 屬性來實例化。

public class UserDaoImpl extends JdbcDaoSupport implements UserDao {  
  
    @Override  
    public void save(User user) {  
        String sql = null;  
        this.getJdbcTemplate().update(sql);  
    }  
        //其它方法省略……  
}  

xml

<bean id="userDao" class="com.hxzy.account.jdbcTemplate.UserDaoImpl">  
           <property name="dataSource" ref="dataSource"/>  
</bean>  

 

五、JDBC Template操作數據庫

 執行DDL與更新

  • 使用JdbcTemplate的execute()方法可以執行DDL語句
  • 執行update或者inert,可以使用update()方法;

 

package com.pb.demo;



import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
/**
 * 1.JdbcTemplate queryForXxx方法執行SQL語句
 * 2. query和update都可以使用占位符
 * 3. 返回的List中的元素為map 
 * 4.使用update執行更新操作
 * 5.使用execute方法執行DDL操作
 */
public class JdbcTemplateDemo {

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        //獲取數據源
        DataSource dataSource=context.getBean("dataSource",DataSource.class);
        //通過數據源實例JdbcTemplate
        JdbcTemplate jt=new JdbcTemplate(dataSource);
        
        //執行占位符的查詢語句
        String sql_v="select * from person where name=? and age=?";
        Object [] params={"李四",24};
        //傳入參數
        List result=jt.queryForList(sql_v,params);
        for (Object object : result) {
            //直接輸出對象
            System.out.println(object);
            //或者輸出值
            Map map=(Map)object;
            System.out.println("ID: "+map.get("ID")+"姓名:"+map.get("NAME")+map.get("AGE"));
        }
        //更新
        String sql_update="update person set  name=? where age=?";
        //年齡為23的都更新為張小三
        Object [] pupdate={"張小三",23};
        //數據庫受影響的行數
        int count=jt.update(sql_update, pupdate);
        System.out.println("更新了"+count+"行");
            //查詢總記錄數
        String sql_count="select count(*) from person";
        int totalcount=jt.queryForInt(sql_count);
        System.out.println("Person表的總記錄數:  "+totalcount);
        //執行DDL語句
        //創建一張表
        String ddl="create table test(id number(4) primary key,name varchar2(50))";
        jt.execute(ddl);
        System.out.println("創建表 成功");
        //刪除表
        String del_table="drop table test";
        jt.execute(del_table);
        System.out.println("刪除表成功");
        
        
    }

}

配置數據如:2.2

 

package com.pb.demo;



import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
/**
 * 使用批量處理數據
 */
public class JdbcTemplateDemo2 {

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        //獲取數據源
        DataSource dataSource=context.getBean("dataSource",DataSource.class);
        //通過數據源實例JdbcTemplate
        JdbcTemplate jt=new JdbcTemplate(dataSource);
    
        //批量插入數據
        final int count=200;
        final List id=new ArrayList();
        final List name=new ArrayList();
        final List password=new ArrayList();
        //為集合調定值
        for (int i = 0; i < count; i++) {
            id.add(i);
            name.add("name_"+i);
            password.add("password_"+i);
            
        }
        
        //指處理數據
        String sql="insert into users values(?,?,?)";
        BatchPreparedStatementSetter bps=new BatchPreparedStatementSetter() {
            
            @Override
            public void setValues(PreparedStatement ps, int index) throws SQLException {
                ps.setObject(1, id.get(index));
                ps.setObject(2, name.get(index));
                ps.setObject(3, password.get(index));
                
            }
            
            @Override
            public int getBatchSize() {
    
                return count;
            }
        };
        //執行插入
        jt.batchUpdate(sql, bps);
        System.out.println("插入完成!");
        
    }

}

六、JDBC Template以對象方 式操作數據庫

執行函數的類繼承:

sqlfunction

package com.pb.object;



import javax.sql.DataSource;

import org.springframework.jdbc.object.SqlFunction;
/**
 * 執行函數
 *
 */
public class PersonFunction extends SqlFunction{
    public PersonFunction(DataSource ds){
        //初始化
        super(ds,"select count(*) from person");
        //編譯
        compile();
    }

}

執行增加或者更新的類繼承sqlupdate

package com.pb.object;

import java.sql.Types;

import javax.sql.DataSource;

import org.springframework.jdbc.object.SqlUpdate;
/**
 * 執行增加或者更新
 *
 */
public class PersonUpdate extends SqlUpdate {
    public PersonUpdate(DataSource ds){
        super(ds,"insert into person values(?,?,?)");
        //設置參數為Oracle中的數據
        int [] types={Types.BIGINT,Types.VARCHAR,Types.INTEGER};
        //設置參數
        setTypes(types);
        compile();
        
    }
}

執行查詢的類繼承MappingSqlQuery

package com.pb.object;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.jdbc.object.MappingSqlQuery;

import com.pb.entity.Person;
/**
 * 對象查詢
 * @author Administrator
 *
 */
public class PersonQuery extends MappingSqlQuery {
    public PersonQuery(DataSource ds){
        super(ds,"select * from person");
        compile();
    }

    @Override
    protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
        Person p=new Person();
        p.setAge(rs.getInt("age"));
        p.setId(rs.getLong("id"));
        p.setName(rs.getString("name"));
        
        return p;
    }

}

實現類和接口

package com.pb.dao;



import java.util.List;

import com.pb.entity.Person;

public interface PersonDao {
    //查詢全部
    public List<Person> find();
    //增加
    public void update(Person p);
    //查詢總記錄數
    public int getCount();
    
    
    
    
    
}

實現類

package com.pb.dao.impl;

import java.util.List;

import javax.sql.DataSource;

import com.pb.dao.PersonDao;
import com.pb.entity.Person;
import com.pb.object.PersonFunction;
import com.pb.object.PersonQuery;
import com.pb.object.PersonUpdate;

public class ObjectPersonDaoImpl implements PersonDao {
    //3個實現類
    private PersonFunction pf=null;  //執行函數
    private PersonQuery pq=null; //執行查詢
    private PersonUpdate pu=null; //執行更新
    
    /*
     *通過注入數據源實例化對象 
     *
     */
    public void setDataSource(DataSource ds){
        pf=new PersonFunction(ds);
        pq=new PersonQuery(ds);
        pu=new PersonUpdate(ds);
    }
    
    
    @Override
    public List<Person> find() {
        
        return pq.execute();
    }

    @Override
    public void update(Person p) {
        //傳入參數
        pu.update(p.getId(),p.getName(),p.getAge());

    }

    @Override
    public int getCount() {
        //函數使用run運行調用
        return pf.run();
    }

}

applicationContext.xml

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

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="username" value="accp"/>
<property name="password" value="accp"/>
</bean>
<bean id="objectPersonDao" class="com.pb.dao.impl.ObjectPersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

 

 

測試類

package com.pb.demo;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.pb.dao.PersonDao;
import com.pb.entity.Person;

public class TestObjectJdbc {


    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        
        PersonDao opd=context.getBean("objectPersonDao",PersonDao.class);
        Person p=new Person();
        p.setAge(99);
        p.setId(7);
        p.setName("滅絕師太");
        
        opd.update(p);
        
        List<Person> persons=opd.find();
        
        //調用查詢總記錄數的方法
        System.out.println("總記錄數:"+opd.getCount());
        for (Person per : persons) {
            System.out.println("ID:"+per.getId()+"姓名:"+per.getName()+" 年齡:"+per.getAge());
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM