1.jdbc技术所存在的问题
当我们使用jdbc之前,都需要做通过数据库连接url和数据库身份验证凭证来获取一个数据库连接。如果需要,我们可能还来个事务管理(创建一个事务同时还需要创建一个语句对象来执行SQL)。如果SQL操作如果返回一个ResultSet对象,还得遍历出每一行数据。全过程走try-catch-finally代码块。如果搞失败了,那么可能会泄漏资源,影响程序的性能。
2.spring依赖注入jdbc
导包:
2.1.jdbc配置通过硬编码方式实现
模型:(后面的介绍都采用此模型就不粘贴了)
public class UserInfo { private Integer id; private String name; private Integer age; 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 Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "UserInfo [id=" + id + ", name=" + name + ", age=" + age + "]"; } }Jdbc编码配置:
@Component public class Jdbc_Configuration { public DataSource doDataSource(){ DriverManagerDataSource dataSource =new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase?characterEncoding=utf-8"); dataSource.setUsername("root"); dataSource.setPassword(null); return dataSource; } }dao接口:
public interface UserInfoDao { public UserInfo find(Integer id); public void insert(UserInfo userInfo); }dao实现:
@Component public class UserInfoDaoImpl implements UserInfoDao{ @Resource private Jdbc_Configuration config; public void setConfig(Jdbc_Configuration config) { this.config = config; } Connection conn =null; PreparedStatement ps =null; ResultSet rs =null; @Override public UserInfo find(Integer id) { try { DataSource dataSource =config.doDataSource(); conn =dataSource.getConnection(); ps =conn.prepareStatement("select * from table2 where id=?"); ps.setInt(1, id); rs =ps.executeQuery(); UserInfo userInfo =new UserInfo(); while(rs.next()){ userInfo.setId(rs.getInt("id")); userInfo.setName(rs.getString("name")); userInfo.setAge(rs.getInt("age")); } return userInfo; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override public void insert(UserInfo userInfo) { try { DataSource dataSource =config.doDataSource(); conn =dataSource.getConnection(); ps =conn.prepareStatement("insert into table2(id,name,age) values(?,?,?)"); ps.setInt(1, userInfo.getId()); ps.setString(2, userInfo.getName()); ps.setInt(3, userInfo.getAge()); ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }bean.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:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" 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.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <context:component-scan base-package="cn.spy.jdbc"></context:component-scan> <context:annotation-config></context:annotation-config> </beans>
测试:
public class MyTest { public static void main(String[] args) throws Exception { ApplicationContext context =new ClassPathXmlApplicationContext("cn/spy/jdbc/bean.xml"); UserInfoDao userInfoDao =(UserInfoDao) context.getBean("userInfoDaoImpl"); // UserInfo userInfo =userInfoDao.find(2); // System.out.println(userInfo); UserInfo userInfo =new UserInfo(); userInfo.setId(6); userInfo.setName("李沁"); userInfo.setAge(40); userInfoDao.insert(userInfo); } }结果:
2.2.XML配置文件方式实现
对于dao层和model模型都是一样的。只是把硬编码的jdbc配置转移到xml中了。相当于xml方式的依赖注入。
bean.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:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <context:component-scan base-package="cn.spy.jdbc"></context:component-scan> <context:annotation-config></context:annotation-config> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/mydatabase?characterEncoding=utf-8"></property> <property name="username" value="root"></property> <property name="password" value=""></property> </bean> </beans>
dao实现:
@Component public class UserInfoDaoImpl implements UserInfoDao{ @Resource private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } Connection conn =null; PreparedStatement ps =null; ResultSet rs =null; @Override public UserInfo find(Integer id) { try { conn =dataSource.getConnection(); ps =conn.prepareStatement("select * from table2 where id=?"); ps.setInt(1, id); rs =ps.executeQuery(); UserInfo userInfo =new UserInfo(); while(rs.next()){ userInfo.setId(rs.getInt("id")); userInfo.setName(rs.getString("name")); userInfo.setAge(rs.getInt("age")); } return userInfo; } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override public void insert(UserInfo userInfo) { try { conn =dataSource.getConnection(); ps =conn.prepareStatement("insert into table2(id,name,age) values(?,?,?)"); ps.setInt(1, userInfo.getId()); ps.setString(2, userInfo.getName()); ps.setInt(3, userInfo.getAge()); ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }测试:
public class MyTest { public static void main(String[] args) throws Exception { ApplicationContext context =new ClassPathXmlApplicationContext("cn/spy/jdbc/bean.xml"); UserInfoDao userInfoDao =(UserInfoDao) context.getBean("userInfoDaoImpl"); UserInfo userInfo =userInfoDao.find(2); System.out.println(userInfo); } }结果:
总结:
可以看到这个例子还是需要try-catch-finally代码块。这个例子仅仅只是使用了spring的依赖注入的特性,并没有使用spring的jdbc模板支持。而且应当注意在生产环境下,切记别玩DriverManagerDataSource这个类,因为这个类没有连接池功能,不会管理连接回收再利用。而是每次都尝试打开一个新的物理jdbc连接。打开一个jdbc连接是一个非常昂贵的过程。所以应该多使用c3p0或者dbcp连接池的DataSource来实现,切记。3.使用jdbc模板类(jdbcTemplate)实现增删改查
由于DriverManagerDataSource的缺点,接下来都使用c3p0连接池来实现jdbc连接的管理。
使用c3p0就要导入相关的jar包:c3p0-0.9.1.2.jar
Model模型:
public class Student { private String id; private String name; private int age; private String gender; 对应的getter、setter方法。。。 @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]"; } }dao接口层:
public interface IStudentDao { public Student findById(String id); public int insert(Student stu); public int delete(String id); public int update(String id,Student stu); }dao实现层:
public class StudentDaoImpl implements IStudentDao{ private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public Student findById(String id) { // TODO Auto-generated method stub String sql="select * from student where id=?"; return jdbcTemplate.queryForObject(sql, new RowMapper<Student>(){ @Override public Student mapRow(ResultSet rs, int rowNum) throws SQLException { // TODO Auto-generated method stub Student stu =new Student(); stu.setId(rs.getString("id")); stu.setName(rs.getString("name")); stu.setAge(rs.getInt("age")); stu.setGender(rs.getString("gender")); return stu; } },id); } @Override public int insert(Student stu) { // TODO Auto-generated method stub String sql="insert into student(id,name,age,gender) values(?,?,?,?)"; int rowNum =jdbcTemplate.update(sql, new Object[]{stu.getId(),stu.getName(),stu.getAge(),stu.getGender()}, new int[]{Types.VARCHAR,Types.VARCHAR,Types.INTEGER,Types.VARCHAR}); return rowNum; } @Override public int delete(String id) { String sql="delete from student where id=?"; int rowNum =jdbcTemplate.update(sql, id); return rowNum; } @Override public int update(String id, Student stu) { // TODO Auto-generated method stub String sql="update student set name=?,age=? where id=?"; int rowNum =jdbcTemplate.update(sql, new Object[]{stu.getName(),stu.getAge(),id}, new int[]{Types.VARCHAR,Types.INTEGER,Types.VARCHAR}); return rowNum; } }测试类:
public class JdbcTest { public static void main(String[] args) { ApplicationContext context =new ClassPathXmlApplicationContext("bean.xml"); IStudentDao studentDao =(IStudentDao) context.getBean("studentDaoImpl"); //通过主键查找: // Student stu =studentDao.findById("1"); // System.out.println(stu); //插入对象 // Student stu =new Student(); // stu.setId("21"); // stu.setName("李沁"); // stu.setAge(21); // stu.setGender("男"); // int rowNum =studentDao.insert(stu); // System.out.println(rowNum); //删除 // int rowNum =studentDao.delete("21"); // System.out.println(rowNum); //修改对象的属性 Student stu =new Student(); stu.setName("张磊"); stu.setAge(26); stu.setGender("男"); int rowNum =studentDao.update("2", stu); System.out.println(rowNum); } }结果:
查询:
更新:
插入:
。。。
4.使用jdbcTemplate实现批处理
dao实现层:
public class StudentDaoImpl implements IStudentDao{ private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public void updateBatch(List<Object[]> list) { // TODO Auto-generated method stub String sql="insert into student values(?,?,?,?)"; jdbcTemplate.batchUpdate(sql, list, new int[]{Types.VARCHAR,Types.VARCHAR,Types.INTEGER,Types.VARCHAR}); } }测试类:
public class JdbcTest { public static void main(String[] args) { List<Object[]> list =new ArrayList<Object[]>(); for(int i=0;i<4;i++){ Object[] objs=new Object[4]; objs[0]="30"+i; objs[1]="赵四"+i; objs[2]=20+i; objs[3]="男"; list.add(objs); } ApplicationContext context =new ClassPathXmlApplicationContext("bean.xml"); IStudentDao studentDao =(IStudentDao) context.getBean("studentDaoImpl"); studentDao.updateBatch(list); } }
结果: