mybatis入门之原始dao开发与mapper代理开发

前言:

相信很多朋友和笔者一样,在开始学习mybatis的时候,看完一遍mybatis相关知识,并没有记住多少,理解深刻就更谈不上,渴求一个简单的demo来测试一下自己到底了解多少,掌握多少以及mybatis到底是怎么玩的,那么机会来了,笔者将自己之前学习过程中练习的demo重新整理了下,并记录总结。

在练习这两种方式之前我们要清楚明白为什么要使用mybatis?先看看原生的数据库连接操作:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TraditionalJdbcConn {

	public static void main(String[] args) {
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/name";
		String user = "root";
		String password = "root";
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			Class.forName(driver);// 加载数据库驱动
			conn = DriverManager.getConnection(url, user, password);// 得到数据库连接
			String sql = "select *from new1 where id=?";
			pstm = conn.prepareStatement(sql);// 得到预编译对象
			pstm.setInt(1, 19);
			rs = pstm.executeQuery();// 得到结果集
			while (rs.next()) {
				System.out.println(rs.getInt(1) + "\t" + rs.getString(2));
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				if (rs != null)
					rs.close();
				if (pstm != null)
					pstm.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				System.out.println(e.getMessage());
			}

		}
	}

}

上面是传统的Jdbc库连接数据库的基本步骤,可以看出上述代码存在着一下几个问题:

  • 数据库连接对象频繁的创建和销毁,存在很大开销。(解决:数据库连接池)

  • sql语句存在硬编码问题,后期维护和升级存在着复杂性。(解决:把语句单独写到一个配置文件中,按照一定规则读取)

  • PreparedStatement设置参数存在着硬编码问题。(解决:配置文件中写)(ps:这里提醒一点,使用statement对象和preparedStatement对象的区别是preparedStatement是预编译对象,对于同一条sql语句,第二次的执行效率远高于第一次,但是如果一条sql语句就执行一次,那么statement执行的速率更快,当然对于同一条语句的多次执行可以使用preparedStatement+批处理,其速度是远超前两者的)

  • 结果集resultSet遍历数据的时候存在硬编码问题。(直接将数据映射成Java对象)

知道了为什么要用mybatis后,就直接进入正题,关于原始dao开发和mapper代理开发:

项目结构:(包括原始dao开发和mapper代理开发)

环境准备:

JAR包下载:

POJO类:

public class User {

	private int id;
	private String content;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", content=" + content + "]";
	}
	public User(int id, String content) {
		super();
		this.id = id;
		this.content = content;
	}
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}

Log4j.properties配置文件:(关于log4j的配置,详情参见log4j日志配置

log4j.rootLogger=debug,console
 
log4j.appender.console=org.apache.log4j.ConsoleAppender  
log4j.appender.console.layout=org.apache.log4j.PatternLayout  
log4j.appender.console.layout.ConversionPattern=%d %-2p [%c.%M()] - %m%n

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>
     <!-- 加载属性文件db.properties -->
     <properties resource="db.properties"></properties>
 	<!-- 和spring整合后,environments将被废除 -->
 	<environments default="development">
 		<environment id="development">
 		<!-- 使用JDBC事务管理 ,事务控制由mybatis管理-->
 		<transactionManager type="JDBC"></transactionManager>
 		<!-- 数据库连接池 ,由mybatis管理-->
 		<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>
 		<mapper resource="sqlmap/user.xml"/>
 		<mapper resource="mapper/UserMapper.xml"/>
 	</mappers>
 </configuration>

db.properties文件:

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

原始dao开发:

开发人员需要编写接口,接口实现类,以及相应的XML配置文件。具体如下:

接口:

import h.l.pojo.User;

public interface UserDao {

	public User findUserById(int id) throws Exception;// 根据id查询查询用户

	public void insertUser(User user) throws Exception;// 新增用户

	public void deleteUser(int id) throws Exception;// 删除用户

	public void updateUser(User user) throws Exception;// 更新用户
}

接口实现类:(ps:除了查询,其他的操作都要commit)

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import h.l.pojo.User;

public class UserDaoImpl implements UserDao {

	// 向dao实现类中注入SqlSessionFactory
	// 这里通过构造函数向实现类中注入SqlSessionFactory
	private SqlSessionFactory sqlSessionFactory;
	public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}
	// 因为SqlSession是线程不安全的,所有SqlSession对象应该在方法中创建,不能在类中创建

	// 根据id查找用户
	@Override
	public User findUserById(int id) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user = sqlSession.selectOne("test.findUserById", id);
		// 释放资源
		sqlSession.close();
		return user;
	}
	// 新增用户
	@Override
	public void insertUser(User user) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.insert("test.insertUser", user);
		sqlSession.commit();
		sqlSession.close();
	}
	// 删除用户
	@Override
	public void deleteUser(int id) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.delete("test.deleteUser", id);
		sqlSession.commit();
		sqlSession.close();
	}
	// 更新用户
	@Override
	public void updateUser(User user) throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.update("test.updateUser", user);
		sqlSession.commit();
		sqlSession.close();
	}

}

