一.Spring 的数据库模板的使用
Spring 可以与Hibernate,MyBatis 进行整合,进行相应的持久化,但都是Spring 自己也有相应的数据库操作,即JdbcTemplate。
接下来,重点讲解一下JdbcTemplate 的用法。
二.JdbcTemplate 类的使用前准备
二.一 引入jar包
在使用JdbcTemplate 类之前,需要引入相应的jar包。 需要引入jdbc和tx jar包。
Spring 可以与Junit 进行测试,引入spring-test 的jar包。这三个,都需要进行引入。
另外,不要忘记引入mysql数据库驱动的jar包。
二.二 搭建环境
采用上一章所使用的例子。 这里为了方便,进行简化一下。 简化后的为。
UserDao.java 接口
public interface UserDao { }
UserDaoImpl 实现类
@Repository public class UserDaoImpl implements UserDao { }
UserService 接口
public interface UserService { }
UserServiceImpl 实现类
@Service public class UserServiceImpl implements UserService{ @Resource private UserDao userDao; }
User Pojo 类,有四个简单的属性
private Integer id; private String name; private String sex; private Integer age;
配置文件 applicationContext.xml
<!-- 开启注解扫描 --> <context:component-scan base-package="com.yjl"></context:component-scan>
采用@Resource 的注解进行相应的注入。
这里采用的是Spring 测试的方式,所以不用Action 类了。
UserTest.java 类
@RunWith(SpringJUnit4ClassRunner.class) // 引入哪个类,固定语法。 @ContextConfiguration("classpath:applicationContext.xml") // 引入配置文件 public class UserTest { @Resource private UserService userService; }
需要手动创建Mysql 数据表 user 表。
三. JdbcTemplate 的常见方法使用
三.一 JdbcTemplate 对象的创建
创建对象,采用的是new JdbcTemplate(dataSource) 的形式, dataSource 指的是数据源。
创建数据源 dataSource
org.springframework.jdbc.datasource.DriverManagerDataSource
DriverManagerDataSource dataSource=new DriverManagerDataSource(); // 构建数据库连接 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring"); dataSource.setUsername("root"); dataSource.setPassword("abc123");
构建JdbcTemplate 对象
JdbcTemplate jdbc=new JdbcTemplate(dataSource);
为了简化后面的开发,将数据源的创建 封装成一个方法。
public DriverManagerDataSource getDataSource(){ DriverManagerDataSource dataSource=new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring"); dataSource.setUsername("root"); dataSource.setPassword("abc123"); return dataSource; }
三.二 插入数据 update()
public int add() { //1. 创建数据源 DriverManagerDataSource dataSource=getDataSource(); //2. 实现化jdbcTemplate 对象。 JdbcTemplate jdbc=new JdbcTemplate(dataSource); //3. sql语句 String sql="insert into user(name,sex,age) values(?,?,?)"; //4. 调用内部方法,进行执行sql语句。 //采用的是可变参数的形式。 //return jdbc.update(sql,"两个蝴蝶飞","男",24); //也可以采用对象数组的形式,传入的是一个对象参数. return jdbc.update(sql,new Object[]{"精灵妹","女",24}); }
UserTest 中测试方法为:(以后省略写。)
@Test public void testAdd(){ int count=userService.add(); System.out.println("变更的数目为:"+count); }
测试运行后:
三.三 修改语句 update()
@Override public int update() { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="update user set name=?,age=? where id=?"; return jdbc.update(sql,new Object[]{"老蝴蝶",25,1}); }
三.四 删除语句 update()
传入参数值为1
public int delete(int id) { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="delete from user where id=?"; return jdbc.update(sql,id); }
三.五 批量更新 batchUpdate()
添加,删除,修改,都是用的update() 方法, 为了便于后面的查询,这里提前讲解一下 批量更新的操作。 batchUpdate()
public int updateBatch() { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); // sql 语句必须是同一个sql语句, 只是参数不一样而已。 String sql="insert into user(name,sex,age) values(?,?,?)"; // 单个时,每一个是Object [] 数组,批量时,便是List<Object []> 数组。 List<Object []> param=new ArrayList<Object []> (); Object [] obj1=new Object[]{"张三","男",24}; Object [] obj2=new Object[]{"李四","男",25}; Object [] obj3=new Object[]{"王二","女",24}; param.add(obj1); param.add(obj2); param.add(obj3); // 更新语句。 return jdbc.batchUpdate(sql,param).length; }
执行后,结果为: 返回的是 int[] 数组
三.六 根据id 查询单个值 queryForObject
查询时,用queryForObject(), 需要自己手动处理查询后的结果。 实现RowMapper 接口,重写里面的mapRow 方法。
@Override public User getById(int id) { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="select * from user where id=?"; //User user=jdbc.queryForObject(sql,new MyUserRow(),id); // 也可以将参数放在前面,但这个时候,参数必须是数组方式 User user=jdbc.queryForObject(sql,new Object[]{id},new MyUserRow()); return user; }
class MyUserRow implements RowMapper<User>{ @Override public User mapRow(ResultSet res, int num) throws SQLException { // 根据res 取出里面的属性。 num 表示索引行 String name=res.getObject("name").toString(); String sex=res.getObject("sex").toString(); int age=Integer.parseInt(res.getObject("age").toString()); int id=Integer.parseInt(res.getObject("id").toString()); // 构建user 对象。 User user=new User(); user.setId(id); user.setName(name); user.setSex(sex); user.setAge(age); return user; } }
查询后的结果为:
三.七 查询多条数据 query()
public List<User> getAll() { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="select * from user"; List<User> userList=jdbc.query(sql,new MyUserRow()); return userList; }
输出集合
List<User> userList=userService.getAll(); userList.forEach(n->System.out.println(n));
三.八 查询单个值 queryForObject()
public int count() { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="select count(*) as count from user"; // 返回的是Integer 类型。 int count=jdbc.queryForObject(sql,Integer.class); return count; }
三.九 查询封装成Map集合 queryForList()
@Override public int forList(){ DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="select * from user"; // 查询出的是map 集合, 列名为key,值为value . List<Map<String,Object>> result =jdbc.queryForList(sql); Iterator <Map<String,Object>> iterator=result.iterator(); while(iterator.hasNext()){ Map<String,Object> map=iterator.next(); // 里面的编号为 属性名称. //实际上,需要遍历一下map,看key 和value 分别是什么。 System.out.print("编号为:"+map.get("id")); System.out.print("名称为:"+map.get("name")); System.out.print("性别为:"+map.get("sex")); System.out.print("年龄为:"+map.get("age")); System.out.println(); } return result.size(); }
queryForList() 时,查询出的是List, 单个值是Map, 里面的key 放置的是列名,value 是数值。 如果sql 语句中 列名不明显或者是不好用的话,最好在sql 语句中设置别名,这样在map 中就可以把别名当成key了。
三.十 封装成单个Map queryForMap()
里面只放置单个Map的值,
可以放置单个值的结果,如 聚集函数 count().
只能放置单个值,不能查询出单条记录。
public int count() { DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); // 设置别名,好设置key值。 String sql="select count(*) as count from user"; Map<String, Object> map=jdbc.queryForMap(sql); int count=Integer.parseInt(map.get("count").toString()); return count; }
不能放置单条记录,这样写是错误的
public User getById(int id) { // 是错误的写法。 DriverManagerDataSource dataSource=getDataSource(); JdbcTemplate jdbc=new JdbcTemplate(dataSource); String sql="select * from user where id=?"; Map<String, Object> map=jdbc.queryForMap(sql,1); User user=new User(); user.setId(Integer.parseInt(map.get("id").toString())); user.setName(map.get("name").toString()); user.setSex(map.get("sex").toString()); user.setAge(Integer.parseInt(map.get("age").toString())); return user; }
四. jdbcTemplate 与数据库配置使用
数据库的配置,应该是用配置文件,而不是硬编码到程序里面。
四.一 jdbc.properties 配置文件
放置在src 目录下。
内容是:
## key值,前面最好加上jdbc的前缀。 因为username 与password 可能与其他值重名。 jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring jdbc.username=root jdbc.password=abc123
四.二 在applictionContext.xml 中引入配置文件jdbc.properties
<!-- 引入配置文件 --> <context:property-placeholder location="jdbc.properties"/>
四.三 UserDaoImpl 类中声明JdbcTemplate对象
@Repository public class UserDaoImpl implements UserDao { @Resource private JdbcTemplate jdbcTemplate; }
四.四 Spring 内置连接池的配置
bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> --> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
四.五 Spring 配置dbcp 连接池
需要引入关于dbcp 的jar包, 一个是 dbcp.jar ,一个是pool.jar
bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> --> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
四.六 Spring 配置C3p0 连接池
需要引入关于c3p0的jar包。
和:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!--注意,这里用的是driverClass和jdbcUrl--> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
上面的三种方式均可以。
这样,就可以在配置文件中进行配置数据源了。
谢谢!!!