【MyBatis】| Apply MyBatis in WEB (using MVC architecture pattern)

Table of contents 

One: Apply MyBatis in the WEB (using the MVC architecture pattern)

1. Preliminary preparation

2. Core code implementation

3. Transaction Control

4. The scope of the three major objects


One: Apply MyBatis in the WEB (using the MVC architecture pattern)

Target:

① Master how to use mybatis in web applications

②The scope and life cycle of the three mybatis objects

③ThreadLocal principle and use

④Consolidate the MVC architecture model

⑤ Prepare for learning the interface proxy mechanism of MyBatis

Realized function: bank account transfer

Technology used: HTML + Servlet + MyBatis

The name of the WEB application: bank

1. Preliminary preparation

(1) Database table preparation

design table structure

 insert data

 (2) Use Mybatis to build the environment in the web application, create a web application, add a local Tomcat server, and then configure resources

①Introduce dependencies in the pom.xml file

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  
  <name>mybatis-004-web</name>
  <groupId>com.bjpowernode</groupId>
  <artifactId>mybatis-004-web</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
    <!--mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.23</version>
    </dependency>
    <!--logback依赖-->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
    </dependency>
    <!--servlet依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
  </dependencies>

</project>

②Introduction of some configuration files

③ Write the front-end transfer page index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>银行账户转账</title>
</head>
<body>
    <form action="/bank/transfer" method="post">
        转出账号:<input type="text" name="fromActno"><br>
        转入账号:<input type="text" name="toActno"><br>
        转账余额:<input type="text" name="money"><br>
        <input type="submit" value="转账">
    </form>
</body>
</html>

④ Use the MVC architecture pattern to create a package

Explanation: dao is to connect to the database, pojo is an ordinary java class, service is to write business, utils is a tool class, web is a servlet

(1) According to the analysis of the three-tier architecture: web is the presentation layer, service is the business layer, and dao is the persistence layer.
(2) Analysis according to the MVC architecture pattern: pojo, dao, and service belong to M, all .jsp belongs to V, and web belongs to C. (3) The relationship between the MVC architecture pattern and the three layers: M includes the business layer and the persistence layer, and V and C belong to the presentation layer.

pojo class, encapsulating account information

package com.bjpowernode.bank.pojo;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.pojo
 * @Project:mybatis
 * @name:Account
 * @Date:2023/1/1 17:53
 */
public class Account {
    private Long id;
    private String actno;
    private Double balance;
    // 构造方法
    public Account() {
    }
    public Account(Long id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }
    // setter and getter
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public Double getBalance() {
        return balance;
    }

    public void setBalance(Double balance) {
        this.balance = balance;
    }
    // 重写toString
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }
}

 Tool class, the class that connects to the database

package com.bjpowernode.bank.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

public class SqlSessionUtils {
    public SqlSessionUtils() {
    }
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession openSession(){
        return sqlSessionFactory.openSession();
    }

}

2. Core code implementation

Details: There is a configuration in the web.xml file, metadata-complete="true"> indicates that only the form of configuration file is supported, and development in the form of annotation is not supported; equal to false indicates that both are supported!

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="false">
</web-app>

The main frame form and the required display pages

① Bao package: the operation of connecting to the database, interface-oriented programming, interface and corresponding implementation class

②exception package: Throwing exceptions, one is the exception thrown by insufficient balance, and the other is the exception that occurs during the transfer process

③pojo package: encapsulates data, ordinary java class

④service package: write business logic code, interface-oriented programming, interface and corresponding implementation class

⑤utils package: code package to connect to the database

⑥ web package: write servlet, it is the commander, for scheduling

①index.html is the page for submitting data at the front end, where you enter the transfer information

②money-not-enough.html is the page where the transfer balance is insufficient and the results are displayed

③success.html is the page where the transfer is successful

④transfer-error.html is the page where there is a problem with the transfer

①AccountMapper.xml: specially written sql statement

②jdbc.properties: configuration information required to connect to the database

③logback.xml: log configuration information

④mybatis-config.xml: core configuration file for importing logs, reading connection database configuration files, connecting databases, and associating AccountMapper.xml configuration files and other information

(1) Write a servlet, write AccountServlet according to the request sent by the front end, this Servlet is equivalent to Commander C, and dispatches two secretaries M and V

package com.bjpowernode.bank.web;