User.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="test">
	<select id="findUserById" parameterType="int"
		resultType="h.l.pojo.User">
		select * from new1 where id=#{id}
	</select>
	<insert id="insertUser" parameterType="h.l.pojo.User">
		insert into new1(id,content) values(#{id},#{content})
	</insert>
	<delete id="deleteUser" parameterType="int">
		delete from new1 where
		id=#{id}
	</delete>
	<update id="updateUser" parameterType="h.l.pojo.User">
		update new1 set content=#{content} where id=#{id}
	</update>
</mapper>

测试类:

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import h.l.pojo.User;

public class UserDaoImplTest {

	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp() throws Exception {
		// 创建sqlSessionFactory
		String resource = "SqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}

	@Test
	public void testFindUserById() throws Exception {
		// 创建UserDao
		UserDao userDao = new UserDaoImpl(sqlSessionFactory);
		// 调用UserDao方法
		User user = userDao.findUserById(5);
		System.out.println(user);
	}
	@Test
	public void testInsertUser() throws Exception {
		// 创建UserDao
		UserDao userDao = new UserDaoImpl(sqlSessionFactory);
		// 创建一个对象
		User user = new User();
		user.setContent("5000");
		// 调用UserDao方法
		userDao.insertUser(user);
	}
	@Test
	public void testDeleteUser() throws Exception {
		// 创建UserDao
		UserDao userDao = new UserDaoImpl(sqlSessionFactory);
		// 调用UserDao方法
		userDao.deleteUser(18);
	}
	@Test
	public void testUpdateUser() throws Exception {
		// 创建UserDao
		UserDao userDao = new UserDaoImpl(sqlSessionFactory);
		User user = new User();
		user.setContent("江西上饶");
		user.setId(19);
		userDao.updateUser(user);
	}
}

Mapper代理开发:

开发人员只需要编写接口和XML文件即可,mybatis可以自动生成mapper接口实现类代理对象。但是接口的编写需要按照一定的规则:

  • 在mapper.xml中namespace等于mapper接口地址。
  • mapper.java接口中的方法名和mapper.xml中statement的id一致。
  • mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
  • mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

mapper接口:

import h.l.pojo.User;

public interface UserMapper {

	public User findUserById(int id) throws Exception;// 根据id查询用户
}

XXXMapper.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="h.l.mapper.UserMapper">
	<select id="findUserById" parameterType="int" resultType="h.l.pojo.User">
		select *from new1 where id=#{id}
	</select>
</mapper>

测试文件:

import java.io.InputStream;

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 org.junit.Before;
import org.junit.Test;

import h.l.pojo.User;

public class UserMapperTest {

	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp() throws Exception {
		String resource = "SqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}

	@Test
	public void testFindUserById() throws Exception {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		User user = userMapper.findUserById(19);
		System.out.println(user);
	}

}

上述就是原始到开发和mapper代理开发的简单入门,通过上面方法的比较,我们可以发现,程序员可以通过mybatis拜托硬编码的问题,使得后期的维护能够更加方便。关于mybatis的其他知识也会陆陆续续总结,请多关照~


注:以上文章仅是个人学习过程总结,若有不当之处,望不吝赐教。

猜你喜欢

转载自blog.csdn.net/m0_37265215/article/details/84101201