编程技术是改变世界的力量。
本站
当前位置:网站首页 > 后端语言 > 正文

Java,Mybatis,使用XML映射的方式,事务管理和事务控制

gowuye 2024-04-04 11:54 2 浏览 0 评论

Mybatis使用XML映射的方式

Employee

package com.what21.mybatis.model;

import lombok.Data;

@Data
public class Employee {

    // ID
    private Integer id;
    // 名称
    private String name;
    // 邮箱
    private String email;
    // 性别
    private String gender;
    // 年龄
    private Integer age;

}

SQL脚本:

create table `employee` (
	`id` INT(12) NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`email` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`gender` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
	`age` INT(12) NULL DEFAULT NULL
)
COLLATE='utf8_unicode_ci' ENGINE=InnoDB;

Mybatis配置:com/what21/mybatis/demo01/mybatisConfig.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>

    <settings>
        <!--建议显示的指定需要配置的值,防止版本更新带来的问题-->
        <!--开启驼峰命名规则-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias type="com.what21.mybatis.model.Employee" alias="employee"/>
    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果-->
            <!--如果某些查询数据量非常大,不应该允许查出所有数据-->
            <property name="pageSizeZero" value="true"/>
        </plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
            <transactionManager type="jdbc"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=UTF8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/what21/mybatis/demo01/mapper/EmployeeMapper.xml"/>
    </mappers>

</configuration>

XML映射文件:com/what21/mybatis/demo01/mapper/EmployeeMapper.xml

<?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="com.what21.mybatis.demo01.mapper.EmployeeMapper">

	<!--
		useGeneratedKeys="true" 表示给主键设置自增长
		keyProperty="id"  表示将自增长后的Id赋值给实体类中的id字段
	 -->
    <insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id" parameterType="employee">
    	insert into `employee` (
    		`name`,`email`,`gender`,`age`
    	)
        values (
    		#{name}, #{email},#{gender},#{age}
        )
   </insert>

    <select id="findEmployeeById" parameterType="int" resultType="employee">
		select * from `employee` where id = #{id}
	</select>

    <update id="updateEmployee" parameterType="employee">
        update `employee`
        <set>
            <if test="name!=null">
                `name`=#{name},
            </if>
            <if test="email!=null">
                `email`=#{email},
            </if>
            <if test="gender!=null">
                `gender`=#{gender},
            </if>
            <if test="age!= null">
                `age`=#{age}
            </if>
        </set>
        where `id` = #{id}
    </update>

    <delete id="deleteEmployeeById" parameterType="int">
		delete from `employee` where `id` = #{id}
    </delete>

</mapper>

EmployeeMapper

package com.what21.mybatis.demo01.mapper;

import com.what21.mybatis.model.Employee;

public interface EmployeeMapper {

    /**
     * @param employee
     * @return
     */
    public int insertEmployee(Employee employee);

    /**
     * @param id
     * @return
     */
    public Employee findEmployeeById(Integer id);

    /**
     * @param employee
     * @return
     */
    public int updateEmployee(Employee employee);

    /**
     * @param id
     * @return
     */
    public int deleteEmployeeById(Integer id);

}

MybatisDemoMain

package com.what21.mybatis.demo01;

import com.what21.mybatis.demo01.mapper.EmployeeMapper;
import com.what21.mybatis.model.Employee;
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;
import java.io.Reader;

public class MybatisDemoMain {

    /**
     * 创建sessionFactory
     *
     * @param mybatisConfig
     * @return
     */
    private static SqlSessionFactory getSessionFactory(String mybatisConfig) {
        SqlSessionFactory sessionFactory = null;
        try {
            Reader reader = Resources.getResourceAsReader(mybatisConfig);
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }

    public static void main(String[] args) {
        String resource = "com/what21/mybatis/demo01/mybatisConfig.xml";
        // 从SessionFactory中获取SqlSession
        SqlSession sqlSession = getSessionFactory(resource).openSession();
        // Mapper
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        // 实体对象
        Employee newEmployee = new Employee();
        newEmployee.setName("学习测试");
        newEmployee.setEmail("leran@demo.com");
        newEmployee.setAge(34);
        newEmployee.setGender("1");
        // insert操作
        int insertOperate = employeeMapper.insertEmployee(newEmployee);
        // SQL正确,插入一条数据成功,返回结果为:1
        System.out.println("insert操作结果:" + insertOperate);
        System.out.println("实体ID:" + newEmployee.getId());
        // update操作
        newEmployee.setId(10000);
        int updateOperate = employeeMapper.updateEmployee(newEmployee);
        // SQL正确,没有更新任何一条数据,返回结果为:0
        System.out.println("update操作结果:" + updateOperate);
        // select操作
        Employee findEmployee = employeeMapper.findEmployeeById(2);
        System.out.println(findEmployee);
        // delete操作
        int deleteOperate = employeeMapper.deleteEmployeeById(10001);
        // SQL正确,没有删除任何一条数据,返回结果为:0
        System.out.println("delete操作结果:" + deleteOperate);
    }

}

Mybatis事务管理和事务控制

Mybatis事务管理:JdbcTransaction和ManagedTransaction

JdbcTransaction事务是对数据库连接Connection的一个包装、内部管理的数据库事务,本质上还是调用了Connection的提交、回滚等事务操作方法。

ManagedTransaction事务是交由外部让容器来管理事务Transaction的整个生命周期。

<transactionManager type="jdbc"/>

1、为jdbc时,使用JdbcTransaction管理事务。

2、为managed时,使用ManagedTransaction管理事务(也就是交由外部容器管理)。

接口:org.apache.ibatis.Transaction

实现:

org.apache.ibatis.transaction.jdbc.JdbcTransaction

org.apache.ibatis.transaction.managed.ManagedTransaction

mybatis-spring实现:

org.mybatis.spring.transaction.SpringManagedTransaction

JdbcTransaction实现方式:

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionException;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@Slf4j
public class JdbcTransaction implements Transaction {

