zoukankan      html  css  js  c++  java
  • 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";//0
    
    //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);
    
    }
    
    }
    复制代码
     
  • 相关阅读:
    找不到vc_runtimeMinimum_x86.msi!
    ubuntu开启coredump
    log4j2项目打成jar包运行日志无法打印
    linux 下使用 tc 模拟网络延迟和丢包
    Spring MVC
    typora实现图片上传
    java异常和调优
    java线程
    java三大特征
    webstorm如何更换主题以及更换主题后字体缩放问题
  • 原文地址:https://www.cnblogs.com/smallfa/p/10640652.html
Copyright © 2011-2022 走看看