Spring中JDBCTemplate的入门
Spring是IOC和AOP的容器框架,一站式的框架
连接数据库的步骤:[必须会写]
Spring当中如何配置连接数据库?
第一步配置核心配置文件:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 启动Spring注解 -->
<context:annotation-config/>
<!-- 扫描,如果有多个使用逗号分隔 -->
<context:component-scan base-package="com.shxt"/>
<!-- 加载属性文件,classpath和classpath*的区别 -->
<context:property-placeholder location="classpath:/jdbc.properties"/>
<!-- 配置数据源信息 -->
<bean id="shxtDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置完成 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="shxtDataSource"/>
</bean>
</beans>
package com.shxt.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class JDBCTest {
private ApplicationContext ac =null;
private JdbcTemplate jdbcTemplate = null;
@Before
public void init(){
//读取核心配置文件
ac = new ClassPathXmlApplicationContext("beans.xml");
//获取JdbcTemplate对象,通过id的方式, JdbcTemplate.class就是强转
jdbcTemplate = ac.getBean("jdbcTemplate",JdbcTemplate.class);//强转
}
@Test
public void 添加角色的操作_第一种方式(){
String sql = "insert into sys_role(role_name,role_desc) values ('悟空','齐天大圣')";
//不正规
//默认情况下JDBC的事务是自动提交的,而大部分的持久层框架是需要手动提交的
int rownum = jdbcTemplate.update(sql);//delete/update/insert的sql语句
System.out.println(rownum);
}
}
代码优化
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 启动Spring注解 -->
<context:annotation-config/>
<!-- 扫描,如果有多个使用逗号分隔 -->
<context:component-scan base-package="com.shxt"/>
<!-- 加载属性文件,classpath和classpath*的区别 -->
<context:property-placeholder location="classpath:/jdbc.properties"/>
<!-- 配置数据源信息 -->
<bean id="shxtDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driver}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"
/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="shxtDataSource"
/>
</beans>
代码说明:
<bean id="shxtDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName[对应的是set方法]="${jdbc.driver}"
p:url[对应的是set方法]="${jdbc.url}" p:username[对应的是set方法]="${jdbc.username}"
p:password[对应的是set方法]="${jdbc.password}"
/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource[对应的是set方法]-ref[引用]="shxtDataSource"
/>
@Test
public void 添加角色的操作_第二种方式_推荐方式_预处理方式(){
String sql = "insert into sys_role(role_name,role_desc) values (?,?)";
//int rownum = jdbcTemplate.update(sql, new Object[]{"八戒","天蓬元帅"});
int rownum = jdbcTemplate.update(sql, "八戒","天蓬元帅");
System.out.println(rownum);
}
如果使用Hibernate或者Mybatis类似的持久层框架,他们都可以通过配置返回你添加数据的主键
Mybatis是如何配置?请补充代码,映射文件内容
---->>>> 如果涉及到Oracle数据库,建议使用官方写法,因为Oracle没有自增长的字段,是通过序列完成自增长操作
final String INSERT_SQL = "insert into my_test (name) values(?)"; // 老版本因为是内部类,所有需要使用final
final String name = "Rob"; KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(INSERT_SQL, new String[] {"id"});//id为主键字段
ps.setString(1, name);//PreparedStatement 1代表第一个问好
return ps;
}
},
keyHolder); // keyHolder.getKey() now contains the generated key
@Test
public void 添加角色的操作_关于主键_前提必须使用自增长的方式(){
String sql = "insert into sys_role(role_name,role_desc) values (?,?)";
Role role = new Role();
role.setRole_name("唐僧");
role.setRole_desc("金蝉子");
KeyHolder keyHolder = new GeneratedKeyHolder();//使用Ctrl+T的方式,看KeyHolder的实现类
jdbcTemplate.update(new PreparedStatementCreator() {
@Override //一期内容
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
//1.获取预处理对象
PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, role.getRole_name());//注意 1代表的是第一个问号
ps.setString(2, role.getRole_desc());//注意 2代表的是第二个问号
return ps;
}
}, keyHolder);
int pk = keyHolder.getKey().intValue();//getKey()返回为Number类型
role.setRole_id(pk);
System.out.println(role.getRole_id());
}
关于更新操作和删除操作类似,如果涉及到批量添加和更新问题,请自行扩展学习
测试查询操作:
@Test
public void 通过查询返回单一的值(){
String sql = "select count(*) from sys_role where role_name like ?";
Integer count = jdbcTemplate.queryForObject(sql, Integer.class, "%1%");//Integer.class 强转
//Integer count = jdbcTemplate.queryForObject(sql, new Object[]{"%员%"}, Integer.class);
System.out.println(count);
}
返回一条数据的形式:
@Test
public void 返回一条数据_Map形式(){
String sql = "select * from sys_role where role_id=?";
Map<String,Object> map = jdbcTemplate.queryForMap(sql, 405);
System.out.println(map);
}
@Test
public void 返回一条数据_对象形式(){
String sql = "select * from sys_role where role_id=?";//一期关系
Role role = jdbcTemplate.queryForObject(sql, new Object[]{405},new RowMapper<Role>(){
@Override //Java的内部类?匿名类?
public Role mapRow(ResultSet rs, int rowNum) throws SQLException {
Role role = new Role();
role.setRole_id(rs.getInt("role_id"));
role.setRole_name(rs.getString("role_name"));
role.setRole_desc(rs.getString("role_desc"));
role.setRole_photo(rs.getString("role_photo"));
role.setRole_status(rs.getString("role_status"));
return role;
}
});
System.out.println(role);
}
返回列表数据
@Test
public void 返回列表数据_List_Map形式(){
String sql = "select * from sys_role where role_name like ?";
List<Map<String,Object>> dataList = jdbcTemplate.queryForList(sql, "%1%");
System.out.println(dataList);
}
@Test
public void 返回列表数据_List_对象形式(){
String sql = "select * from sys_role where role_name like ?";
List<Role> roleList = jdbcTemplate.query(sql, new Object[]{"%员%"}, new RowMapper<Role>(){
@Override
public Role mapRow(ResultSet rs, int rowNum) throws SQLException {
Role role = new Role();
role.setRole_id(rs.getInt("role_id"));
role.setRole_name(rs.getString("role_name"));
role.setRole_desc(rs.getString("role_desc"));
role.setRole_photo(rs.getString("role_photo"));
role.setRole_status(rs.getString("role_status"));
return role;
}
});
System.out.println(roleList);
}
我们发现 返回列表数据_List_对象形式()和返回一条数据_对象形式() 中的代码有重复性质!
public class RoleRowMapper implements RowMapper<Role> {
@Override
public Role mapRow(ResultSet rs, int rowNum) throws SQLException {
Role role = new Role();
role.setRole_id(rs.getInt("role_id"));
role.setRole_name(rs.getString("role_name"));
role.setRole_desc(rs.getString("role_desc"));
role.setRole_photo(rs.getString("role_photo"));
role.setRole_status(rs.getString("role_status"));
return role;
}
}
@Test
public void 返回一条数据_对象形式_优化(){
String sql = "select * from sys_role where role_id=?";//一期关系
Role role = jdbcTemplate.queryForObject(sql, new Object[]{405},new RoleRowMapper()); //实现类
System.out.println(role);
}
@Test
public void 返回列表数据_List_对象形式_优化(){
String sql = "select * from sys_role where role_name like ?";
List<Role> roleList = jdbcTemplate.query(sql, new Object[]{"%员%"}, new RoleRowMapper()); //实现类
System.out.println(roleList);
}
个人推荐: 超精简版[自己命名的,私人珍藏],通过领域模型自动完成映射
@Test //你需要保持数据库的字段名和属性名保持一致,[没有说完全一致]
public void 返回一条数据_对象形式_超精简版(){
String sql = "select * from sys_role where role_id=?";//一期关系
Role role = jdbcTemplate.queryForObject(sql, new Object[]{405},new BeanPropertyRowMapper<Role>(Role.class));
System.out.println(role);
}
@Test
public void 返回列表数据_List_对象形式_超精简版(){
String sql = "select * from sys_role where role_name like ?";
List<Role> roleList = jdbcTemplate.query(sql, new Object[]{"%员%"}, new BeanPropertyRowMapper<Role>(Role.class));
System.out.println(roleList);
}
@Test
public void 返回列表数据_List_对象形式_超精简版_一致的解释(){
String sql = "select role_name , role_desc role_photo1 from sys_role";
List<Role> roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Role>(Role.class));
System.out.println(roleList);
}
模拟权限分配操作
@Test
public void 权限分配() throws Exception{
//1.客户端复选框传递过来一个数组 1,2 菜单的ID
Integer[] menus = new Integer[]{1,2};
//2.声明数组
String[] sqls = new String[menus.length+1];//0,1,2
//3.通过ROle_Id 200 删除中间表的信息
sqls[0] = "delete from role_link_menu where fk_role_id=200";//
//3.新数据添加到中间表
for (int i=0;i<menus.length;i++) {
//1,2
sqls[i+1] = "insert into role_link_menu (id,fk_role_id,fk_menu_id) values ('"+UUID.randomUUID().toString()+"',200,"+menus[i]+")";
}
jdbcTemplate.batchUpdate(sqls);
//MyBatis的实现方式
}
-----------------------------------------
********等价操作*********
-----------------------------------------
通过MyBatis的实现方式,自学内容,MySQL下的操作,设置如下!
&allowMultiQueries=true 新增内容如下:
shxt.driver=com.mysql.jdbc.Driver shxt.url=jdbc:mysql://127.0.0.1:3308/xy37_rbac??useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true shxt.username=root shxt.password=shxt
接口中定义方法,如下推荐使用Map public void permission(Map<String,Object> map);
映射文件代码如下:
<delete id="permission" parameterType="map" statementType="PREPARED">
DELETE FROM role_link_menu WHERE fk_role_id=#{role_id};
<foreach collection="menus" item="menu_id" >
INSERT INTO role_link_menu (id, fk_role_id, fk_menu_id) VALUES ((SELECT UUID()),#{role_id},#{menu_id});
</foreach>
</delete>
测试代码:
@Test
public void 多条SQL语句执行(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlSession();
Map<String, Object> map = new HashMap<String,Object>();
map.put("role_id", 200);
map.put("menus", new Object[]{1,2,3,6});
sqlSession.getMapper(UserMapper.class).permission(map);
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
Spring中JDBCTemplate的入门的更多相关文章
- Spring中IoC的入门实例
Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如 ...
- Spring 中jdbcTemplate 实现执行多条sql语句
说一下Spring框架中使用jdbcTemplate实现多条sql语句的执行: 很多情况下我们需要处理一件事情的时候需要对多个表执行多个sql语句,比如淘宝下单时,我们确认付款时要对自己银行账户的表里 ...
- Spring中JdbcTemplate的基础用法
Spring中JdbcTemplate的基础用法 1.在DAO中使用JdbcTemplate 一般都是在DAO类中使用JdbcTimplate,在XML配置文件中配置好后,可以在DAO中注入即可. 在 ...
- 【sping揭秘】19、关于spring中jdbctemplate中的DataSource怎么来呢
我们这是可以正好借助之前学的factorybean类,自己吧jdbctemplate加载到spring容器中,我们可以封装多个这种对象,那么可以实现针对不同的数据库的jdbctemplate 首先我们 ...
- 2018.12.25 Spring中JDBCTemplate模版API学习
1 Spring整合JDBC模版 1.1 spring中土拱了一个可以操作数据库的对象.对象封装了jdbc技术 JDBCTemplateJDBC模板对象 1.2 与DBUtils中的QueryRunn ...
- SSM-Spring-19:Spring中JdbcTemplate
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- Spring自带一个ORM持久化框架JdbcTemplate,他可以说是jdbc的加强版,但是对最细微的控制肯 ...
- Spring中JdbcTemplate中使用RowMapper
转自:https://blog.csdn.net/u012661010/article/details/70049633 1 sping中的RowMapper可以将数据中的每一行数据封装成用户定义的类 ...
- Spring中jdbcTemplate的用法实例
一.首先配置JdbcTemplate: 要使用Jdbctemplate 对象来完成jdbc 操作.通常情况下,有三种种方式得到JdbcTemplate 对象. 第一种方式:我们可以在自己定 ...
- spring中JdbcTemplate使用
1.maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
随机推荐
- 一个最不可思议的MySQL死锁分析
1 死锁问题背景 1 1.1 一个不可思议的死锁 1 1.1.1 初步分析 3 1.2 如何阅读死锁日志 3 2 死锁原因深入剖析 4 2. ...
- 各大IT企业招聘所须要求技能
1.中兴 ZTE 软件研发project师 工作地点:西安.深圳.上海.天津 主要职责: 1.从事通讯产品相关软件开发 2.进行软件具体设计,代码编写.单元測试.集成測试.系统測试等 3.进行软件代码 ...
- ubuntu下安装RemixOS双系统(Android x86)
这篇文章主要讲在怎样在ubuntu下安装RemixOS pc版(Android x86版本号),下面两种做法的思路都适合安装不论什么版本号的Android x86版本号到ubuntu系统上,仅仅须要改 ...
- 泛泰A820L (高通MSM8660 cpu) 3.4内核的CM10.1(Android 4.2.2) 測试版第二版
欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...
- try/catch的用法
1.try/catch用法基础介绍 try { //程序中抛出异常 throw value; } catch(valuetype v) { //例外处理程序段 } 语法小结:throw抛出值,catc ...
- noip 2018 day1 T2 货币系统 完全背包
Code: #include<cstdio> #include<string> #include<cstring> #include<algorithm> ...
- 一个project师该怎样高效工作
1. 静. 在千头万绪,百般push.各种IM电话邮件狂轰滥炸中保持一个静字.找到最适合如今做的事情,情绪不要被外界所干扰.一次仅仅做一件事,不要被打断. 有的公司土鳖文化严重,领导一会儿要求你干这 ...
- HDU 2846 Repository (字典树 后缀建树)
Repository Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- JavaLearning:日期操作类
package org.fun.classdemo; import java.util.Calendar; import java.util.GregorianCalendar; public cla ...
- KETTLE使用javascript步骤过滤特殊字符
KETTLE使用javascript步骤过滤特殊字符 使用kettle在抽取大量excel数据时.总是遇到excel中有一些特殊字符,导致ExecuteSQL script步骤运行失败,本文记录一些方 ...