Spring入门后半部分----JDBCTemplate和事务控制

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring入门后半部分----JDBCTemplate和事务控制相关的知识,希望对你有一定的参考价值。

JDBCTemplate和事物控制

Spring入门前半部分

JDBCTemplate基本使用,承接上半部分

抽取数据库连接池配置时填入的参数,放到properties配置文件中

properties配置文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test1
jdbc.username=root
jdbc.password=126433

在Spring容器中引入pro配置文件,然后修改刚才传入的参数—配置数据库的模板

注意: ${}取出配置文件中的值 ,#{}是Spring的表达式语言

    <!--加载jdbc.properties-->
<!--引入context命名空间-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--数据源对象-->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
         <property name="driverClass" value="${jdbc.driver}"/>
         <property name="jdbcUrl" value="${jdbc.url}"/>
         <property name="user" value="${jdbc.username}"/>
         <property name="password" value="${jdbc.password}"/>
     </bean>
   <!--jdbc模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
    </bean>

在主类中向数据库插入数据

public class jdbc {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
        int row = jt.update("insert account values (?,?),(?,?)", "大忽悠", 8000, "小朋友", 6000);
        System.out.println("影响的行数"+row);
    }
}

批量插入的方法

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
        String sql="insert into account values(?,?)";
        //List<Object[]>
        //List的长度就是sql语句要执行的次数
        //Object[]:每次执行要用的参数
        ArrayList<Object[]> obj = new ArrayList<Object[]>();
        obj.add(new Object[]{"张三",7000});
        obj.add(new Object[]{"李四",8000});
        obj.add(new Object[]{"王五",9000});
        obj.add(new Object[]{"赵六",6000});
        //返回的是一个数组,表示每条sql语句影响的行数
        int[] is = jt.batchUpdate(sql, obj);
        for(int i:is)
            System.out.println("影响的行数:"+i);

在这里插入图片描述
在这里插入图片描述


查询某条记录,封装为一个java对象,并返回

JavaBean对象的属性名需要和数据库中的字段名一致,否则无法完成数据的封装,当前也可以在编写查询sql语句的时候,通过对数据库每列的名称起一个别名,来达到封装的目的

这里的属性名依旧是set方法,去掉set,首字母小写得到的字符串,因此set方法必不可少

jdbcTemplate在方法级别进行了区分: 查询集合,查询单个对象

  • 查询集合: jt.query();
  • 查询单个对象:jt.queryForObject(); 如果查询没结果就会报错,如果查询出来多个结果也会报错

friend类:

public class friend {
    String name;
    Integer money;

    public void setName(String name) {
        this.name = name;
    }

    public void setMoney(Integer money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "friend{" +
                "name='" + name + '\\'' +
                ", money=" + money +
                '}';
    }
}

主类:

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
          String sql="SELECT * FROM account WHERE NAME=?";
          //RowMapper: 每一条记录和javabean的属性和数据库里面一行记录进行映射
          friend f=null;
        f = jt.queryForObject(sql, new BeanPropertyRowMapper<friend>(friend.class), "张三");
        System.out.println(f);

在这里插入图片描述


查询集合

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
          String sql="SELECT * FROM account ";
          //封装为List:集合里面的元素类型
        List<friend> query = jt.query(sql, new BeanPropertyRowMapper<friend>(friend.class));
          for(friend e:query)
          {
              System.out.println(e);
          }

在这里插入图片描述


查询单条数据

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
          String sql="SELECT MAX(money) FROM account";
          //无论是返回单个数据还是单个对象,都是调用queryForObject
        Integer moneyMax = jt.queryForObject(sql, Integer.class);
        System.out.println("最高工资为:"+moneyMax);

在这里插入图片描述


使用带有具名参数的sql语句插入一条员工记录,并以Map的形式传入参数值

具名参数: (具有名字的参数,参数不是一个占位符了,而是以个变量名)

语法格式 --------------------> :参数名

需要使用spring的一个支持具名参数的springTemplate类

占位符参数: ?的顺序不能乱,传参的时候要注意

以map的形式传入参数

代码:

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
        NamedParameterJdbcTemplate npjt = app.getBean(NamedParameterJdbcTemplate.class);
        String sql="insert into account(name,money) values(:name,:money)";
        //将有具名参数的值都放在map容器中
        Map<String, Object> Map = new HashMap<String,Object>();
          Map.put("name","大忽悠");
          Map.put("money",8000);
        int row = npjt.update(sql,Map);
        System.out.println("影响的行数:"+row);

