JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,抽象了不同数据库之间的差异。
1.使用普通的JDBC
public static void main(String[] args) {
String url="jdbc:mysql://127.0.0.1:3306/test";
String user="root";
String password="1234";
try {
//1.加载数据库驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2.获得数据库链接
Connection conn=DriverManager.getConnection(url, user, password);
//3.通过数据库的连接操作数据库,实现增删改查(使用Statement类)
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("select * from user");
//4.处理数据库的返回结果(使用ResultSet类)
while(rs.next()){
System.out.println(rs.getString("user_name")+" "
+rs.getString("user_password"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//关闭资源
rs.close();
st.close();
conn.close();
}
}
问题:
(1)上述数据访问代码散落在数据访问层的各处,不利于维护;
(2)业务逻辑与数据访问代码耦合在一起,同样也不利于维护。
(3)必须要catch SQL异常。(checked异常会强制抛给程序员处理)
2.Spring JDBC支持
2.1 JDBC连接
Spring使用DataSource来获取底层数据库的链接,Spring提供了DataSource接口的多个实现,如DriverManagerDataSource。DataSource能让我们隐藏数据库连接参数、连接池以及应用程序的事务管理问题等。
Spring JDBC支持需要spring-jdbc.jar,maven项目需要在pom.xml中添加该依赖。
以下通过基于Java的配置元数据,以及基于java的配置元数据来创建和使用Spring来获取JDBC连接。
(1)基于java的配置元数据
//配置类
@Configuration//该注解告诉Spring该类是一个Bean,并且包含配置元数据
public class XnnBeanConfiguration{
//以下是工厂方法,这些方法在启动期间被Spring容器调用,返回值被视为Spring管理的Bean
//默认情况下,方法的名称就是Bean的名称
//在工厂方法中,首先通过调用setter方法设置所需依赖,然后使用具体类创建Bean,并将其返回。
//注,(1)依赖项也可以 以构造函数参数的形式赋予;
//(2)工厂方法的返回类型一般是接口,这样可以更容易的使用不同Bean的实现类来配置系统。
//(3)默认情况下,每个Bean作用域是单实例(singleton),即工厂方法被调用多次,返回的都是同一个实例。
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
dataSource.setUserName("root");
dataSource.setPassword("1234");
return dataSource;
}
}
(2)基于java配置类创建和使用Spring,并获得JDBC连接
public class Main{
public static void Main(String[] args) throws SQLException{
//通过以下可以看到,Spring容器也是一个Java对象,并负责管理程序中的其他对象
//参数是Java配置元数据类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(XnnBeanConfiguration.class);
//查找bean
//参数1:Bean名称
//参数2:类型参数,以便找到的Bean实例转换为该类型
DataSource dataSource =applicationContext.getBean("dataSource",DataSource.class);
//获取dataSource后,就可以调用其中的方法了
Connection connection=dataSource.getConnection();
//创建Statement对象,执行SQL操作,对结果集进行处理
//关闭连接
connection.close();
}
}
注:DriverManagerDataSource 是DataSource的简单实现,DriverManagerDataSource没有连接池功能,每次调用getConnection()方法都会尝试打开一个新的物理JDBC连接。而打开JDBC连接是一个非常昂贵的过程,所以最好使用提供连接池功能的DataSource实现。
第三方连接池:C3P0、Apache Commons DBCP、Druid(阿里巴巴开源平台的数据库连接池)
2.2 配置和使用Spring JDBC支持
Spring JDBC支持的核心类JdbcTemplate。可以使用JdbcTemplate执行Sql查询、插入、更新和删除语句,在ResultSet结果集上迭代操作以及获取JDBC异常,并将其转换为Spring提供的泛型的、可提供更多信息的DataAccessException层次结构。
如何配置使用呢?
首先需要理解的是,Spring通过JdbcTemplate执行Sql查询、插入、更新和删除操作。Spring将JdbcTemplate作为Spring管理的Bean,该Bean是线程安全的,并且被不同的数据访问对象(DAO)所共享,它是单实例的,依赖一个DataSource对象。那么这就很清楚了,如何配置和使用也好理解了。
依赖关系如下:
Controller-》Service-》DAO-》JdbcTemplate-》DataSource
基于Java的配置元数据:
在配置类中增加JdbcTemplate Bean的定义,并将其做为DAO层的属性,从而在DAO实现类中就可以操作JdbcTemplate进行SQL的查询、插入、更新和删除操作。
(1)DAO实现类
public class AdDaoJDBCImpl implements AdDao {
private JdbcTemplate jdbcTemplate;
//setter注入
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate =jdbcTemplate;
}
//以下是增删查改的方法
@Override
public int insert(Ad ad) {
//插入数据库操作
}
//根据id,查询广告记录
public Ad search(long id){
return jdbcTemplate.queryForObject(
"select * from ad where id = ?",
new RowMapper<Ad>(){//匿名类,多结果集处理
@Override
public Ad mapRow(ResultSet rs, int rowNum) throws SQLEXception{
Ad ad=new Ad();
ad.setId(rs.getLong("id"));
ad.setTitle(rs.getString("title"));
//其他属性的set
return ad;
}
},id);
}
}
(2)基于Java配置
//配置类
@Configuration//该注解告诉Spring该类是一个Bean,并且包含配置元数据
public class XnnBeanConfiguration{
//以下是工厂方法,这些方法在启动期间被Spring容器调用,返回值被视为Spring管理的Bean
//默认情况下,方法的名称就是Bean的名称
//在工厂方法中,首先通过调用setter方法设置所需依赖,然后使用具体类创建Bean,并将其返回。
//注,(1)依赖项也可以 以构造函数参数的形式赋予;
//(2)工厂方法的返回类型一般是接口,这样可以更容易的使用不同Bean的实现类来配置系统。
//(3)默认情况下,每个Bean作用域是单实例(singleton),即工厂方法被调用多次,返回的都是同一个实例。
@Bean
public AdService adService(){
AdServiceImpl bean= new AdServiceImpl();
bean.setAdDao(adDao());
return bean;
}
@Bean
public AdDao adDao(){
AdDaoJDBCImpl bean= new AdDaoJDBCImpl ();
//DAO依赖jdbcTemplate
bean.setJdbcTemplate(jdbcTemplate());
return bean;
}
@Bean
public JdbcTemplate jdbcTemplate(){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource());
return jdbcTemplate;
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
dataSource.setUserName("root");
dataSource.setPassword("1234");
return dataSource;
}
}
(3)创建和使用Spring:获取AdService,执行业务逻辑等
public class Main{
public static void Main(String[] args) throws SQLException{
//通过以下可以看到,Spring容器也是一个Java对象,并负责管理程序中的其他对象
//参数是Java配置元数据类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(XnnBeanConfiguration.class);
//查找bean
//参数1:Bean名称
//参数2:类型参数,以便找到的Bean实例转换为该类型
//DataSource dataSource =applicationContext.getBean("dataSource",DataSource.class);
/*
//获取dataSource后,就可以调用其中的方法了
Connection connection=dataSource.getConnection();
//创建Statement对象,执行SQL操作,对结果集进行处理
//关闭连接
connection.close();
*/
//注释掉上面的代码,查找Service层bean,执行业务逻辑
AdService adService =applicationContext.getBean("adService",AdService.class);
}
}
以上,通过Spring JDBC支持,我们可以看出:
(1)Spring JDBC对DAO层隐藏了数据连接等信息;
(2)DAO层不用再重复 加载驱动、获取连接、关闭连接等代码步骤,可以通过JdbcTemplate来操作数据库;
(3)Spring封装了数据访问逻辑,将数据访问技术细节(JDBC)从应用程序代码中抽象出来,在DAO层可以使用不同的访问技术,例如可以有其他访问技术的DAO实现类。
2.3 Spring异常处理
Spring可以处理特定技术异常,特定技术异常是指,如直接JDBC访问的SQLException、Hibernate的HibernateException和JPA的EntityException,Spring将这些异常转换为自己的异常层次结构DataAccessException。
任何底层JDBC API抛出的受检查的异常SQLException都会与DataAccessException框架子类相映射。