import com.bjpowernode.bank.exception.MoenyNotEnoughException;
import com.bjpowernode.bank.exception.TransferException;
import com.bjpowernode.bank.service.AccountService;
import com.bjpowernode.bank.service.impl.AccountServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.web
 * @Project:mybatis
 * @name:AccountServlet
 * @Date:2023/1/1 19:23
 */
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet {
    // 编写业务逻辑的类,声明为成员变量,其它方法也能调用
    private AccountService accountService = new AccountServiceImpl();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取表单数据
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        double money = Double.parseDouble(request.getParameter("money"));
        // AccountService accountService = new AccountServiceImpl(); // 面向接口编程
        try {
            // 调用service的转账方法完成转账(调度业务层-M)
            accountService.transfer(fromActno,toActno,money);
            // 调用View完成展示结果
            // 转账成功,跳转页面
            response.sendRedirect(request.getContextPath()+"/success.html");
        } catch (MoenyNotEnoughException e) {
            // 钱不够,跳转页面
            response.sendRedirect(request.getContextPath()+"/money-not-enough.html");
        } catch (TransferException e) {
            // 转账失败,跳转页面
            response.sendRedirect(request.getContextPath()+"/transfer-error.html");
        }

    }
}

 Insufficient balance money-not-enough.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>余额不足</title>
</head>
<body>
    <h1>余额不足</h1>
</body>
</html>

 Transfer successful success.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>转账成功</title>
</head>
<body>
    <h1>转账成功</h1>
</body>
</html>

Transfer failed transfer-error.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>转账失败</title>
</head>
<body>
    <h1>转账失败</h1>
</body>
</html>

(2) The above logic found that Commander Servlet calls the business logic code (M) to complete the transfer operation, so it is necessary to write the AccountService interface and the AccountServiceImpl implementation class

AccountService interface

package com.bjpowernode.bank.service;

import com.bjpowernode.bank.exception.MoenyNotEnoughException;
import com.bjpowernode.bank.exception.TransferException;

public interface AccountService {
    /**
     * 账户转账
     * @param fromActno 转账账号
     * @param toActno 转入账号
     * @param money 转账金额
     */
    void transfer(String fromActno,String toActno,double money) throws MoenyNotEnoughException, TransferException;
}

AccountServiceImpl implementation class

package com.bjpowernode.bank.service.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.bao.impl.AccountDaoImpl;
import com.bjpowernode.bank.exception.MoenyNotEnoughException;
import com.bjpowernode.bank.exception.TransferException;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.service.AccountService;

/** 编写业务逻辑代码
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.service.impl
 * @Project:mybatis
 * @name:AccountServiceImpl
 * @Date:2023/1/1 19:40
 */
public class AccountServiceImpl implements AccountService {---
   // 修改数据的类
   private AccountDao accountDao = new AccountDaoImpl();
    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoenyNotEnoughException, TransferException {
        // 判断转出账户的余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            // 如果转出账户余额不足,抛出异常提示用户
            throw new MoenyNotEnoughException("对不起,余额不足");
        }
        // 如果余额充足,更新转出和转入账户余额
        Account toAct = accountDao.selectByActno(toActno);
        // 修改内存中的余额
        fromAct.setBalance(fromAct.getBalance()-money);
        toAct.setBalance(toAct.getBalance()+money);
        // 修改数据库当中余额
        int count = accountDao.updateByActno(fromAct);
        count += accountDao.updateByActno(toAct);
        if (count != 2) {
            // 转账异常
            throw new TransferException("转账异常");
        }
    }
}

 Insufficient balance throws an exception MoenyNotEnoughException

package com.bjpowernode.bank.exception;

public class MoenyNotEnoughException extends Exception{
    // 两个构造方法
    public MoenyNotEnoughException() {
    }
    public MoenyNotEnoughException(String message) {
        super(message);
    }
}

 An exception TransferException is thrown when the transfer fails

package com.bjpowernode.bank.exception;

public class TransferException extends Exception{
    public TransferException() {
    }
    public TransferException(String message) {
        super(message);
    }
}

(3) When writing business logic, it is found that database operations are required, which requires a class to connect to the database and process data operations; interface-oriented programming, write AccountDao interface and AccountDaoImpl class

AccountDao interface

package com.bjpowernode.bank.bao;

import com.bjpowernode.bank.pojo.Account;

/**
 * 负责对表中数据进行CRUD
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.bao
 * @Project:mybatis
 * @name:AccountDao
 * @Date:2023/1/1 19:48
 */
public interface AccountDao {
    /**
     * 根据账号查询账户信息
     * @param actno
     * @return 返回的是账户信息
     */
   Account selectByActno(String actno);

