Mybatis框架学习01

写在前面

在查找了各路学习的课程后,选择了学习SSM,即Spring+SpringMVC+Mybatis。今天主要学习了Mybatis的基础知识。

1.传统JDBC的问题

先来看一段JDBC的经典代码:

public static void main(String[] args) {
		//数据库连接
		Connection connection = null;
		//预编译的Statement,使用预编译的Statement
		PreparedStatement preparedStatement = null;
		//结果集
		ResultSet resultSet = null;
		
		try {
			//加载数据库驱动
			Class.forName("com.mysql.jdbc.Driver");
			
			//通过驱动管理类获取数据库链接
			connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "abc456");
			//定义sql语句 ?表示占位符
		String sql = "select * from user where username = ?";
			//获取预处理statement
			preparedStatement = connection.prepareStatement(sql);
			//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
			preparedStatement.setString(1, "王五");
			//向数据库发出sql执行查询,查询出结果集
			resultSet =  preparedStatement.executeQuery();
			//遍历查询结果集
			while(resultSet.next()){
				System.out.println(resultSet.getString("id")+"  "+resultSet.getString("username"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//释放资源
			if(resultSet!=null){
				try {
					resultSet.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(preparedStatement!=null){
				try {
					preparedStatement.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(connection!=null){
				try {
					connection.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

	}

从这段代码中,我们可以读到几个问题:

  • 1.数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。
  • 2.将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
  • 3.向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
  • 4.从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。

可以看到,传统的JDBC有很多的问题,我们设想一下如何来解决:

  • 1.使用数据库连接池来管理连接。
  • 2&&3&&4:放到xml配置文件中,形成软编码。

在大致了解后,正式进入Mybatis的学习

2.Mybatis的运行原理:

我们首先看一张图:

这张图细致的描述了Mybatis的运行原理:Mybatis首先通过一个总配置文件(SqlMapConfig.xml,名称不固定),来配置各种映射文件和事务等。之后建立一个会话工厂,通过总配置文件会话工厂,会话工厂创建一个面向用户的接口,来实现操作数据库,其实际上是通过Executor来控制数据库,而Executor则是使用mapped statement来对数据库进行直接操作。这就是Mybatis的运行原理。

3.Mybatis的测试程序

3.1 按照上面的流程,我们首先要写一个总配置文件SqlMapConfig.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>
	<!-- 和spring整合后 environments配置将废除-->
	<environments default="development">
		<environment id="development">
		<!-- 使用jdbc事务管理,事务控制由mybatis控制-->
			<transactionManager type="JDBC" />
		<!-- 数据库连接池,由mybatis管理-->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="abc456" />
			</dataSource>
		</environment>
	</environments>
	<!-- 加载映射文件 -->
	<mappers>
		<mapper resource ="sqlmap/User.xml"></mapper>
	</mappers>
</configuration>

其中定义了mappers,即第二步的映射对象。

3.2映射对象的配置(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">
<!-- namespace 命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要作用 -->
<mapper namespace="test">
	<!-- 在映射文件中配置很多sql语句 -->
	<!-- 通过select进行数据库的查询,按id查询user表 id:标识映射文件中的sql,称为statement的id 将sql语句封装到mapperStatement对象中,所以将id称为statement的id -->
	<!-- #{}表示一个占位符号 -->
	<!-- parameterType 指定输入参数的类型,这里指定int型 -->
	<!-- #{id}:其中的id表示接收输入的参数,参数的名称就是id 如果输入参数是简单类型,#{}中的参数名可以任意 -->
	<!--resultType:指定sql输出结果所映射的java对象类型:select指定resultType 表示将单条记录映射成java对象 -->
	<select id="findUserById" parameterType="int"
		resultType="mybatis01.po.User">
		select * from user where id =#{id}
	</select>
	<!-- 根据用户名称模糊查询用户信息 可能返回多条 resultType:指定的就是单条记录所映射的java对象类型 -->
	<!-- ${}:表示拼接sql串,将接收到的内容不加任何修饰拼接在sql中
	使用${}拼接sql可能会引起sql注入
	${value}:接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value
	 -->
	<select id="findUserByName" parameterType="java.lang.String"
		resultType="mybatis01.po.User">
		select * from user where username like '%${value}%'
	</select>
        <insert id="insertUser" parameterType="mybatis01.po.User">
		<!-- 
		将插入数据的主键返回,返回到USER对象中
		select last_insert_id():得到insert进去记录的主键值,只适用于自增主键
		
		keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
		order:select last_insert_id()执行顺序(相对于insert语句来说)
		
		resultType:指定select last_insert_id()的结果类型
		 -->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
		
		insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
	</insert>
	
	<!-- 删除用户 
	根据id删除用户,需要输入id值
	-->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id = #{id}
	</delete>
	
	<!-- 更新用户
	需要传入用户id
	需要传入用户的更新信息
	parameterType指定user对象,包括id和更新信息,注意,id必须存在
	 #{id} 从输入的user对象中获取id属性值
	 -->
	
	<update id="updateUser" parameterType="mybatis01.po.User">
		update user set username = #{username},birthday=#{birthday},sex=${sex},address=#{address} where id = #{id}
	</update>
</mapper>

这里编写主要的sql语句以及接受和发出的各种参数,具体的操作解释都在注释里。
其中由于操作的是User对象,我们要创建一个User对象:

public class User {

	//属性名和数据库表的字段对应
	private int id;
	private String username;// 用户姓名
	private String sex;// 性别
	private Date birthday;// 生日
	private String address;// 地址
	
}

3.3 在配置完成后,我们写一个测试程序来测试Mybatis,这里在User.xml定义了两个sql语句,分别是按ID查找和按名称模糊查找,我们分别编写方法:

	//根据id查询用户信息,得到一条记录的结果
	@Test
	public void findUserByIdTest() throws IOException {
		//mybatis配置文件
		String resource = "SqlMapConfig.xml";
		//得到配置文件流
		InputStream config = Resources.getResourceAsStream(resource);
		//创建会话工厂
			SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
		//通过工厂得到SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//通过SqlSession操作数据库
		//第一个参数,映射文件中statement的 id=namespace+"."+statment的id
		//第二个参数:指定映射文件中所匹配的parameterType类型的参数
		//selectone的结果是与映射文件中所匹配的resultType类型的对象
		User  user = sqlSession.selectOne("test.findUserById",1);
		System.out.println(user);
		//释放资源
		sqlSession.close();
	}
	
	//根据用户名称模糊查询用户列表
	
	@Test
	public void findUserByNameTest() throws IOException {
		//mybatis配置文件
				String resource = "SqlMapConfig.xml";
				//得到配置文件流
				InputStream config = Resources.getResourceAsStream(resource);
				//创建会话工厂
					SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
				//通过工厂得到SqlSession
				SqlSession sqlSession = sqlSessionFactory.openSession();
				//list中的user和映射文件中resultType所指定的类型一致
				List<User> list = sqlSession.selectList("test.findUserByName","小明");
				System.out.println(list);
				sqlSession.close();
	}
        //添加用户
	@Test
	public void insertNameTest() throws IOException {
				//mybatis配置文件
				String resource = "SqlMapConfig.xml";
				//得到配置文件流
				InputStream config = Resources.getResourceAsStream(resource);
				//创建会话工厂
					SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
				//通过工厂得到SqlSession
				SqlSession sqlSession = sqlSessionFactory.openSession();
				//插入用户对象
				User user = new User();
				user.setUsername("赵淫荡");
				user.setBirthday(new Date());
				user.setSex("1");
				user.setAddress("武安市第一中学");
				sqlSession.insert("test.insertUser",user);
				//执行提交事务
				sqlSession.commit();
				//获取用户信息主键
				System.out.println(user.getId());
				//关闭会话
				sqlSession.close();
	}
	//删除用户
	@Test
	public void deleteUserTest() throws IOException {
				//mybatis配置文件
				String resource = "SqlMapConfig.xml";
				//得到配置文件流
				InputStream config = Resources.getResourceAsStream(resource);
				//创建会话工厂
					SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
				//通过工厂得到SqlSession
				SqlSession sqlSession = sqlSessionFactory.openSession();
				//传入id,删除用户
				sqlSession.delete("test.deleteUser",39);
				//执行提交事务
				sqlSession.commit();
				//获取用户信息主键
				//关闭会话
				sqlSession.close();
	}
	//更新用户
	@Test
	public void updateUserTest() throws IOException {
				//mybatis配置文件
				String resource = "SqlMapConfig.xml";
				//得到配置文件流
				InputStream config = Resources.getResourceAsStream(resource);
				//创建会话工厂
					SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
				//通过工厂得到SqlSession
				SqlSession sqlSession = sqlSessionFactory.openSession();
				User user = new User();
				user.setId(37);
				user.setUsername("赵荡荡");
				user.setBirthday(new Date());
				user.setSex("1");
				user.setAddress("武安市第中学");
				//传入id,删除用户
				sqlSession.update("test.updateUser",user);
				//执行提交事务
				sqlSession.commit();
				//获取用户信息主键
				//关闭会话
				sqlSession.close();
	}

并通过JUnit进行测试,测试无误。

posted @ 2020-03-09 22:10  武神酱丶  阅读(200)  评论(0编辑  收藏  举报