在这里插入图片描述


以SqlParameterSource的形式传入参数

使用该方法前,要确保自定义类中有get方法,因为该方法实现原理是从传入的对象中,找对象的get方法,去掉get,首字母小写,看得到的字符串是否和具名参数匹配.

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        JdbcTemplate jt = app.getBean(JdbcTemplate.class);
        NamedParameterJdbcTemplate npjt = app.getBean(NamedParameterJdbcTemplate.class);
        String sql="insert into account(name,money) values(:name,:money)";
           friend f=new friend();
           f.setMoney(20000);
           f.setName("小朋友");
        int row = npjt.update(sql, new BeanPropertySqlParameterSource(f));
        System.out.println("影响的行数"+row);

在这里插入图片描述


使用注解完成对JdbcTemplate的注入----小规模常用

test类:

@Component("test")
public class test {
    @Autowired //按照类型注入
   private JdbcTemplate jdbcTemplate;
    int getJBDCTemplate(friend f)
    {
        int row = jdbcTemplate.update("insert into account values(?,?)", f.getName(), f.getMoney());
        return row;
    }
}

jdbc测试类:

        ApplicationContext app = new ClassPathXmlApplicationContext("appOfDao.xml");
        test t=(test)app.getBean("test");
        friend f=new friend();
        f.setName("超级大忽悠");
        f.setMoney(40000);
        int row = t.getJBDCTemplate(f);
        System.out.println("影响的行数"+row);

配置文件:

<!--组件扫描-->
    <context:component-scan base-package="com.jdbcTemplate"/>
        <!--数据源对象-->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
         <property name="driverClass" value="${jdbc.driver}"/>
         <property name="jdbcUrl" value="${jdbc.url}"/>
         <property name="user" value="${jdbc.username}"/>
         <property name="password" value="${jdbc.password}"/>
     </bean>

   <!--jdbc模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
    </bean>

在这里插入图片描述


声明式事务

数据库环境搭建—账户表,图书表,图书库存表

account账号表:
在这里插入图片描述

book图书表:
在这里插入图片描述

book_stock图书库存表:
在这里插入图片描述

jdbc.properties的配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tx
jdbc.username=root
jdbc.password=126433

数据源配置并直接注入到jdbcTemplate中

    <!--加载jdbc.properties-->
    <!--引入context命名空间-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
     <!--组件扫描-->
    <context:component-scan base-package="com.BookCheck"/>
    <!--数据源对象-->
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
         <property name="driverClass" value="${jdbc.driver}"/>
         <property name="jdbcUrl" value="${jdbc.url}"/>
         <property name="user" value="${jdbc.username}"/>
         <property name="password" value="${jdbc.password}"/>
     </bean>

   <!--jdbc模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
    </bean>

Dao层和Service层的类环境搭建

BookDao类:

@Repository
public class BookDao {
    @Autowired
   private JdbcTemplate jdbcTemplate;
    /*减去某个用户的剩余金额*/
    public void updateBalance(String username,int price)
    {
        String sql="update account set money=money-? where name=?";
         jdbcTemplate.update(sql,price,username);
    }
    /*获取某本图书的价格*/
    public int getBookPrice(String isbn)
    {
          String sql="select price from book where ISBN=?";
       return jdbcTemplate.queryForObject(sql, Integer.class,isbn);
    }
    /*减去某本书库存*/
    public void updateStock(String isbn)
    {
        String sql="update book_stock set stock=stock-1 where isbn=?";
        jdbcTemplate.update(sql,isbn);
    }
}

Service类:

@Service
public class BookService {
    @Autowired
    BookDao bookDao;
    /*结账*/
    public void checkOut(String username,String isbn)
    {
        //1.减去库存
        bookDao.updateStock(isbn);
        //2.获取图书的价格
        int bookPrice = bookDao.getBookPrice(isbn);
        //3.减去余额
        bookDao.updateBalance(username,bookPrice);
    }

}

主类:

public class test {
  static  ApplicationContext ioc= new ClassPathXmlApplicationContext("appOfDao.xml");
    public static void main(String[] args) {
        如何根据纪元时间获得前半部分和后半部分('attempt updated_at' 列)

前半部分透明,后半部分标题的按钮

将动态数组的前半部分复制到后半部分在 C 中失败?

CTFshow—web入门21-28(爆破)

c语言中如何只清屏后半部分保留前半部分?

Spring Security与Tomcat基本授权冲突