• 第9章 Spring的数据库编程


    目录/Contents

    第9章 Spring的数据库编程

    学习目标

    1.了解JdbcTemplate类的作用
    2.熟悉Spring JDBC的配置
    3.熟悉JdbcTemplate的增删改查操作
    4.理解Spring事务管理
    5.掌握基于XML方式的声明式事务
    6.熟悉基于注解方式的声明式事务

    学习内容

    1 Spring JDBC

    1.1 JDBCTemplate概述
    1.1.1 JDBCTemplate作用

    针对数据库操作,Spring框架提供了JdbcTemplate类,JdbcTemplate是一个模板类,Spring JDBC中的更高层次的抽象类均在JdbcTemplate模板类的基础上创建。 JdbcTemplate类提供了操作数据库的基本方法,包括添加、删除、查询和更新。在操作数据库时,JdbcTemplate类简化了传统JDBC中的复杂步骤,这可以让开发人员将更多精力投入到业务逻辑中。

    1.1.2 抽象类JdbcAccessor的属性

    JdbcTemplate类继承自抽象类JdbcAccessor,同时实现了JdbcTemplate接口。抽象类JdbcAccessor提供了一些访问数据库时使用的公共属性,具体如下:
    DataSource:DataSource主要功能是获取数据库连接。在具体的数据操作中,它还提供对数据库连接的缓冲池和分布式事务的支持。SQLExceptionTranslator:SQLExceptionTranslator是一个接口,它负责对SQLException异常进行转译工作。

    1.2 Spring JDBC的配置
    1.2.1 Spring JDBC中的4个包说明

    在这里插入图片描述

    Spring对数据库的操作都封装在了core、dataSource、object和support这4个包中,想要使用Spring JDBC,就需要对这些包进行配置。

    在Spring中,JDBC的配置是在配置文件applicationContext.xml中完成的,包括配置数据源、配置JDBC模板和配置注入类

    <!-- 1.配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
         <!-- 数据库驱动 -->
         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
         <!-- 连接数据库url -->
         <property name="url" value="jdbc:mysql://localhost:3306/spring"/>
         <property name="username" value="root"/><!-- 连接数据库用户名 -->
         <property name="password" value="root"/><!-- 连接数据库密码 -->
    </bean>
    <!-- 2.配置JDBC模板 -->
    <bean id="JdbcTemplate"   class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 3.配置注入类 -->
    <bean id="xxx" class="Xxx">	<property name="JdbcTemplate" ref="JdbcTemplate"/></bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1.2.2 dataSource配置4个属性的含义

    在这里插入图片描述

    1.2.3 dataSource属性值的设定要求

    在dataSource的4个属性中,需要根据数据库类型或者系统配置设置相应的属性值。例如,如果数据库类型不同,需要更改驱动名称;如果数据库不在本地,则需要将地址中的localhost替换成相应的主机IP;默认情况下,数据库端口号可以省略,但如果修改过MySQL数据库的端口号,则需要加上修改后的端口号。此外,连接数据库的用户名和密码需要与数据库创建时设置的用户名和密码保持一致。

    2 JdbcTemplate的常用方法

    2.1 excute()方法
    2.1.1 excute()语法格式

    execute()方法用于执行SQL语句,其语法格式如下:

    jdTemplate.execute("SQL 语句");
    
    • 1
    2.2 演示excute()方法的使用
    STEP 01

    创建数据库:在MySQL中,创建一个名为spring的数据库。

    在这里插入图片描述

    STEP 02

    创建项目并引入依赖:在IDEA中创建一个名为chapter09的Maven项目,然后在pom.xml文件中加载使用到的Spring
    基础包、Spring依赖包、MySQL数据库的驱动JAR包、Spring JDBC的JAR包和Spring事务处理的JAR包。

    <!– 这里只展示了其中一个JAR包-->
    <!-- MySQL数据库驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
                <scope>runtime</scope>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    STEP 03

    编写配置文件:在chapter09项目的src/main/resources目录下,创建配置文件applicationContext.xml,在该文件中配置数据源Bean和JDBC模板Bean,并将数据源注入到JDBC模板中。

    <!-- 1. 配置数据源 -->
    <bean id="dataSource" class= "org.springframework.jdbc.datasource.DriverManagerDataSource">
    	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
    	<property name="url" value="jdbc:mysql://localhost/spring" />
    	<property name="username" value="root" />
    	<property name="password" value="root" /></bean>
    <!-- 2. 配置 JDBC 模板 -->
    <bean id="jdbcTemplate" 	   class="org.springframework.jdbc.core.JdbcTemplate">
    	<property name="dataSource" ref="dataSource" /></bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    STEP 04

    编写测试类:创建测试类TestJdbcTemplate,在该类的main()方法中获取JdbcTemplate实例,然后调用execute()方法执行创建数据表的SQL语句。

    public class TestJdbcTemplate {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new
                ClassPathXmlApplicationContext("applicationContext.xml");
            JdbcTemplate jdTemplate =
                    (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
            jdTemplate.execute("create table account(" +
                    "id int primary key auto_increment," +
                    “username varchar(50)," + 	"balance double)");
            System.out.println("账户表account创建成功!");}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 05

    查看运行结果:在IDEA中启动TestJdbcTemplate类,再次查询spring数据库。

    在这里插入图片描述

    2.3 update()方法
    2.3.1 JdbcTemplate类中常用的update()方法

    在这里插入图片描述

    2.4 演示update()方法的使用
    STEP 01

    编写实体类:创建Account类,在该类中定义属性,以及其对应的getter/setter方法。

    public class Account {
           private Integer id;       	               // 账户id
           private String username; 	// 用户名
           private Double balance;  	// 账户余额
           // 省略gettter/setter方法
           public String toString() {
    	return "Account [id=" + id + ", "
    	+ "username=" + username + ", balance=" + balance + "]";}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    STEP 02

    编写Dao层接口:创建接口AccountDao,并在接口中定义添加、更新和删除账户的方法。

    public interface AccountDao {
    	// 添加
    	public int addAccount(Account account);
    	// 更新
    	public int updateAccount(Account account);
    	// 删除
    	public int deleteAccount(int id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    STEP 03

    实现Dao层接口:创建AccountDao接口的实现类AccountDaoImpl,并在类中实现添加、更新和删除账户的方法。

    public class AccountDaoImpl implements AccountDao {
          // 定义JdbcTemplate属性,此处省略setter方法
          private JdbcTemplate jdbcTemplate;
          // 这里只展示(添加账户)的操作
          public int addAccount(Account account) {
                String sql = "insert into account(username,balance) value(?,?)";
                Object[] obj = new Object[] {// 定义数组来存放SQL语句中的参数
                      account.getUsername(), account.getBalance() 	};
    	// 执行添加操作,返回的是受SQL语句影响的记录条数
                return this.jdbcTemplate.update(sql, obj);}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 04

    编写配置文件:在applicationContext.xml中,定义一个id为accountDao的Bean,用于将jdbcTemplate注入到accountDao实例中。

    <!--定义id为accountDao的Bean-->
    <bean id="accountDao" class="com.itheima.AccountDaoImpl">
              <!-- 将jdbcTemplate注入到accountDao实例中 -->
              <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    STEP 05

    测试添加功能:创建测试类TestAddAccount,该类主要用于添加用户账户信息。

    public class TestAddAcount {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new 
                ClassPathXmlApplicationContext("applicationContext.xml");
            AccountDao accountDao =
                    (AccountDao) applicationContext.getBean("accountDao");
            Account account = new Account();
            account.setUsername("tom");	account.setBalance(1000.00);
            int num = accountDao.addAccount(account);
            if (num > 0) { System.out.println("成功插入了" + num + "条数据!");
            } else { System.out.println("插入操作执行失败!"); }
    }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    STEP 06

    查看执行第5步后的运行结果:在IDEA中启动TestAddAccount类,控制台会输出结果。此时再次查询spring数据库中的account表。

    在这里插入图片描述

    STEP 07

    测试更新功能:执行完插入操作后,接下来调用JdbcTemplate类的update()方法执行更新操作。

    public class TestUpdateAccount {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new 
                ClassPathXmlApplicationContext("applicationContext.xml");
            AccountDao accountDao =
                    (AccountDao) applicationContext.getBean("accountDao");
            Account account = new Account();
            account.setId(1);	account.setUsername("tom");
            account.setBalance(2000.00);
            int num = accountDao.updateAccount(account);
            if (num > 0) {System.out.println("成功修改了" + num + "条数据!");
            } else {System.out.println("修改操作执行失败!");}	}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    STEP 08

    查看执行第7步后的运行结果:在IDEA中启动TestUpdateAccount类,控制台会输出结果。此时再次查询spring数据库中的account表。

    在这里插入图片描述

    STEP 09

    测试删除功能:创建测试类TestDeleteAccount,该类主要用于测试删除用户账户信息。

    public class TestDeleteAccount {
        public static void main(String[] args) {
            // 加载配置文件
            ApplicationContext applicationContext =new 
                ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取AccountDao实例
            AccountDao accountDao =
                    (AccountDao) applicationContext.getBean("accountDao");
            // 执行deleteAccount()方法,并获取返回结果
            int num = accountDao.deleteAccount(1);
            // 输出语句省略
    }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    STEP 10

    查看执行第9步后的运行结果:在IDEA中启动TestDeleteAccount类,控制台会输出结果。此时再次查询spring数据库中的account表。

    在这里插入图片描述

    2.5 query()方法
    2.5.1 JdbcTemplate类中常用的查询方法

    在这里插入图片描述

    2.6 演示query()方法的使用
    STEP 01

    插入数据:向数据表account中插入几条数据。

    insert into `account`(`id`,`username`,`balance`) values(1,'zhangsan',100),(3,'lisi',500),(4,'wangwu',300);
    
    • 1
    STEP 02

    编写查询方法:在前面的AccountDao接口中,声明findAccountById()方法,通过id查询单个账户信息;声明findAllAccount()方法,用于查询所有账户信息。

    // 通过id查询
    public Account findAccountById(int id);
    // 查询所有账户
    public List<Account> findAllAccount();
    
    • 1
    • 2
    • 3
    • 4
    STEP 03

    实现查询方法:在前面的的AccountDaoImpl类中,实现AccountDao接口中的findAccountById()方法和findAllAccount()方法,并调用query()方法分别进行查询。

    // 这里只展示了其中一个方法,通过id查询单个账户信息
    public Account findAccountById(int id) {
        //定义SQL语句
        String sql = "select * from account where id = ?";
        // 创建一个新的BeanPropertyRowMapper对象
        RowMapper<Account> rowMapper = 
    	new BeanPropertyRowMapper<Account>(Account.class);
        // 将id绑定到SQL语句中,通过RowMapper返回Object类型的单行记录
        return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    STEP 04

    测试条件查询:创建测试类FindAccountByIdTest,用于测试条件查询。

    public class FindAccountByIdTest {
        public static void main(String[] args) {
            // 加载配置文件
            ApplicationContext applicationContext =new 
                ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取AccountDao实例
            AccountDao accountDao =
                    (AccountDao) applicationContext.getBean("accountDao");
            Account account = accountDao.findAccountById(1);
            System.out.println(account);	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 05

    测试查询所有用户信息:创建测试类FindAllAccountTest,用于查询所有用户账户信息。

    public class FindAllAccountTest {
        public static void main(String[] args) {
            // 加载配置文件
            ApplicationContext applicationContext =new 
                 ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取AccountDao实例
            AccountDao accountDao =
                    (AccountDao) applicationContext.getBean("accountDao");
            List<Account> account = accountDao.findAllAccount(); // 执行方法
            for (Account act : account) {// 循环输出集合中的对象
                System.out.println(act); } }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    STEP 06

    查看运行结果:在IDEA中启动FindAllAccountTest类,控制台会输出结果。

    在这里插入图片描述

    3 Spring事务管理概述

    3.1 事务管理的核心接口
    3.1.1 spring-tx-5.2.8.RELEAS依赖包的3个接口

    PlatformTransactionManager接口:可以根据属性管理事务。
    TransactionDefinition接口:用于定义事务的属性。
    TransactionStatus接口:用于界定事务的状态 。

    3.1.2 PlatformTransactionManager接口

    PlatformTransactionManager 接口主要用于管理事务,该接口中提供了三个管理事物的方法。

    在这里插入图片描述

    3.1.3 TransactionDefinition接口

    TransactionDefinition接口中定义了事务描述相关的常量,其中包括了事务的隔离级别、事务的传播行为、事务的超时时间和是否为只读事务。

    3.1.4 事务的隔离级别

    在这里插入图片描述

    3.1.5 事务的传播行为

    事务的传播行为是指处于不同事务中的方法在相互调用时,方法执行期间,事务的维护情况。例如,当一个事务的方法B调用另一个事务的方法A时,可以规定A方法继续在B方法所属的现有事务中运行,也可以规定A方法开启一个新事务,在新事务中运行,B方法所属的现有事务先挂起,等A方法的新事务执行完毕后再恢复。

    3.1.6 TransactionDefinition接口中定义的7种事务传播行为

    在这里插入图片描述

    3.1.7 事务的超时时间

    事务的超时时间是指事务执行的时间界限,超过这个时间界限,事务将会回滚。TransactionDefinition接口提供了TIMEOUT_DEFAULT常量定义事务的超时时间。

    3.1.8 事务是否只读

    当事务为只读时,该事务不修改任何数据,只读事务有助于提升性能,如果在只读事务中修改数据,会引发异常。
    TransactionDefinition接口中除了提供事务的隔离级别、事务的传播行为、事务的超时时间和是否为只读事务的常量外,还提供了一系列方法来获取事务的属性。

    3.1.9 TransactionDefinition接口常用方法

    在这里插入图片描述

    3.1.10 TransactionStatus接口

    在这里插入图片描述

    3.2 事务管理的方式
    3.2.1 Spring中的事务管理的两种方式

    Spring中的事务管理分为两种方式,一种是传统的编程式事务管理,另一种是声明式事务管理。
    编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚。
    声明式事务管理:通过AOP技术实现的事务管理,其主要思想是将事务管理作为一个“切面”代码单独编写,然后通过AOP技术将事务管理的“切面”代码植入到业务目标类中。

    4 声明式事务管理

    4.1 基于XML方式的声明式事务
    4.1.1 如何实现XML方式的声明式事务

    基于XML方式的声明式事务管理是通过在配置文件中配置事务规则的相关声明来实现的。在使用XML文件配置声明式事务管理时,首先要引入tx命名空间,在引入tx命名空间之后,可以使用元素来配置事务管理的通知,进而通过Spring AOP实现事务管理。配置元素时,通常需要指定 id 和 transaction-manager 属性,其中,id 属性是配置文件中的唯一标识,transaction-manager 属性用于指定事务管理器。除此之外,元素还包含子元素元素可配置多个子元素,子元素主要用于配置事务的属性。

    4.1.2 元素的常用属性

    在这里插入图片描述

    4.1.3 如何通过XML方式实现Spring的声明式事务管理
    STEP 01

    导入依赖:在chapter09项目的pom.xml文件中加入aspectjweaver依赖包和aopalliance依赖包作为实现切面所需的依赖包。

    <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.9.6</version>
          <scope>runtime</scope>	</dependency>
    <dependency>
          <groupId>aopalliance</groupId>
          <artifactId>aopalliance</artifactId>
          <version>1.0</version>	</dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    STEP 02

    定义Dao层方法:AccountDao接口中声明转账方法transfer()。

    // 转账
    public void transfer(String outUser,
    	String inUser,
    	Double money);
    
    • 1
    • 2
    • 3
    • 4
    STEP 03

    实现Dao层方法:AccountDaoImpl实现类中实现AccountDao接口中的transfer()方法。

    // 转账 inUser:收款人; outUser:汇款人; money:收款金额
    public void transfer(String outUser, String inUser, Double money) {
        // 收款时,收款用户的余额=现有余额+所汇金额
        this.jdbcTemplate.update("update account set balance = balance +? "
                + "where username = ?",money, inUser);
        // 模拟系统运行时的突发性问题
        int i = 1/0;
        // 汇款时,汇款用户的余额=现有余额-所汇金额
        this.jdbcTemplate.update("update account set balance = balance-? "
                + "where username = ?",money, outUser);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 04

    修改配置文件:修改chapter09项目的配置文件applicationContext.xml,添加命名空间等相关配置代码。

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx">
           <!-- 引入命名空间,这里只列举了两个-->
        <!-- 1.配置数据源;2.配置JDBC模板;3.定义id为accountDao的Bean;前3步省略--><!-- 4.事务管理器,依赖于数据源 -->
        <bean id="transactionManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" /></bean>
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    STEP 05

    测试系统:创建测试类TransactionTest。

    public class TransactionTest {
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取AccountDao实例
            AccountDao accountDao =
                    (AccountDao)applicationContext.getBean("accountDao");
            // 调用实例中的转账方法
            accountDao.transfer("lisi", "zhangsan", 100.0);
            // 输出提示信息
            System.out.println("转账成功!");}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 06

    查看表数据:在执行转账操作前,也就是在执行第5不操作前,先查看account表中的数据。

    在这里插入图片描述

    STEP 07

    再查看表数据:在执行第5步后,控制台中报出了“/by zero”的算术异常信息。此时再次查询数据表account。

    在这里插入图片描述

    未使用事物管理的缺陷
    由XML方式实现声明式事务管理的案例可知,zhangsan的账户余额增加了100,而lisi的账户确没有任何变化,这样的情况显然是不合理的。这就是没有事务管理,系统无法保证数据的安全性与一致性,下面使用事务管理解决该问题。

    STEP 08

    使用事务管理测试系统:在第4步的代码文件中添加事务管理的配置。

    <!-- 5.编写通知,需要编写对切入点和具体执行事务细节-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*" propagation="REQUIRED"
                           isolation="DEFAULT" read-only="false" /></tx:attributes>
    </tx:advice>
    <!-- 6.编写aop,使用AspectJ的表达式,让spring自动对目标生成代理-->
    <aop:config>
            <aop:pointcut expression="execution(* com.itheima.*.*(..))"
                          id="txPointCut" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" 
    </aop:config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    4.2 基于注解方式的声明式事务
    4.2.1 @Transactional的属性

    在这里插入图片描述

    4.2.2 注解方式来实现项目中的事务管理
    STEP 01

    创建配置文件:创建配置文件applicationContext-annotation.xml,在该文件中声明事务管理器等配置信息。

    <!– 前四步省略-->
    <!-- 1.配置数据源:数据库驱动;连接数据库的url;连接数据库的用户名;连接数据库的密码 -->
    <!-- 2.配置JDBC模板:默认必须使用数据源 -->
    <!--3.定义id为accountDao的Bean:将jdbcTemplate注入到AccountDao实例中 -->		
    <!-- 4.事务管理器,依赖于数据源 -->
    <!-- 5.注册事务管理器驱动 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    STEP 02

    修改Dao层实现类:在AccountDaoImpl类的transfer()方法上添加事务注解@Transactional。

    @Transactional(propagation = Propagation.REQUIRED, 
                isolation = Isolation.DEFAULT, readOnly = false)
    public void transfer(String outUser, String inUser, Double money) {
        // 收款时,收款用户的余额=现有余额+所汇金额
        this.jdbcTemplate.update("update account set balance = balance +? "
                + "where username = ?",money, inUser);
        // 模拟系统运行时的突发性问题
        int i = 1/0;
        // 汇款时,汇款用户的余额=现有余额-所汇金额
        this.jdbcTemplate.update("update account set balance = balance-? "
                + "where username = ?",money, outUser);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    STEP 03

    编写测试类:创建测试类AnnotationTest。

    public class AnnotationTest {
        public static void main(String[] args) {
            ApplicationContext applicationContext =new 
       ClassPathXmlApplicationContext("applicationContext-annotation.xml");
            // 获取AccountDao实例
            AccountDao accountDao =
                    (AccountDao)applicationContext.getBean("accountDao");
            // 调用实例中的转账方法
            accountDao.transfer("lisi", "zhangsan", 100.0);
            // 输出提示信息
            System.out.println("转账成功!");}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5 案例:实现用户登录

    5.1 案例要求

    本案例要求学生在控制台输入用户名密码,如果用户账号密码正确则显示用户所属班级,如果登录失败则显示登录失败。实现用户登录项目运行成功后控制台效果如下所示。

    在这里插入图片描述

    5.2 思路分析

    根据学生管理系统及其登录要求,可以分析案例的实现步骤如下。
    (1)为了存储学生信息,需要创建一个数据库。
    (2)为了程序连接数据库并完成对数据的增删改查操作,需要在XML配置文件中配置数据库连接和事务等信息。
    (3)在Dao层实现查询用户信息的方法。
    (4)在Controller层处理业务逻辑,如判断用户输入的用户名与密码是否正确 。

    STEP 01

    创建数据库:在MySQL中的spring数据库中创建一个名为student的表。

    在这里插入图片描述

    STEP 02

    编写实体类:创建Student类,在该类中定义id、username、password和course属性,以及属性对应的getter/setter方法。

    public class Student {
        //学生ID
        private Integer id;
        //学生姓名
        private String username;
        //学生密码
        private String password;
        //学生班级
        private String course;
        // 省略getter/setter方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 03

    编写配置文件:创建配置文件applicationContext-student.xml,在该文件中配置id为dataSource的数据源Bean和id为jdbcTemplate的JDBC模板Bean,并将数据源注入到JDBC模板中。

    <!-- 1.配置数据源 -->
    <!--数据库驱动 -->
    <!--连接数据库的url -->
    <!--连接数据库的用户名 -->
    <!--连接数据库的密码 -->
    <!-- 2.配置JDBC模板 -->
    <!-- 默认必须使用数据源 -->
    <!-- 3.定义id为accountDao的Bean -->
    <!-- 将jdbcTemplate注入到AccountDao实例中 -->
    <!-- 4.事务管理器,依赖于数据源 -->
    <!-- 5.注册事务管理器驱动 -->
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 04

    编写Dao层方法:创建StudentDao接口,在StudentDao接口中声明查询所有用户信息的方法。

    package com.itheima.dao;
    import com.itheima.entity.Student;
    import java.util.List;
    public interface StudentDao {
        //查询所有账户
        public List<Student> findAllStudent();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    STEP 05

    实现Dao层方法:创建StudentDaoImpl实现类,在StudentDaoImpl类中实现StudentDao接口中的findAllStudent()方法。

    public class StudentDaoImpl implements StudentDao {
        // 声明JdbcTemplate属性,省略了setter方法
        private JdbcTemplate jdbcTemplate;
        public List<Student> findAllStudent() {
            String sql = "select * from student";
            RowMapper<Student> rowMapper =
                    new BeanPropertyRowMapper<Student>(Student.class);
            // 执行静态的SQL查询,并通过RowMapper返回结果
            return this.jdbcTemplate.query(sql, rowMapper);
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    STEP 06

    编写Controller层:创建StudentController类,用于实现用户登录操作。

    public class StudentController {
        public static void main(String[] args) {
           Scanner sca=new Scanner(System.in);
            String name=sca.nextLine();
            ApplicationContext applicationContext =new 
            ClassPathXmlApplicationContext("applicationContext-student.xml");
            // 获取AccountDao实例
            StudentDao studentDao =
                    (StudentDao) applicationContext.getBean("studentDao");
            List<Student> student = studentDao.findAllStudent();
            // for循环输出集合中的对象,此处省略	}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    STEP 07

    查看运行结果:在IDEA中启动StudentController类,在控制台按照提示输入账号密码进行登录。

    在这里插入图片描述

  • 相关阅读:
    数字化审计智慧
    13 最大子数组和
    基于Java健身房管理系统
    ESP Insights 自定义仪表板
    【Python】实现excel文档中指定工作表数据的更新操作
    Techsmith Camtasia Studio 2022.0.2屏幕录制软件
    YOLOv3 | 核心主干网络,特征图解码,多类损失函数详解
    Hashmap
    使用Android数据恢复恢复已删除的文件[Windows]
    使用STM32CubeMX实现LED闪烁
  • 原文地址:https://blog.csdn.net/qq_42670540/article/details/126638103