什么是Spring JDBC
Spring是一个一站式框架,提供了对JDBC的管理封装
Spring自身也提供了控制层的SpringMVC 和持久层的Spring JdbcTemplate。
提供用于执行sql的方法
JDBC模块对事务进行管理
在这时,大多都采用MyBatis对数据库进行操作。
Mybatis框架概述和搭建详解
Spring JDBC的开发步骤
下载 Spring JdbcTemplate 的jar包
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
Spring数据链接不直接参与数据库的连接,所以就要使用第三方的组件来连接数据库。(DBCP、c3p0、阿里druid(德鲁伊))称为数据库连接组件
与数据库做连接,我们再加一个阿里的数据源,它还带有数据库连接池的计数。还有着sql监控作用
阿里druid数据库连接包含有三大功能:
- 基本的数据库连接 封装了jdbc。
- 数据库连接池 (频繁的连接数据库、创建销毁连接对象开销较大。所以就出现了创建一个连接对象的池子,与数据库交互时,可以先从连接池中获取连接对象,用完后不进行销毁,只是还回到连接池中,这样就减少了创建销毁时的开销。就是提前创建好连接对象,有数据请求时直接用就行了)
<!-- 阿里数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
顺便加上一个mysql的驱动包,做到与mysql数据库的连接
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
导入属性文件
因为我将数据库密码账户等信息提取到一个 .properties属性文件中去了。
我也将对数据库的连接的配置文件也与总的Spring分离出来了。
在总的Spring配置文件中导入对数据库的配置文件的内容。
<import resource="db.xml"></import>
<!--导入db.xml的配置文件-->
config.properties文件里的内容
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
ume=root
pwd=wasd
initialSize=5
maxActive=15
然后在数据库连接的配置文件中导入属性文件
<context:property-placeholder location="config.properties"></context:property-placeholder>
Spring读取到自己建的文件属性
管理数据源对象
spring 管理与数据库链接 (数据源)
<!--配置Druid的数据库连接对象-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${ume}"></property>
<property name="password" value="${pwd}"></property>
<property name="initialSize" value="${initialSize}"></property>
<!--initialSize初始化几个-->
<property name="maxActive" value="${maxActive}"></property>
<!--maxActive最大创建几个连接池-->
</bean>
在配置文件中创建JdbcTemplate对象
<!--Spring提供的JdbcTemplate封装类-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="druidDataSource"></property>
<!--将德鲁伊Druid注入到Spring提供的JdbcTemplate中去-->
</bean>
JdbcTemplate 中常用的方法
execute:无返回值,可执行 ddl,增删改语句 ;
update:执行新增、修改、删除语句;
queryForXXX:执行查询相关语句;
测试
在所需要的类中获得JdbcTemplate这个在bean中通过bean创建的对象
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
UserDao文件是向数据库发送数据库信息的
update执行数的增、删、改
- 添加信息
package com.demo.spring.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
jdbcTemplate.update("insert into admin(account,password,sex) values (?,?,?)","jim","111","男");
}
}
package com.demo.spring.service;
import com.demo.spring.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service(value = "userService")
public class UserService {
@Autowired
private UserDao userDao;
//在这里通过在Spring的注入将UserDao赋给UserService中的userDao属性
// 然后在UserService中的直接使用
public void saveUser() {
System.out.println("这是UserService中的saveUser中的方法");
userDao.save();
}
}
测试代码:
package com.demo.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.demo.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
//调用UserService中的saveUser方法
userService.saveUser();
}
}
测试结果:
jdbcTemplate.update的结果是有返回值的的,返回值是一个int型的,意为在数据库中有几行收到了改变
package com.demo.spring.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
//update一般做的都是增、删、改的操作
int a = jdbcTemplate.update("insert into admin(account,password,sex) values (?,?,?)","jim","111","男");
//jdbcTemplate.update的结果是有返回值的的,返回值是一个int型的,意为有几行收到了改变
System.out.println(a);
}
}
再跑test文件可以得到结果:
添加了一条数据,所以在数据库中就只有一行数据得到了改变。
- 删除数据
删除id>17的数据,应该是删除两条的数据
package com.demo.spring.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
//update一般做的都是增、删、改的操作
int a = jdbcTemplate.update("delete from admin where id > ?",17);
//jdbcTemplate.update的结果是有返回值的的,返回值是一个int型的,意为有几行收到了改变
System.out.println(a);
}
}
这些test测试运行代码(和上面的都一样)
package com.demo.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.demo.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
//调用UserService中的saveUser方法
userService.saveUser();
}
}
控制台输出结果如下图:控制台也显示在数据控中改变了两行的数据。
修改和增、删也都大同小异
execute不返回值,可执行 ddl语句,也可以执行增删改语句
package com.demo.spring.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
//execute 没有返回值,执行的是ddl语句,当然也可以执行的增删改的语句
jdbcTemplate.execute("create table test(id int)");
}
}
运行测试代码
package com.demo.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.demo.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
//调用UserService中的saveUser方法
userService.saveUser();
}
}
在数据库中也添加了一个所加的数据库表
queryForXXX:执行查询相关语句
返回一个简单类型的
package com.demo.spring.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
//通过jdbcTemplate.queryForObject来查询数据库的语言
int a = jdbcTemplate.queryForObject("select count(*) from admin",Integer.class);
System.out.println(a);
}
}
还是通过Test来测试代码
package com.demo.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.demo.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
//调用UserService中的saveUser方法
userService.saveUser();
}
}
查询总共有几条数据,查询结果应该为3条,控制台输出也是3格。
数据库表中的数据
返回一个对象的数据
package com.demo.spring.dao;
import com.demo.spring.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
// 这里就需要创建一个匿名的内部类的方式来接受数据库传来的数据,第二个参数必须为数组,数组里面的为传递进去的值
// 当然用Spring写向数据库中传输的方式远没有用Mybatis方便的,所以这里也就不再用Spring向数据库传输数据
Admin admin = jdbcTemplate.queryForObject("select * from admin where id = ?", new Object[]{15},
new RowMapper<Admin>() {
@Override
public Admin mapRow(ResultSet resultSet, int i) throws SQLException {
Admin admin1 = new Admin();
admin1.setId(resultSet.getInt("id"));
admin1.setAccount(resultSet.getString("account"));
admin1.setPassword(resultSet.getString("password"));
admin1.setSex(resultSet.getString("sex"));
return admin1;
}
});
System.out.println(admin);
}
}
同Mybatis都一样,也是需要创建一个对应的类来疯转保存数据
package com.demo.spring.model;
public class Admin {
private Integer id;
private String account;
private String password;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Admin{" +
"id=" + id +
", account='" + account + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
执行运行的测试代码:
package com.demo.spring.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.demo.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
//调用UserService中的saveUser方法
userService.saveUser();
}
}
运行结果如下:
返回多个对象的数据
package com.demo.spring.dao;
import com.demo.spring.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
List<Map<String,Object>> list = jdbcTemplate.queryForList("select * from admin ");
System.out.println(list);
}
}
在这个当中是用数据库中的列名作为键名的(但是不建议用,也没事,反正现在Spring对数据库数据的接受也就本身用的不多,都是用Mybatis来对数据库的操作)
运行测试代码结果如下:
使用另一种方式来拿数据
package com.demo.spring.dao;
import com.demo.spring.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
@Repository(value = "userDao")
public class UserDao {
@Autowired//注入JdbcTemplate作为对数据库的连接
JdbcTemplate jdbcTemplate;
public void save() {
//使用Spring对jdbc的封装类,发送sql,默认是自动提交事务的
List<Admin> admins = jdbcTemplate.query("select * from admin ", new RowMapper<Admin>() {
@Override
public Admin mapRow(ResultSet resultSet, int i) throws SQLException {
Admin admin1 = new Admin();
admin1.setId(resultSet.getInt("id"));
admin1.setAccount(resultSet.getString("account"));
admin1.setPassword(resultSet.getString("password"));
admin1.setSex(resultSet.getString("sex"));
return admin1;
}
});
System.out.println(admins);
}
}
运行测试代码
输出结果:
上一篇:>>> Spring Bean的管理(IOC 依赖注入)
下一篇:>>> Spring中AOP的概述、搭建和实现