Spring JDBC
直接使用JDBC
a.增删改
获取Connection
获取Statement
设置SQL中?参数
执行SQL操作
释放Connection
b.查询
获取Connection
获取Statement
设置SQL中?参数
执行SQL操作获取Resulset结果
将Resultset结果封装成实体对象
释放Connection
在Spring中使用JDBC
a.提供了编写DAO的工具栏
JdbcTemplate
JdbcTemplet.update(“sql语句”,参数);
b.提供了AOP式事务管理(不需要再方法中追加事务提交和回滚)
c.提供了统一的异常处理
2.Spring整合JDBC步骤
引入spring(ioc,aop,dao)开发包
添加src下的spring配置文件
数据库去掉
package entity;
import java.io.Serializable;
public class Emp implements Serializable{
private Integer id;
private String name;
private Double salary;
private Integer age;
//定义为封装类。在数据库中为null。封装类可以接受,但是int就不能了。
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 Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package dao;
import javax.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import entity.Emp;
@Repository//扫描Dao
public class EmpDao {
@Resource
private JdbcTemplate template;//注入
//还可以继承 JdbcDaoSupport 来实现
public void save(Emp emp){
String sql ="insert into emp(name,salary,age) values(?,?,?)";
Object[] params = {emp.getName(),emp.getSalary(),emp.getAge()};
//存储给那个几个values的值.要是Object的。因为有很多不同的类型。
template.update(sql, params);
}
}
用到连接池就导入了dbcp各种jar
dbcp给JdbcTemplate注入。
<context:component-scan base-package="dao">context:component-scan>
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dbcp">property>
bean>
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="root">property>
<property name="password" value="root">property>
<property name="driverClassName" value="com.mysql.jdbc.Driver">property>
<property name="url" value="jdbc:mysql:///jsd1507db">property>
bean>
emplate在DAO中定义并利用注解注入。配置中的template又利用dbcp连接池注入信息。
创建一个Emp对象,然后利用dao的save方法存进去一个对象。
注意注入!我就遇到了错误。没有给template注入没写@Resource报空指针异常,检测发现template对象为空。
运行后
比如写一个查询
public List<Emp> findAll(){
String sql ="select * from emp";
EmpRowMapper rowMapper = new EmpRowMapper();
List<Emp> list =template.query(sql, rowMapper);
//要单独对rowMapper写一个组件
return list;
}
注意要写RowMapper组件 就要写一个类实现 RowMapper接口
这个组件的作用就是把查询出来的记录封装成实体对象
EmpRowMapper
package entity;
/**
* 将Emp记录封装成Emp对象
* @author Recar
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class EmpRowMapper implements RowMapper<Emp>{
public Emp mapRow(ResultSet arg0, int arg1) throws SQLException {
Emp emp = new Emp();
emp.setId(arg0.getInt("id"));
emp.setName(arg0.getString("name"));
emp.setSalary(arg0.getDouble("salary"));
emp.setAge(arg0.getInt("age"));
return emp;
}
}
//多行查询用query()方法
//单行查询用到queryForObject()方法
public Emp findById(int id){
String sql = "select * from emp "+"where id=?";
Object[] params={id};//这个是参数就是sql语句中的?
EmpRowMapper rowMapper = new EmpRowMapper();
Emp emp = template.queryForObject(sql, params, rowMapper);
//还是要用到了RowMapper
return emp;
}
Emp emp =empdao.findById(21);
System.out.println(emp.getName());
要注意!开始我传入的id是1.但是我的数据库中并没有id=1
的数据。然后报错:Incorrect result size: expected 1, actual 0
突然想到。。。。我没有id=1的啊。写上等于21即实际存在的。不然要写个异常。如果是0个会报错。
如果想执行 select count(*) from emp 的语句,返回的是一行。就是数字的话可以用template.queryForInt();方法。然后拿个去接收。
create table cost(
cost_id int primary key,
name varchar(50) not null,
base_duration long,
base_cost double,
unit_cost double,
status char(1),
descr varchar(100),
creatime date,
startime date,
cost_type char(1)
);
增加数据:
insert into cost values(2,'计时收费',null,null,0.5,0,'0.5元每小时',DEFAULT,DEFAULT,null);
Cost
package entity;
import java.io.Serializable;
import java.util.Date;
public class Cost implements Serializable {
private Integer cost_id;//资费ID
private String name;//资费名
private Long base_duratio;//基本时长
private Double base_cost;//基本费用
private Double unit_cost;//单位费用
private String status;//状态
private String descr;//描述
private Date creatime;//创建时间
private Date startime;//启用时间
private String cost_type;//资费类型
public Integer getCost_id() {
return cost_id;
}
public void setCost_id(Integer cost_id) {
this.cost_id = cost_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getBase_duratio() {
return base_duratio;
}
public void setBase_duratio(Long base_duratio) {
this.base_duratio = base_duratio;
}
public Double getBase_cost() {
return base_cost;
}
public void setBase_cost(Double base_cost) {
this.base_cost = base_cost;
}
public Double getUnit_cost() {
return unit_cost;
}
public void setUnit_cost(Double unit_cost) {
this.unit_cost = unit_cost;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
public Date getCreatime() {
return creatime;
}
public void setCreatime(Date creatime) {
this.creatime = creatime;
}
public Date getStartime() {
return startime;
}
public void setStartime(Date startime) {
this.startime = startime;
}
public String getCost_type() {
return cost_type;
}
public void setCost_type(String cost_type) {
this.cost_type = cost_type;
}
}
package entity;
import java.io.Serializable;
import java.util.Date;
public class Cost implements Serializable {
private Integer cost_id;//资费ID
private String name;//资费名
private Long base_duratio;//基本时长
private Double base_cost;//基本费用
private Double unit_cost;//单位费用
private String status;//状态
private String descr;//描述
private Date creatime;//创建时间
private Date startime;//启用时间
private String cost_type;//资费类型
public Integer getCost_id() {
return cost_id;
}
public void setCost_id(Integer cost_id) {
this.cost_id = cost_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getBase_duratio() {
return base_duratio;
}
public void setBase_duratio(Long base_duratio) {
this.base_duratio = base_duratio;
}
public Double getBase_cost() {
return base_cost;
}
public void setBase_cost(Double base_cost) {
this.base_cost = base_cost;
}
public Double getUnit_cost() {
return unit_cost;
}
public void setUnit_cost(Double unit_cost) {
this.unit_cost = unit_cost;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
public Date getCreatime() {
return creatime;
}
public void setCreatime(Date creatime) {
this.creatime = creatime;
}
public Date getStartime() {
return startime;
}
public void setStartime(Date startime) {
this.startime = startime;
}
public String getCost_type() {
return cost_type;
}
public void setCost_type(String cost_type) {
this.cost_type = cost_type;
}
}
public static void main(String[] args){
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
CostDao costdao = ac.getBean("costDao",CostDao.class);
List list = costdao.findAll();
for(Cost cost:list){
System.out.println(cost.getName());
}
}
要注意每个方法的返回值。很多的默认的或者我自己先写了个null
要记得改回来。
在之前的基础上增加一个Controller
利用注解~
package Controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import dao.CostDao;
import entity.Cost;
@Controller
public class ListController {
@RequestMapping("/list.do")
public String list(HttpServletRequest request){
String conf = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
CostDao costdao = ac.getBean("costDao",CostDao.class);
List list = costdao.findAll();
request.setAttribute("list", list);
return "list";
}
}
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>spring mvc+jsbctitle>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
head>
<body>
<%@page import="entity.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<table width="800" border="1">
<tr>
<td>资费IDtd>
<td>资费名td>
<td>基本时长td>
<td>基本时长td>
<td>单位费用td>
<td>状态td>
<td>描述td>
<td>创建时间td>
<td>启用时间td>
<td>资费类型td>
tr>
<c:forEach items="${list}" var="cost">
<tr>
<td>${cost.cost_id}td>
<td>${cost.name}td>
<td>${cost.base_duratio}td>
<td>${cost.base_cost}td>
<td>${cost.unit_cost}td>
<td>${cost.status}td>
<td>${cost.descr}td>
<td>${cost.creatime}td>
<td>${cost.startime}td>
<td>${cost.cost_type}td>
tr>
c:forEach>
table>
body>
html>
<mvc:annotation-driven>mvc:annotation-driven>
<context:component-scan base-package="Controller">context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/">property>
<property name="suffix" value=".jsp">property>
bean>
<servlet>
<servlet-name>springwebmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>springwebmvcservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
并没有写拦截器。结合登陆应该会更好。