    protected Connection connection;
    protected DataSource dataSource;
    protected TransactionIsolationLevel level;
    protected boolean autoCommmit;

    public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
        dataSource = ds;
        level = desiredLevel;
        autoCommmit = desiredAutoCommit;
    }

    public JdbcTransaction(Connection connection) {
        this.connection = connection;
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (connection == null) {
            openConnection();
        }
        return connection;
    }

    @Override
    public void commit() throws SQLException {
        if (connection != null && !connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Committing JDBC Connection [" + connection + "]");
            }
            connection.commit();
        }
    }

    @Override
    public void rollback() throws SQLException {
        if (connection != null && !connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Rolling back JDBC Connection [" + connection + "]");
            }
            connection.rollback();
        }
    }

    @Override
    public void close() throws SQLException {
        if (connection != null) {
            resetAutoCommit();
            if (log.isDebugEnabled()) {
                log.debug("Closing JDBC Connection [" + connection + "]");
            }
            connection.close();
        }
    }

    protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
        try {
            if (connection.getAutoCommit() != desiredAutoCommit) {
                if (log.isDebugEnabled()) {
                    log.debug("Setting autocommit to " + desiredAutoCommit + " on JDBC Connection [" + connection + "]");
                }
                connection.setAutoCommit(desiredAutoCommit);
            }
        } catch (SQLException e) {
            // Only a very poorly implemented driver would fail here,
            // and there's not much we can do about that.
            throw new TransactionException("Error configuring AutoCommit.  "
                    + "Your driver may not support getAutoCommit() or setAutoCommit(). "
                    + "Requested setting: " + desiredAutoCommit + ".  Cause: " + e, e);
        }
    }

    protected void resetAutoCommit() {
        try {
            if (!connection.getAutoCommit()) {
                // MyBatis does not call commit/rollback on a connection if just selects were performed.
                // Some databases start transactions with select statements
                // and they mandate a commit/rollback before closing the connection.
                // A workaround is setting the autocommit to true before closing the connection.
                // Sybase throws an exception here.
                if (log.isDebugEnabled()) {
                    log.debug("Resetting autocommit to true on JDBC Connection [" + connection + "]");
                }
                connection.setAutoCommit(true);
            }
        } catch (SQLException e) {
            if (log.isDebugEnabled()) {
                log.debug("Error resetting autocommit to true "
                        + "before closing the connection.  Cause: " + e);
            }
        }
    }

    protected void openConnection() throws SQLException {
        if (log.isDebugEnabled()) {
            log.debug("Opening JDBC Connection");
        }
        connection = dataSource.getConnection();
        if (level != null) {
            connection.setTransactionIsolation(level.getLevel());
        }
        setDesiredAutoCommit(autoCommmit);
    }

    @Override
    public Integer getTimeout() throws SQLException {
        return null;
    }

}

ManagedTransaction实现方式:

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@Slf4j
public class ManagedTransaction implements Transaction {

    private DataSource dataSource;
    private TransactionIsolationLevel level;
    private Connection connection;
    private boolean closeConnection;

    public ManagedTransaction(Connection connection, boolean closeConnection) {
        this.connection = connection;
        this.closeConnection = closeConnection;
    }

