这一篇文章简单谈谈Spring的dao模块,主要的内容是JdbcTemplate这个对象的使用,因为原先用过的原因,所以这一次就比较简单了。
我们进行数据库操作,这次需要的jar包如下:
在配置数据源的时候我们可以选择使用原生的JDBC连接操作,也可以使用各种数据库连接池,使用数据库连接池显然是更加高效的做法:
数据源类型:
常见连接池:
想要使用这些连接池或者其他数据源,需要额外引入jar包,因为我们只引入了spring-jdbc这一个jar包是非常纯净的spring体验,所以这次就使用原生JDBC驱动程序定义的数据源
配置方法如下:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="dzzhyk"/>
<property name="password" value="123456"/>
<property name="url" value="jdbc:mysql://abc.com:3306/spring"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
bean>
其实有好多属性可以选择,使用其他数据源需要的配置是相同或者更加复杂的。
配置到这里其实就可以了,简单配置只需要这四项即可,但是在xml配置文件里面写死配置内容不是太好的做法,我们可以在src下新建一个jdbc.properties文件来专门存储配置信息:
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://abc.com:3306/spring?useUnicode=true&characterEncoding=UTF-8
mysql.username=dzzhyk
mysql.password=123456
然后在xml文件中加载这个配置文件,使用引用表达式来创建bean:
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
<property name="url" value="${mysql.url}"/>
<property name="driverClassName" value="${mysql.driver}"/>
bean>
其实就是在容器中也配置一个bean对象,其类型为jdbcTemplate,我们在需要进行数据库操作的时候,就直接主动注入获取这个对象即可。
<context:component-scan base-package="dao"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
bean>
我们创建一个dao层类MyDao:
@Repository("myDao")
@ComponentScan
public class MyDao {
@Autowired
private JdbcTemplate template;
public void addUser(User user){
String sql = "INSERT INTO `user`(`username`, `password`) VALUES(?, ?)";
template.update(sql, user.getUsername(), user.getPassword());
}
}
然后把这个dao类也注册成为bean,并且在测试类中调用:
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
MyDao dao = (MyDao) ac.getBean("myDao");
User user = new User("dzzhyk", "123");
dao.addUser(user);
在调用template的方法的时候可以看到有很多的已经包装好的语句,其中query开头的代表的就是查询语句:
Spring并不知道我们想要查询回来的记录行,其类型含义是个什么对象,所以我们需要自己实现RowMapper这个东西,或者调用Spring的方法帮助我们生成RowMapper,从而把记录转换为我们想要的对象:
手动写法:
public User getUser(String username){
String sql = "SELECT * FROM `user` WHERE username=?";
return template.queryForObject(sql, new RowMapper<User>() {
// 自己重写属于User对象的RowMapper
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
}, username);
}
使用Spring提供的工具类BeanPropertyRowMapper:
public User getUser(String username){
String sql = "SELECT* FROM `user` WHERE username=?";
return template.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username);
}
这个BeanPropertyRowMapper其实也就是根据属性名称的对应情况来自动装配的,如果数据库字段名和对象的属性名称相同就会装配成功,否则该字段的属性值为null
接下来让我们运行试验一下:
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
MyDao dao = (MyDao) ac.getBean("myDao");
User dzzhyk = dao.getUser("dzzhyk");
System.out.println(dzzhyk);
输出结果如下:
User{username='dzzhyk', password='123'}
另外还需要注意的是:在写sql语句的时候语句里面都使用了占位符?来代表未知量,这实际就是JDBC技术中的PrepareStatement类型,可以防止绝大部分sql注入