本文介绍: 对于使用JdbcTemplate进行数据库交互,则使用DataSourceTransactionManager实现类,如果整合Hibernate框架使用HibernateTransactionManager实现类,具体情况具体使用。@Nullable注解可以用在方法上,属性上,参数上,表示方法返回值可以为空属性可以为空,参数可以为空。如果把@Transactional添加在类上面,这个类里面所有方法都添加事务事务四个特性ACID:原子性,一致性隔离性,持久性配置JdbcTemplate对象

一、JdbcTemplate

(1)增删操作

int update(String sql, Object... args);

(2)查询返回某个值

T queryForObject(String sql,Class<T> requiredType);

(4)查询返回集合

List<T> query(String sql,RowMapper<T> rowMapper,Object... args);

(5)批量增删改:

int[]batchUpdate(String sql,List<Object[]> batchArgs);1

举例:

  1. 引入相关jar

  1. 配置数据库连接池配置JdbcTemplate对象

<context:component-scan base-package="com.oymn"></context:component-scan>

<!--配置数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="url" value="jdbc:mysql://localhost:3306/book" />
    <property name="username" value="root" />
    <property name="password" value="000000" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>

<!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--注入数据库连接池-->
    <property name="dataSource" ref="dataSource"></property>
</bean>
  1. 创建Service类和Dao类,在Dao类中注入JdbcTemplate对象

public interface BookDao {

    public void add(Book book);  //添加图书

    public void update(Book book);  //修改图书

    public void delete(int id);  //删除图书

    public int queryCount();   //查询数量

    public Book queryBookById(int id);  //查询本书

    public List<Book> queryBooks();   //查询所有书

    public void batchAddBook(List<Object[]> books);  //批量添加图书

    public void batchUpdateBook(List<Object[]> books);  //批量修改图书

    public void batchDeleteBook(List<Object[]> args);  //批量删除图书
}
@Repository
public class BookDaoImpl implements BookDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void add(Book book) {
        String sql = "insert into t_book set name=?,price=?";
        Object[] args = {book.getBookName(),book.getBookPrice()};
        int update = jdbcTemplate.update(sql, args);
        System.out.println(update);
    }

    @Override
    public void update(Book book) {
        String sql = "update t_book set name=?,price=? where id=?";
        Object[] args = {book.getBookName(),book.getBookPrice(),book.getBookId()};
        int update = jdbcTemplate.update(sql, args);
        System.out.println(update);
    }

    @Override
    public void delete(int id) {
        String sql = "delete from t_book where id=?";
        int update = jdbcTemplate.update(sql, id);
        System.out.println(update);
    }

    @Override
    public int queryCount() {
        String sql = "select count(*) from t_book";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        return count;
    }

    @Override
    public Book queryBookById(int id) {
        String sql = "select id bookId,name bookName,price bookPrice from t_book where id=?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
        return book;
    }

    @Override
    public List<Book> queryBooks() {
        String sql = "select id bookId,name bookName,price bookPrice from t_book";
        List<Book> bookList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
        return bookList;
    }

    @Override
    public void batchAddBook(List<Object[]> books) {
        String sql = "insert into t_book set id=?,name=?,price=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, books);
        System.out.println(ints);
    }

    @Override
    public void batchUpdateBook(List<Object[]> books) {
        String sql = "update t_book set name=?,price=? where id=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, books);
        System.out.println(ints);
    }

    @Override
    public void batchDeleteBook(List<Object[]> args) {
        String sql = "delete from t_book where id=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, args);
        System.out.println(ints);
    }
}
@Service
public class BookService {
    @Autowired
    private BookDao bookDao = new BookDaoImpl();
    //添加图书
    public void add(Book book){
        bookDao.add(book);
    }
    //修改图书
    public void update(Book book){
        bookDao.update(book);
    }
    //删除图书
    public void delete(Integer id){
        bookDao.delete(id);
    }
    //查询数量
    public int queryCount(){
        return bookDao.queryCount();
    }
    //查询图书
    public Book queryBookById(Integer id){
        return bookDao.queryBookById(id);
    }
    //查询所有图书
    public List<Book> queryBooks(){
        return bookDao.queryBooks();
    }
    //批量添加图书
    public void batchAddBook(List<Object[]> books){
        bookDao.batchAddBook(books);
    }
    //批量修改图书
    public void batchUpdateBook(List<Object[]> books){
        bookDao.batchUpdateBook(books);
    }
    //批量删除图书
    public void batchDeleteBook(List<Object[]> args){
        bookDao.batchDeleteBook(args);
    }
}