    /**
     * 更新账户信息
     * @param act
     * @return 1表示更新成功
     */
   int updateByActno(Account act);
}

AccountDaoImpl class

package com.bjpowernode.bank.bao.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.bao.impl
 * @Project:mybatis
 * @name:AccountDaoImpl
 * @Date:2023/1/1 19:57
 */
public class AccountDaoImpl implements AccountDao {
    @Override
    public Account selectByActno(String actno) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        Account account = (Account) sqlSession.selectOne("account.selectByActno", actno);
        sqlSession.close();
        return account;
    }

    @Override
    public int updateByActno(Account act) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        int count = sqlSession.update("account.updateByActno", act);
        sqlSession.commit();
        sqlSession.close();
        return count;
    }
}

AccountMapper.xml for writing sql statements

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="account">
    <select id="selectByActno" resultType="com.bjpowernode.bank.pojo.Account">
        select * from t_act where actno=#{actno}
    </select>

    <update id="updateByActno">
        update t_act set balance = #{balance} where actno = #{actno};
    </update>
</mapper>

The configuration file jdbc.properties for connecting to the database

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123

Core configuration file mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--读取配置文件-->
    <properties resource="jdbc.properties" />
    <!--引入日志-->
    <settings>
        <setting name="logImpl" value="SLF4J"/>
    </settings>
    <environments default="mybatisDB">
        <!--连接的是mybatis数据库-->
        <environment id="mybatisDB">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--关联AccountMapper.xml配置文件-->
        <mapper resource="AccountMapper.xml"/>
    </mappers>

</configuration>

3. Transaction Control

Note: The current code has no transaction control. If a null pointer exception is added after the first update statement and before the second update statement, money will be lost, which requires transaction control!

(1) In fact, the control of the transaction should not be placed on the Dao layer, and it should be submitted once if one cannot be updated; it should be sent to the Service layer, and all logic is completed before submitting.

(2) It is not acceptable for us to directly add codes for controlling transactions at the Service layer; because the sqlSession object obtained here and the sqlSession object obtained by executing the update statement are not the same sqlSession object.

package com.bjpowernode.bank.service.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.bao.impl.AccountDaoImpl;
import com.bjpowernode.bank.exception.MoenyNotEnoughException;
import com.bjpowernode.bank.exception.TransferException;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.service.AccountService;
import com.bjpowernode.bank.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.service.impl
 * @Project:mybatis
 * @name:AccountServiceImpl
 * @Date:2023/1/1 19:40
 */
public class AccountServiceImpl implements AccountService {
   private AccountDao accountDao = new AccountDaoImpl();
    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoenyNotEnoughException, TransferException {

        // 添加事务控制代码
        SqlSession sqlSession = SqlSessionUtils.openSession();

        // 判断转出账户的余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            // 如果转出账户余额不足,抛出异常提示用户
            throw new MoenyNotEnoughException("对不起,余额不足");
        }
        // 如果余额充足,更新转出和转入账户余额
        Account toAct = accountDao.selectByActno(toActno);
        // 修改内存中的余额
        fromAct.setBalance(fromAct.getBalance()-money);
        toAct.setBalance(toAct.getBalance()+money);
        // 修改数据库当中余额
        int count = accountDao.updateByActno(fromAct);
        count += accountDao.updateByActno(toAct);
        if (count != 2) {
            // 转账异常
            throw new TransferException("转账异常");
        }

        // 提交事务
        sqlSession.commit();
        sqlSession.close();
    }
}

(3) Use ThreadLocal control, which is essentially a Map collection. Its key stores the thread object, and its value stores the sqlSession object; we store the sqlSession object in this Map collection, and for the same thread, it will be taken out later All are the same sqlSession object.

Introduce ThreadLocal in the tool class SqlSessionUtils

package com.bjpowernode.bank.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.mybatis.utils
 * @Project:mybatis
 * @name:SqlSessionUtils
 * @Date:2022/12/29 14:11
 */

public class SqlSessionUtils {
    public SqlSessionUtils() {
    }
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 全局的,服务器级别的,一个服务器当中定义一个
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

    // 获取会话对象
    public static SqlSession openSession(){
        // 先从ThreadLocal当中获取
        SqlSession sqlSession = local.get();
        // 第一次获取肯定是空的
        if (sqlSession == null) {
            // 是空的,在去工厂中获取
            sqlSession = sqlSessionFactory.openSession();
            // 将sqlSession对象绑定到当前线程上
            local.set(sqlSession);
        }
        return sqlSession;
    }

