spring jdbc也是持久化层的技术,和mybatis是一个级别的,帮助我们简化数据库操作的。
一.举例:spring jdbc 实现dept表的增删改查
第一步:创建项目,引入jar包
jar包: spring 核心jar包 spring jdbc的jar包。spring jdbc 要使用数据源连接池,所以我们还要引入dbcp的jar包。
数据库驱动包。
第二步:创建spring的主配置文件
spring jdbc 要使用数据源连接数据库,我们需要先创建数据源连接池,这里我们使用dpcp数据源连接池:
<!--创建dbcp数据源连接池对象-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<!--驱动-->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<!--url-->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"></property>
<!--用户名-->
<property name="username" value="scott"></property>
<!--密码-->
<property name="password" value="tiger"></property>
</bean>
使用spring 的jdbc 一般会使用JdbcTemplate对象,我们在spring工厂中创建这个对象,这个对象有点像mybatis中
的SqlSession
<!--创建spring jdbc的JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
第三步:创建实体类,dao层
创建实体类层
/** * 部门管理实体类 */ public class Dept { private Long deptno; private String dname; private String loc; public Long getDeptno() { return deptno; } public void setDeptno(Long deptno) { this.deptno = deptno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } }
创建DeptDAO.java
/** * 部门管理的dao接口 */ public interface DeptDao { /** * 保存部门 * @param dept */ public void save(Dept dept); /** * 删除部门 * @param deptno */ public void delete(Long deptno); /** * 修改部门 * @param dept */ public void update(Dept dept); /** * 查询所有部门 * @return */ public List<Dept> listAll(); /** * 根据主键查询部门 * @param deptno * @return */ public Dept findByDeptno(Long deptno); }
创建dao接口的实现类DeptDaoImpl.java:
/** * 部门管理dao接口的实现 */ @Component public class DeptDaoImpl implements DeptDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void save(Dept dept) { jdbcTemplate.update("insert into dept values(?,?,?)",dept.getDeptno(),dept.getDname(),dept.getLoc()); } @Override public void delete(Long deptno) { jdbcTemplate.update("delete from dept where deptno=?",deptno); } @Override public void update(Dept dept) { jdbcTemplate.update("update dept set dname=?,loc=? where deptno=?",dept.getDname(),dept.getLoc(),dept.getDeptno()); } //直接new接口的语法叫匿名内部类 //有的接口的实现类可能只需要使用一次,这种情况我们就不需要单独再创建一下这个接口的实现类了 //可以直接使用匿名内容类来创建这个接口的实现类。 private RowMapper<Dept> rowMapper = new RowMapper<Dept>(){ //第二个参数代表取到数据的行的下标 @Override public Dept mapRow(ResultSet resultSet, int i) throws SQLException { Dept dept = new Dept(); dept.setDeptno(resultSet.getLong("deptno")); dept.setDname(resultSet.getString("dname")); dept.setLoc(resultSet.getString("loc")); return dept; } }; @Override public List<Dept> listAll() { List<Dept> list = jdbcTemplate.query("select * from dept", rowMapper); return list; } @Override public Dept findByDeptno(Long deptno) { Dept dept = jdbcTemplate.queryForObject("select * from dept where deptno=?", rowMapper, deptno); return dept; } }
记在spring 主配置文件中扫描dao包:
<!--扫描dao实现类的包-->
<context:component-scan base-package="com.aaa.springjdbc.dao"></context:component-scan>
第四步:测试
/** * 测试spring jdbc 增删改查 */ public class Test01 { public static void main(String[] args) { //创建spring工厂类的对象 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //从工厂中获取DeptDaoImpl的对象 DeptDao deptDao = context.getBean(DeptDao.class); //测试保存 Dept dept = new Dept(); dept.setDeptno(1L); dept.setDname("技术部"); dept.setLoc("郑州"); deptDao.save(dept); //测试修改 dept.setDname("销售部"); deptDao.update(dept); //根据主键查询部门 Dept result = deptDao.findByDeptno(1L); System.out.println("部门编号为1的部门名称为:"+result.getDname()); //查询所有部门 List<Dept> depts = deptDao.listAll(); for (Dept d: depts) { System.out.println("部门编号:"+d.getDeptno()); System.out.println("部门名称:"+d.getDname()); System.out.println("部门位置:"+d.getLoc()); System.out.println("==="); } //删除部门 deptDao.delete(1L); } }
二.按名称传递参数
刚才我们在DeptDaoImp中传递参数使用是按占位符的位置传递参数,我们也可以使用按名称的方式传递参数,如果需要按名称传递参数,我们需要使用NamedParameterJdbcTemplate这类的对象,使用之前应该先在spring工厂中创建这个类的对象:
<!--创建按名称传递参数需要的jdbc模板对象 这个类中注入dataSource需要使用构造注入-->
<bean id="namedJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
增加按名称传递参数的dao的实现类对象DeptDaoMapper2.java:
/** * 部门管理dao接口的实现 */ @Component public class DeptDaoImpl2 implements DeptDao { @Autowired private NamedParameterJdbcTemplate jdbcTemplate; @Override public void save(Dept dept) { //需要把所有需要传递的参数封装到Map中 HashMap<String, Object> map = new HashMap<>(); map.put("deptno",dept.getDeptno()); map.put("dname",dept.getDname()); map.put("loc",dept.getLoc()); jdbcTemplate.update("insert into dept values(:deptno,:dname,:loc)",map); } @Override public void delete(Long deptno) { HashMap<String, Object> map = new HashMap<>(); map.put("deptno",deptno); jdbcTemplate.update("delete from dept where deptno=:deptno",map); } @Override public void update(Dept dept) { HashMap<String, Object> map = new HashMap<>(); map.put("deptno",dept.getDeptno()); map.put("dname",dept.getDname()); map.put("loc",dept.getLoc()); jdbcTemplate.update("update dept set dname=:dname,loc=:loc where deptno=:deptno",map); } //直接new接口的语法叫匿名内部类 //有的接口的实现类可能只需要使用一次,这种情况我们就不需要单独再创建一下这个接口的实现类了 //可以直接使用匿名内容类来创建这个接口的实现类。 private RowMapper<Dept> rowMapper = new RowMapper<Dept>(){ //第二个参数代表取到数据的行的下标 @Override public Dept mapRow(ResultSet resultSet, int i) throws SQLException { Dept dept = new Dept(); dept.setDeptno(resultSet.getLong("deptno")); dept.setDname(resultSet.getString("dname")); dept.setLoc(resultSet.getString("loc")); return dept; } }; @Override public List<Dept> listAll() { List<Dept> list = jdbcTemplate.query("select * from dept", rowMapper); return list; } @Override public Dept findByDeptno(Long deptno) { HashMap<String, Object> map = new HashMap<>(); map.put("deptno",deptno); Dept dept = jdbcTemplate.queryForObject("select * from dept where deptno=:deptno",map,rowMapper); return dept; } }