二、事务管理

(1)注解实现声明式事务管理:

<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      destroy-method="close">
    <property name="url" value="jdbc:mysql://localhost:3306/book" />
    <property name="username" value="root" />
    <property name="password" value="000000" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>

<!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--注入数据库连接池-->
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

service类上面或者service类的方法上面添加事务注解@Transactional

  • 如果把@Transactional添加在类上面,这个类里面所有方法都添加事务。

  • 如果只是添加在方法上面,则只为这个方法添加事务。

@Service
@Transactional
public class UserService {

声明式事务管理的参数配置:

  1. propagation:事务传播行为,总共有7种,这一块讲的不是很清楚

  1. isolation:事务隔离级别

有三个读问题:脏读,不可重复读,虚读(幻读)。

设置隔离级别解决问题

脏读

不可重复

虚读

READ UNCOMMITED(读未提交

READ COMMITED(读已提交

REPEATABLE READ(可重复读)

SERIALIZABLE(串行化

  1. timeout超时时间

  1. readOnly是否只读

  • 设置为true,只能查询。

  1. rollbackFor回滚,设置出现哪些异常进行事务回滚。

  1. noRollbackFor:不回滚,设置出现哪些异常不进行事务回滚。

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
public class AccountService {

完全注解实现声明式事务管理:

配置类:

@Configuration  //配置类
@ComponentScan(basePackages = "com.oymn.spring5")  //开启组件扫描
@EnableTransactionManagement  //开启事务
public class Config {

    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/book");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("000000");
        return druidDataSource;
    }
    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
@Service
public class AccountService {

    @Autowired
    private AccountDao accountDao;

    @Transactional
    public void accountMoney(){
        accountDao.add();
        //int i=1/0;   //用来模拟转账失败
        accountDao.reduce();
    }
}

(2)xml实现声明式事务管理:

<context:component-scan base-package="com.oymn"></context:component-scan>

<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      destroy-method="close">
    <property name="url" value="jdbc:mysql://localhost:3306/book" />
    <property name="username" value="root" />
    <property name="password" value="000000" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>

<!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--注入数据库连接池-->
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--配置事务通知-->
<tx:advice id="txadvice">
    <!--配置事务参数-->
    <tx:attributes>
        <tx:method name="accountMoney" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<!--配置切入点和切面-->
<aop:config>
    <!--配置切入点-->
    <aop:pointcut id="pt" expression="execution(* com.oymn.spring5.Service.*.*(..))"/>
    <!--配置切面-->
    <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>

三、Spring5新特性

1. 自带日志封装

Spring5整合Log4j2:

一步引入jar

第二步:创建log4j2.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status用于设置log4j2自身内部信息输出可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出-->
<configuration status="INFO">
    <!--先定义所有的appender-->
    <appenders>
        <!--输出日志信息控制台-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制日志输出格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </console>
    </appenders>
    <!--然后定义logger,只有定义logger引入appender,appender才会生效-->
    <!--root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认日志输出-->
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>
2. @Nullable注解
@Nullable     //表示方法返回值可以为空
public int getId();

@Nullable     //表示参数可以为空
public void setId(@Nullable int Id);

@Nullable     //表示属性可以为空
public int id;
3. 支持函数风格编程

这是因为java8新增了lamda表达式

@Test
public void test() {
    //1 创建 GenericApplicationContext 对象
    GenericApplicationContext context = new GenericApplicationContext();
    //2 调用 context 的方法对象注册
    context.refresh();
    context.registerBean("user1",User.class,() -> new User());
    //3 获取spring 注册的对象
    // User user = (User)context.getBean("com.atguigu.spring5.test.User");
    User user = (User)context.getBean("user1");
    System.out.println(user);
}
4. 支持整合JUnit5

(1)整合JUnit4:

一步:引入jar

第二步:创建测试类,使用注解方式完成

@RunWith(SpringJUnit4ClassRunner.class) //单元测试框架
@ContextConfiguration("classpath:bean4.xml") //加载配置文件
public class JUnitTest {

    @Autowired
    public User user;

    @Test
    public void test(){
        System.out.println(user);
    }
}

bean4.xml

<context:component-scan base-package="com.oymn"></context:component-scan>

通过使用@ContextConfiguration注解,测试方法中就不用每次都通过context获取对象了,比较方便。

ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
BookService bookService = context.getBean("bookService",BookService.class);

(2)整合JUnit5:

5. Webflux

原文地址:https://blog.csdn.net/qq_62594984/article/details/129235108

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_27602.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注