    public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) {
        this.dataSource = ds;
        this.level = level;
        this.closeConnection = closeConnection;
    }

    @Override
    public Connection getConnection() throws SQLException {
        if (this.connection == null) {
            openConnection();
        }
        return this.connection;
    }

    @Override
    public void commit() throws SQLException {
        // Does nothing
    }

    @Override
    public void rollback() throws SQLException {
        // Does nothing
    }

    @Override
    public void close() throws SQLException {
        if (this.closeConnection && this.connection != null) {
            if (log.isDebugEnabled()) {
                log.debug("Closing JDBC Connection [" + this.connection + "]");
            }
            this.connection.close();
        }
    }

    protected void openConnection() throws SQLException {
        if (log.isDebugEnabled()) {
            log.debug("Opening JDBC Connection");
        }
        this.connection = this.dataSource.getConnection();
        if (this.level != null) {
            this.connection.setTransactionIsolation(this.level.getLevel());
        }
    }

    @Override
    public Integer getTimeout() throws SQLException {
        return null;
    }

}

相关推荐

PHPMailer远程命令执行漏洞分析

摘要:PHPMailer是一个强大的PHP编写的邮件发送类,但近日被爆出远程命令执行漏洞,该漏洞实际上是什么,有何种影响,本文对该漏洞进行了分析及验证方法,并给出防护方案。0x00漏洞概要PHPMa...

「安全漏洞」DedeCMS-5.8.1 SSTI模板注入导致RCE

漏洞类型SSTIRCE利用条件影响范围应用漏洞概述2021年9月30日,国外安全研究人员StevenSeeley披露了最新的DedeCMS版本中存在的一处SQL注入漏洞以及一处SSTI导致的RCE...

回顾使用PHP原生发送电子邮件(终)文件附件

FileAttachments文件附件Fileattachmentsworkjustlikemixedemail,exceptthatadifferentcontenttyp...

php-fpm.conf &amp; php.ini 安全优化实践

0x01关于php其历史相对已经比较久远了,这里也就不废话了,属弱类型中一种解释型语言除了web开发以及写些简单的exp,暂未发现其它牛逼用途,暂以中小型web站点开发为主另外,低版本的php自身...

linux 安全配置 ossec 开源检测

linux安全配置ossec开源检测一:介绍主要功能有日志分析、完整性检查、rootkit检测、基于时间的警报和主动响应。除了具有入侵检测系统功能外,它还一般被用在SEM/SIM(安全事件管理(...

PHP使用PHPMailer发送验证码邮件的方法与调用逻辑

首先我们需要下载PHPMailer:https://github.com/PHPMailer/PHPMailer一般情况下我们只需要压缩包中的src文件夹中的文件,并保存至根目录即可:设置一个文件,如...

回顾使用PHP原生发送电子邮件(一)

IwishIcouldremembertheveryfirstemailmessageIeversent.Unfortunately,thetruthisthatI...

PHPMAILER实现PHP发邮件功能php实例

这篇文章主要为大家详细介绍了PHPMAILER实现PHP发邮件功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下本文实例为大家分享了PHPMAILER实现PHP发邮件功能的具体代码,供大家参考,具...

500道网络安全面试题集锦(附答案)

本篇文章内容为网络安全各个方向涉及的面试题,星数越多代表问题出现的几率越大,但是无论如何都无法覆盖所有的面试问题,更多的还是希望由点达面,查漏补缺,然后祝各位前程似锦,都能找到自己满意的工作!一、We...

网站放家里,随处看电影「Apache+php+ssl 安装和配置」

  使用5G网络,随处都可以看到放自己家里电脑的视频。这个功能很容易实现,不需要太多的专业知识,也不需要额外花钱。如果确实需要,最多花不到两百块钱买一台旧电脑放家里,做个网站,就能解决全部问题,Fre...

Windows2008中 Magic Winmail Server提权

MagicWinmailServer是安全易用全功能的邮件服务器软件,不仅支持SMTP/POP3/IMAP/Webmail/LDAP(公共地址簿)/多域/发信认证/反垃圾邮件/邮件过滤/邮件组...

利用PHPmailer发送邮件

早上帮朋友做一个收集客户联系方式的页面,要求能实时推送信息给管理员。刚开始想到做后台管理,因为时间紧,做后台是赶不上了。想过通过短信发送,成本太高,否决了。。。灵机一动,客户提交时直接把信息发送到邮箱...

phpmailer发送邮件

phpmailer发送邮件PHP内置的mail函数使用起来不够方便,另外受其他语言的影响,博主更偏好面向对象的包管理模式,因此phpmailer成为了我用PHP发送邮件的首选,这里分享给大家。库导入这...

PHP初级教程:读取输入

PHP读取输入:Form:?formaction="welcome.php"method="post">Name:(inputtype="text...

php filter 验证Email,Url,Ip格式

今天发现一个非常好用的函数东西,filter过滤器,用于验证和过滤来自非安全来源的数据,比如用户的输入。验证Email:$email='1234567@qq.com';if(!filter_v...

取消回复欢迎 发表评论: