MyBatis-CRUD

框架还没搭好的请看MyBatis入门

MyBatis工具类

由于频繁的加载配置文件创建对象工厂获取会话,如果我每个接口都需要重新写一遍这样的代码就会显得代码量很多,所以我写了一个MyBatis工具类,把这些重复的代码给封装起来。
MyBatis工具类

增、删、改、查

通过使用工具类来完成对数据库的操作
UserDao

public interface UserDao {
	//根据主键id查询
	User fainQuery(int id);
	//修改
	int update(@Param("id")int id,@Param("name")String name);
	//新增
	int insert(User user);
	//删除
	int delete(int id);
	//查询全部
	List<User> selectAll();
	//获取总条数
	int count();
}

1.@Param注解一般是用在传递多个参数的场景里,这样方便我们知道传递的是哪个参数。
2.还有一种方式在xml里用 #[0],#[1]… 这样的方式是根据接口的参数列表来按顺序传递的

UserDaoImpl

public class UserDaoImpl implements UserDao {
	//获取接口实现类对象
	private UserDao userDao = (UserDao)SqlUtils.getMapper(UserDao.class); 

	@Override
	public User fainQuery(int id) {
		// TODO Auto-generated method stub
		return userDao.fainQuery(id);
	}

	@Override
	public int update(int id,String name) {
		// TODO Auto-generated method stub
		return userDao.update(id,name);
	}

	@Override
	public int insert(User user) {
		// TODO Auto-generated method stub
		return userDao.insert(user);
	}

	@Override
	public List<User> selectAll() {
		// TODO Auto-generated method stub
		return userDao.selectAll();
	}

	@Override
	public int count() {
		// TODO Auto-generated method stub
		return userDao.count();
	}

	@Override
	public int delete(int id) {
		// TODO Auto-generated method stub
		return userDao.delete(id);
	}
}

UserMapper

<?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.dao.UserDao">

	<select id = "fainQuery" parameterType="int" resultType="user">
		select * from user where id = #{id} 
	</select>
	
	<update id="update" parameterType = "user">
		update user set name = #{name} where id = #{id}
	</update>
	
	<insert id = "insert" parameterType="user">
		insert user(id,name,age) 
		value(#{id},#{name},#{age})
	</insert>
	
	<select id = "selectAll" resultType="user">
		select * from user
	</select>
	
	<select id="count" resultType="int">
		select count(*) from user
	</select>
	
	<delete id = "delete" parameterType="int">
		delete from user where id = #{id}
	</delete>
</mapper>
  • parameterType:传递过来的参数类型
  • resultType:返回的参数类型

delete,insert,update是没有resultType的因为返回的都是int类型。
上面这两个是常用的。

测试:

public class Demo {
	
	//获取实体类对象
	private UserDao userDao = new UserDaoImpl();
	
	/**
	 * 根据主键id获取一条数据
	 */
	@Test
	public void test1(){
		User user = userDao.fainQuery(2);
		System.out.println(user.getName());
	}
	
	/**
	 * 修改
	 */
	@Test
	public void test2(){
		int open = userDao.update(2,"huisbsbsbs");
		SqlUtils.commit();
		
		System.out.println(open);
	}
	
	/**
	 * 新增
	 */
	@Test
	public void test3(){
		User user = new User();
		user.setId(3);
		user.setName("周总");
		user.setAge(24);
		int open = userDao.insert(user);
		SqlUtils.commit();
		
		System.out.println(open);
	}
	
	/**
	 * 查询全部
	 */
	@Test
	public void test4(){
		List<User> list = userDao.selectAll();
		for (User user : list) {
			System.out.println(user.getId());
			System.out.println(user.getName());
			System.out.println(user.getAge());
			System.out.println();
		}
	}
	
	/**
	 * 获取总数
	 */
	@Test
	public void test5(){
		int count = userDao.count();
		System.out.println(count);
	}
	
	/**
	 * 删除
	 */
	public void test6(){
		int open = userDao.count();
		SqlUtils.commit();
		
		System.out.println(open);
	}
}

只有新增,删除,修改才会改变数据 才需要commit(提交事务)

事务管理

1.什么是事务

事务是一个不可分割工作单位,事务中的操作要么都做,要么都不做。事务可大可小,一个事务在关系数据库中,可以是一条SQL语句也可以是一组SQL语句或者一个程序。

2.MyBatis的两种事务管理机制

1.使用JDBC的事务管理机制
        利用java.sql.Connection来完成对事务提交(commit)、回滚(rollback)、清空(close).
2.使用MANAGED的事务管理机制
        MyBatis自身不会管理事务,将管理事务的操作交给Web容器或者Spring容器来实现对事务的管理。

3.MyBatis事务管理的配置

<?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="config/db.properties"/>
	
	<!-- 类型别名 -->
	<typeAliases>
		<package name="com.action"/>
	</typeAliases>
	
	<!-- 配置数据源 -->
	<environments default="development">
		<environment id="development">
			
			<!--配置JDBC手动管理事务 -->
			<transactionManager type="JDBC"/>
			<!--配置MANAGED自动管理事务-->
			<!--<transactionManager type="MANAGED"/>-->
			<dataSource type="POOLED">
				<property name="url" value="${jdbc.url}"/>
				<property name="driver" value="${jdbc.driver}"/>
				<property name="username" value="${jdbc.username}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
			
		</environment>
	</environments>

	
	<!-- 配置映射接口 -->
	<mappers>
		<mapper resource="mapper/UserMapper.xml"/>
	</mappers>
	
</configuration>

environment节点配置连接数据库的信息,其子节点transactionManager 的type决定我们使用什么事务管理机制。

4.MyBatis的Transaction

Transaction接口是对两种事务的管理器进行的一个约束

/**
 * 包装数据库连接
 * 处理连接生命周期,包括:它的创建,准备,提交/回滚和关闭
 *
 * @author Clinton Begin
 */
public interface Transaction {

  /**
   * 检索内部数据库连接
   * @return DataBase connection
   * @throws SQLException
   */
  Connection getConnection() throws SQLException;

  /**
   * 提交内部数据库连接。
   * @throws SQLException
   */
  void commit() throws SQLException;

  /**
   * 回滚内部数据库连接。
   * @throws SQLException
   */
  void rollback() throws SQLException;

  /**
   * 关闭内部数据库连接。
   * @throws SQLException
   */
  void close() throws SQLException;

  /**
   * 如果设置了,则获取事务超时
   * @throws SQLException
   */
  Integer getTimeout() throws SQLException;
  
}

5.Transaction的两个实现类

JdbcTransaction
        JdbcTransaction直接使用JDBC的提交和回滚事务管理机制。它依赖与从dataSource中获取连接connection对象来管理Transaction的作用域。connection对象的获取被延迟到调用getConnection,如果autoCommit设置为on(开启状态),它会忽略commit和rollback.(看下面的代码)

public class JdbcTransaction implements Transaction {

  private static final Log log = LogFactory.getLog(JdbcTransaction.class);

 //数据库连接
  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
        这个实现类中没有具体的实现commit和rollback方法,ManagedTransaction是让容器来管理Transaction的生命周期,使用commit和rollback也没关系因为没用具体的实现,它将事务管理全权交给了容器。(看下面的代码)

public class ManagedTransaction implements Transaction {

  private static final Log log = LogFactory.getLog(ManagedTransaction.class);

   //数据库连接
  protected Connection connection;
  //数据源
  protected DataSource dataSource;
  //隔离级别
  protected TransactionIsolationLevel level;
  //是否为自动提交
  protected boolean autoCommmit;

  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;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值