    // 关闭sqlSession对象
    public static void close(SqlSession sqlSession){
        if (sqlSession != null) {
            sqlSession.close();
            // 移除sqlSession对象与当前线程的绑定关系
            // 因为Tomcat服务器是支持多线程的,被当前用户用到的t1线程,有可能继续被其他用户使用
            local.remove();
        }
    }
}

Modify the database AccountDaoImpl class, you should not commit and close in it

package com.bjpowernode.bank.bao.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.bao.impl
 * @Project:mybatis
 * @name:AccountDaoImpl
 * @Date:2023/1/1 19:57
 */
public class AccountDaoImpl implements AccountDao {
    @Override
    public Account selectByActno(String actno) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        Account account = (Account) sqlSession.selectOne("account.selectByActno", actno);
        return account;
    }

    @Override
    public int updateByActno(Account act) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        int count = sqlSession.update("account.updateByActno", act);
        return count;
    }
}

Add transaction control in the Service layer AccountServiceImpl class

package com.bjpowernode.bank.service.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.bao.impl.AccountDaoImpl;
import com.bjpowernode.bank.exception.MoenyNotEnoughException;
import com.bjpowernode.bank.exception.TransferException;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.service.AccountService;
import com.bjpowernode.bank.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.service.impl
 * @Project:mybatis
 * @name:AccountServiceImpl
 * @Date:2023/1/1 19:40
 */
public class AccountServiceImpl implements AccountService {
   private AccountDao accountDao = new AccountDaoImpl();
    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoenyNotEnoughException, TransferException {

        // 添加事务控制代码
        SqlSession sqlSession = SqlSessionUtils.openSession();

        // 判断转出账户的余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            // 如果转出账户余额不足,抛出异常提示用户
            throw new MoenyNotEnoughException("对不起,余额不足");
        }
        // 如果余额充足,更新转出和转入账户余额
        Account toAct = accountDao.selectByActno(toActno);
        // 修改内存中的余额
        fromAct.setBalance(fromAct.getBalance()-money);
        toAct.setBalance(toAct.getBalance()+money);
        // 修改数据库当中余额
        int count = accountDao.updateByActno(fromAct);
        count += accountDao.updateByActno(toAct);
        if (count != 2) {
            // 转账异常
            throw new TransferException("转账异常");
        }

        // 提交事务
        sqlSession.commit();
        // 调用方法关闭
        SqlSessionUtils.close(sqlSession);
    }
}

4. The scope of the three major objects

(1) SqlSessionFactoryBuilder: This class can be instantiated, used and discarded, once the SqlSessionFactory is created, it is no longer needed . So the best scope for an instance of SqlSessionFactoryBuilder is method scope (that is, local method variables).

(2) SqlSessionFactory: Once SqlSessionFactory is created, it should always exist during the running of the application . There is no reason to discard it or recreate another instance, unless another database is connected, and a database corresponds to a SqlSessionFactory object . The best practice of using SqlSessionFactory is not to create multiple times during the running of the application, so it is placed in a static code block when encapsulating. So the best scope for SqlSessionFactory is application scope

(3 ) SqlSession: Each thread should have its own instance of SqlSession. Instances of SqlSession are not thread-safe and therefore cannot be shared, so its best scope is request or method scope (one request) . A thread corresponds to a SqlSession object .

Supplement: We found that each method code of the Dao implementation class AccountDaoImp ​​has only two lines, and one line is repeated; so can this class not be written, and the implementation class of this interface can be generated in memory? Using javassist technology, you can only give the interface, and automatically generate the implementation class in memory according to this interface. This is the technology to learn next!

package com.bjpowernode.bank.bao.impl;

import com.bjpowernode.bank.bao.AccountDao;
import com.bjpowernode.bank.pojo.Account;
import com.bjpowernode.bank.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.bank.bao.impl
 * @Project:mybatis
 * @name:AccountDaoImpl
 * @Date:2023/1/1 19:57
 */
public class AccountDaoImpl implements AccountDao {
    @Override
    public Account selectByActno(String actno) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        Account account = (Account) sqlSession.selectOne("account.selectByActno", actno);
        return account;
    }

    @Override
    public int updateByActno(Account act) {
        SqlSession sqlSession = SqlSessionUtils.openSession();
        int count = sqlSession.update("account.updateByActno", act);
        return count;
    }
}

Guess you like

Origin blog.csdn.net/m0_61933976/article/details/128511127