Spring JDBCTemplate介绍
- (1)JdbcTemplate属于Spring中比较独立的一个模块
- (2)JdbcTemplate是什么?
Spring对数据库的操作在jdbc上面做了深层次的封装 - (3)有什么特点?
》使用spring的注入功能
可以把DataSource注册到JdbcTemplate之中 (spring-jdbc.jar)
》JdbcTemplate 核心处理对象(有对应的增删改查的方法)
update(sql, 实际传递的参数 ); 可以完成增删改
- (4)与原生JDBC,MyBatis区别?
》与MyBatis都是对原生JDBC的封装
》简单的数据库操作使用JdbcTemplate,大型复杂的使用Mybatis
SpringJDBCTemplate的Spring实现
- (1)准备数据库
- (2)依赖配置
- (3)给数据源DriverManagerDataSource设置四大信息
sql
#创建数据库
create database springjdbc ;
use springjdbc;
create table `stu` (
`sid` double ,
`sname` varchar (90),
`schoolName` varchar (300),
`score` double
);
insert into `stu` (`sid`, `sname`, `schoolName`, `score`) values('1','赵四','吉大','300');
insert into `stu` (`sid`, `sname`, `schoolName`, `score`) values('17','张三','交大','3000');
insert into `stu` (`sid`, `sname`, `schoolName`, `score`) values('18','熊3','武大','3000');
insert into `stu` (`sid`, `sname`, `schoolName`, `score`) values('19','张飞','交大','3000');
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
TestJdbcTemplate
public class TestJdbcTemplate {
@Test
public void test01(){
//创建数据源对象 四大信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc");
dataSource.setUsername("root");
dataSource.setPassword("");
//创建JdbcTemplate对象,并传入连接池
//参数:数据源连接池
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//调用update方法 参数1:sql语句 参数2:实际传递的参数
jdbcTemplate.update("insert into stu values(?,?,?,?)",66,"tom","吉首",100);
}
}
上面这个创建过程我们用springIOC配置优化
applicationContext.xml
<!-- //创建数据源对象 四大信息-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springjdbc"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<!-- //JdbcTemplate对象
//参数:数据源连接池
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"/>
</bean>
SpringJDBCTemplate-增删改
- 调用update方法
update(sql, 实际传递的参数 ); 可以完成增删改
TestJdbcTemplateSpring
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJdbcTemplateSpring {
//什么时候使用注解 ,如果是自己开发的类,使用注解
//如果是别人开发的,因为注解加不上去,使用xml
@Autowired
JdbcTemplate jdbcTemplate;
@Test
public void test01(){
//调用update
int count = jdbcTemplate.update("insert into stu values(?,?,?,?)",1000,"rose","吉首",100);//参1 sql,参2 占位符对应的参数
}
@Test
public void test02(){
//调用update
int count = jdbcTemplate.update("delete from stu where sid = ? ",1000);//参1 sql,参2 占位符对应的参数
}
@Test
public void test03(){
//调用update
int count = jdbcTemplate.update("update stu set sname = ? where sid= ?","关于",17);//参1 sql,参2 占位符对应的参数
}
}
SpringJDBCTemplate-单值查询和查询一行(即 数值 或 对象)
- (1)queryForObject
- 返回的结果可以是
一个值
如:String Integer - 也可以是
一个对象
如:Student - (2)如果是一个对象,则需要BeanPropertyRowMapper,但需要强转为对象类型
》什么是BeanPropertyRowMapper
将一行表记录赋值给一个javaBean对象返回,
但要求列名与表名相同。 - (3)结果赋值给Map,很少用。
根据数据表创建好实体类
TestJdbcTemplateSpring
//查询
//返回结果为一个值
@Test
public void test04(){
Integer integer = jdbcTemplate.queryForObject("select count(*) from stu", Integer.class);
logger.debug("一共有"+integer+"条数据");
String s = jdbcTemplate.queryForObject("select sname from stu where sid = ?", String.class, 19);
logger.debug("编号为19的姓名为"+s);
}
//返回结果为一行数据
@Test
public void test05(){
//一行数据转换成一个对象需要rowMapper
//即查询结果处理类型 设置为Stu类型
BeanPropertyRowMapper rowMapper = new BeanPropertyRowMapper(Stu.class);
String sql = "select * from stu where sid = ?";
Stu stu = (Stu) jdbcTemplate.queryForObject(sql, rowMapper, 19);
logger.debug(stu.toString());
//结果封装成一个Map集合(很少用,取值不方便,需要根据键取值)
//Map集合的键是字段的名字,Map集合的值是字段的值
Map<String, Object> map = jdbcTemplate.queryForMap(sql, 18);
logger.debug(map.toString());
}
SpringJDBCTemplate-单值多行(即List集合)
-
(1)queryForList
返回结果是一个List
List元素可是javaBean对象,也可以是Map<String,Object> -
(2)前者比较常用,后者基本不用
TestJdbcTemplateSpring
//返回结果为多行数据
@Test
public void test06(){
String sql = "select * from stu where score > 300";
BeanPropertyRowMapper rowMapper = new BeanPropertyRowMapper(Stu.class);
//结果类型为集合List
List<Stu> list = jdbcTemplate.query(sql,rowMapper);
logger.debug(list.toString());
//结果类型为Map
List<Map<String, Object>> listMap = jdbcTemplate.queryForList(sql);
//取值(很麻烦,要记得键的值,容易出错)
Map<String,Object> map = listMap.get(1);
logger.debug((String) map.get("sname"));
}
所有查询方法汇总
查询的方法,重点2,5 方法
1. queryForObject(sql ,返回数据类型的字节码对象, 实际传递的参数); 查询指定的字段
2. queryForObject(sql, BeanPropertyRowMapper, 实际传递的参数); 查询对象
3. queryForMap(sql , 实际传递的参数); 返回的是一个Map,map对象中存放的是对象的数据, 以键值对方式存储
4. queryForList(sql , 实际参数); 返回的是List<Map<String,Object>> 查询一个List的结果,但是list中有map
5. query(sql,BeanPropertyRowMapper); 查询一个List<POJO对象>
扩展:返回类型
@Repository
public class StudentDaoImpl implements IStudentDao {
@Autowired
private JdbcTemplate jt;
//添加学生,返回主键
//参数加final是确保该参数不会被改值
@Override
public int addStudent(final Student stu) {
String sql = "insert into student(name,age,birth,email,schid) values(?,?,?,?,?)";
GeneratedKeyHolder kh = new GeneratedKeyHolder();
int count = jt.update((connection)->{
PreparedStatement pst = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pst.setString(1,stu.getName());
pst.setInt(2,stu.getAge());
pst.setDate(3,new java.sql.Date(stu.getBirth().getTime()));
pst.setString(4,stu.getEmail());
pst.setInt(5,stu.getSchid());
return pst;
},kh);
stu.setId(kh.getKey().intValue());
return count;
}
//添加多条数据
@Override
public void addPics(List<Pic> pics) {
String insert="insert into pic(savepath,realname,uploadtime,flag,stuid) values (?,?,?,?,?)";
List<Object[]> list = new ArrayList<>();
for(Pic p:pics){
Object[] obj = new Object[5];
obj[0] = p.getSavepath();
obj[1] = p.getRealname();
obj[2] = p.getUploadtime();
obj[3] = p.getFlag();
obj[4] = p.getStuid();
list.add(obj);
}
//批量操作
jt.batchUpdate(insert,list);
}
//查询行的数值
@Override
public int countStu(StudentVo vo) {
String sql = "select count(*) as s1 from student where 1=1";
if(vo!=null && !StringUtils.isNullOrEmpty(vo.getName())){
sql += " and name like '%"+vo.getName()+"%'";
}
if (vo!=null && vo.getSchid()!=null){
sql+=" and schid="+vo.getSchid();
}
if(vo!=null && !StringUtils.isNullOrEmpty(vo.getStartbirth())){
sql+=" and birth>= date_format('"+vo.getStartbirth()+"','%Y-%m-%d')";
}
if (vo!=null && !StringUtils.isNullOrEmpty(vo.getEndbirth())){
sql+=" and birth<= date_format('"+vo.getEndbirth()+"','%Y-%m-%d')";
}
//{count(*):8}
Long count = jt.queryForObject(sql, new SingleColumnRowMapper<Long>());
return count.intValue();
}
//返回的集合的元素是Map
@Override
public List<Sc> queryCourseAndScoreByStu(int stuid) {
String sql = "select sc.id as scid,sc.score,c.id,c.name,c.code from student s left join sc on s.id " +
"= sc.sid left join course c on c.id = sc.cid where s.id = ?";
List<Map<String,Object>> data = jt.query(sql,new ColumnMapRowMapper(),stuid);
List<Sc> result = new ArrayList<>();
for(Map<String,Object> d : data){
Sc sc = new Sc();
if(d.get("scid")==null){
return null;
}
sc.setId(Integer.parseInt(d.get("scid")+""));
sc.setScore(Integer.parseInt(d.get("score")+""));
Course course = new Course();
course.setId(Integer.parseInt(d.get("id")+""));
course.setName(d.get("name")+"");
course.setCode(d.get("code")+"");
sc.setCourse(course);
result.add(sc);
}
return result;
}
//编写逻辑拼写 in (?,?,?)语句
@Override
public List<Student> queryStuByIds(List<Integer> data) {
String sql = "select * from student where id in (";
int k = 1;
for (Integer d : data){
sql+= d + (k==data.size()?")":",");
k++;
}
List<Student> result = jt.query(sql,new BeanPropertyRowMapper<Student>(Student.class));
return result;
}
}