springJDBC
1.JDBC
JDBC技术
全写为 java database connectivity
翻译为 Java访问数据库的解决方案
技术出现原因
希望以相同的方式实现访问不同的数据库
以实现与具体数据库无关的Java操作
JDBC定义一套标准的接口,即访问数据库API
不同的数据库厂商根据各自数据库的特点去实现接口
从而得到Java程序访问
JDBC接口:
DriverManager:驱动管理类
Connection:连接接口
Statement:语句对象
PreparedStatement:语句对象
CallableStatement:调用存储过程语句对象
ResutSet:结果集接口
JDBC工作过程:
1)加载驱动创建连接
2)创建语句对象
3)执行SQL语句
4)处理结果集
5)关闭资源
1.1spring+JDBC
前提准备
数据库:mysq数据库
开发工具:eclipse
数据库中表:
create table t_table(
id int ,
username varchar(30)
)
insert into t_table values(1,“aaa”);
insert into t_table values(2,“bbb”);
insert into t_table values(3,“ccc”);
insert into t_table values(4,“ddd”);
引入jar包
mysql-connector-java-5.1.8-bin.jar
spring-core-4.3.8.RELEASE.jar
spring-beans-4.3.8.RELEASE.jar
spring-context-4.3.8.RELEASE.jar
commons-logging.jar
spring-expression-4.3.8.RELEASE.jar
spring-aop-4.3.8.RELEASE.jar
①新建Java项目
直接使用Java代码表示为
//1.建立数据库连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
//2.创建语句对象
PreparedStatement ps = con.prepareStatement("select * from t_table");
//3.执行sql语句
ResultSet rs = ps.executeQuery();
List<Table> tables = new ArrayList<Table>();
Table table = null;
//4.处理结果集
while (rs.next()) {
table = new Table(rs.getInt("id"), rs.getString("username"));
tables.add(table);
}
for (Table t : tables) {
System.out.println(t);
}
//5.关闭连接
rs.close();
ps.close();
con.close();
如果使用spring,要类的加载交给容器处理
所以DriverManager这个类交给容器,其它的类则不用
而DriverManager中需要注入的参数是数据库连接地址、用户名和密码
但该类本身并无构造器初始化参数和setter方法
所以在Java中新建一个工具类获取参数,然后返回Connection对象
外部配置文件 db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=root
spring配置文件
<context:component-scan base-package="com.ds"/>
<util:properties id="db" location="classpath:db.properties" />
<bean id="con" class="com.ds.util.DBUtil">
<property name="classname" value="#{db.driver}"/>
<property name="url" value="#{db.url}"/>
<property name="username" value="#{db.username}"/>
<property name="password" value="#{db.password}"/>
</bean>
DBUtil类
private String classname;
private String url;
private String username;
private String password;
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Connection getConnection() {
try {
try {
Class.forName(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return DriverManager.getConnection(url, password, username);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
测试类
// spring+JDBC
@Test
public void test1() throws SQLException {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
DBUtil db = ac.getBean("con", DBUtil.class);
Connection con = db.getConnection();
PreparedStatement ps = con.prepareStatement("select * from t_table");
ResultSet rs = ps.executeQuery();
List<Table> tables = new ArrayList<Table>();
Table table = null;
while (rs.next()) {
table = new Table(rs.getInt("id"), rs.getString("username"));
tables.add(table);
}
for (Table t : tables) {
System.out.println(t);
}
rs.close();
ps.close();
con.close();
}
测试结果
Table [id=1, Username=aaa]
Table [id=2, Username=bbb]
Table [id=3, Username=ccc]
Table [id=4, Username=ddd]
这里只是把数据库连接基本类交给容器管理
理想情况下只需要调用容器中数据库连接类,并输入查询语句,便可以返回结果
1.2Spring对JDBC整合支持
新增spring-tx-4.3.18.jar、spring-jdbc-4.3.18.jar、commons-dbcp2-2.6.0.jar、commons-pools2-2.6.2.jar
Spring对DAO data access object 提供哪些支持
1)Spring对DAO异常提供统一处理
2)Spring对DAO编写提供支持的抽象类
3)减少DAO编码量,提高编程效率
Spring对于DAO异常的支持
Spring把特定某种技术的异常,如SQLException,
统一转换为自己的异常,把异常进行封装
异常以DataAccessException为父类
它封装了原始的异常对象,不会丢失原始的错误信息
DataAccessException继承于RuntimeException,是非检查异常
把检查异常变成非检查异常,不需要再增加try catch语句块
不会因为没有处理异常而出现编译错误,异常必须要处理可以用拦截器统一处理
Spring对DAO编写支持
Spring为了便于以一种一致的方式使用各种数据库访问技术,
如JDBC、SpringJDBC、MyBatis、Hiibernate
Spring提供一套抽象的DAO类,通过DAO类提供的方法
可以获取数据库访问技术相关的数据源和其他配置相关信息
jdbcTemplate:封装常用的JDBC操作方法
jdbcDaoSupport:JDBC数据库访问对象的基类
HibernateTemplate:封装常用Hibernate方法
HibernateDaoSupport:Hibernate数据库访问对象的基类
jdbcDaoSupport
利用JDBC技术编写DAO的父类。通过此类提供的方法可便于获取Connection和jdbcTempate
jdbcDaoSupport使用是需要注入一个DataSource
jdbcTemplate:封装了链接获取以及连接释放等工作
从而简化我们对JDBC的使用,避免忘记关闭连接等错误
如何编写DAO组件
基于Springjdbc技术编写DAO组件可以采用以下两种方式
1)DAO继承jdbcDaoSupport,通过getJdbcTempate方法获取JdbcTemplate对象
需要在DAO实现类中注入一个Dataource对象来完成JdbcTemplate的实例化
前提
spring.xml
<!--外部数据库数据文件-->
<util:properties id="db" location="classpath:db.properties"/>
<!--建立数据库连接-->
<bean id="ds" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="#{db.driver}"/>
<property name="url" value="#{db.url}"/>
<property name="username" value="#{db.username}"/>
<property name="password" value="#{db.password}"/>
</bean>
<context:component-scan base-package="com.ds"/>
Java类中代码
@Autowired
public void setDs(DataSource ds) {//容器中有BasicDataSource
super.setDataSource(ds);
}
或
@Autowired
public void setJT(JdbcTemplate jt) {
super.setJdbcTemplate(jt);
}
或直接在bean中注入给父类
<bean id="tableDao" class="com.ds.dao.TableDao">
<property name="dataSource" ref="ds"/>
</bean>
Java类中代码
@Repository
public class TableDao extends JdbcDaoSupport {
@Autowired
public void setDs(DataSource ds) {// 容器中有BasicDataSource
super.setDataSource(ds);
}
public List<Table> findAll() {
String sql = "select * from t_table";
return this.getJdbcTemplate().query(sql, new TableRowMapper());
}
class TableRowMapper implements RowMapper<Table> {
@Override
public Table mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Table(rs.getInt("id"), rs.getString("username"));
}
}
}
2)DAO不继承JdbcDaoSupport,在spring的容器中配置一个JdbcTemplate的Bean
然后注入给DAO组件,
spring配置文件
<!--外部数据库数据文件-->
<util:properties id="db" location="classpath:db.properties"/>
<!--建立数据库连接-->
<bean id="ds" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="#{db.driver}"/>
<property name="url" value="#{db.url}"/>
<property name="username" value="#{db.username}"/>
<property name="password" value="#{db.password}"/>
</bean>
<!-- 定义JDBCtemplate -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
</bean>
<context:component-scan base-package="com.ds"/>
java类中代码
@Autowired
private JdbcTemplate jt;
//查询
public List<Dept> findAll() {
return jt.query("select * from dept", new DeptRowMapper());
}
//条件查询
public Dept findById(int deptno) {
return jt.queryForObject("select * from dept where deptno=?", new Object[] { deptno }, new DeptRowMapper());
}
//增加
public void save(Dept dept) {
jt.update("insert into dept values(?,?)", dept.getDeptno(), dept.getDname());
}
//更新
public void update(Dept dept) {
jt.update("update dept set dname=? where deptno=?", dept.getDname(), dept.getDeptno());
}
//删除
public void delete(int deptno) {
jt.update("delete from dept where deptno=?", deptno);
}
//结果集映射对象
class DeptRowMapper implements RowMapper<Dept> {
@Override
public Dept mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Dept(rs.getInt("deptno"), rs.getString("dname"));
}
}
测试类
// spring整合JDBC
@Test
public void test2() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
TableDao td = ac.getBean(TableDao.class);
List<Table> tables = td.findAll();
for (Table table : tables) {
System.out.println(table);
}
}
图解