mybatis的两种开发方式(传统dao和动态代理模式)


一、

(一)就前一章的jdbc来进行连接数据库出现的问题

  1. 频繁创建和打开、关闭数据连接,太消耗资源
  2. Sql语句存在硬编码,不利于维护
  3. Sql参数设置硬编码,不利于维护
  4. 结果集获取与遍历复杂,存在硬编码,不利于维护,期望能够查询后返回一个java对象

二、什么是mybatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
Mybatis是面向sql的持久层框架,他封装了jdbc访问数据库的过程,我们开发,只需专注于sql语句本身的拼装,其它复杂的过程全部可以交给mybatis去完成。

三、传统dao

传统dao需要接口以及实现类,配置文件也类似于jdbc连接数据库
基本步骤
1.穿件xml文件编写数据操作语言
2.创建Dao接口
3.创建DaoImpl的实现类
4.进行测试

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语句 
	id:sql id,语句的唯一标识
	parameterType:入参的数据类型
	resultType:返回结果的数据类型
	
	#{} :相当于一个占位符
--> 
<!-- 查看 -->
<mapper namespace="user">
	<select id = "getUserById" parameterType = "int" resultType="pojo.User">
	SELECT * FROM `user`
	where id = #{id2}
	</select>
	
	<!-- 模糊查询 -->
	<select id="getUserByUseName" parameterType="string" resultType="pojo.User">
	SELECT * FROM `user`
<!-- 	WHERE username LIKE '%${value}%' -->
	WHERE username LIKE '%${value}%'
	</select>
	<insert id ="insertUser" parameterType="pojo.User">
	INSERT INTO user (
		username,
		birthday,
		sex,
		address
	 )
	 VALUES(
	 #{username},
	 #{birthday},
	 #{sex},
	 #{address}
	 )
	 </insert>
	<!-- 更新用户 -->
	<update id="updateUser" parameterType="pojo.User">
	UPDATE 
		`user`
	SET 
		`username` = #{username} 
		WHERE `id` = #{id}
	</update>
	<!-- 删除用户 -->
	<delete id="deleteUser" parameterType="int">
	DELETE FROM `user`
	WHERE `id` = #{id}
	</delete>
</mapper>

dao

public interface UserDao {
	//根据用户id查询用户信息
	/**
	 * 根据用户的id来查询用户的信息
	 * @param id
	 * @return
	 */
    User getUserById(Integer id);
	//根据用户名查询用户列表
	/**
	 * 根据用户的名字来查询数据库
	 * @param userName
	 * @return
	 */
    List<User> getUserByUserName(String userName);
	/**
	 * //添加用户
	 * @param user
	 */
    void insertUser(User user);
}

daoimpl

package com.dao.impl;

import java.util.Date;
import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.dao.UserDao;
import com.pakage.SqlSessionFactoryUtils;

import pojo.User;

public class UserDaoImpl implements UserDao{

	@Override
	public User getUserById(Integer id) {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
		User user = sqlSession.selectOne("user.getUserById", id);
		sqlSession.close();
		return user;
	}

	@Override
	public List<User> getUserByUserName(String userName) {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
		List<User> list = sqlSession.selectList("user.getUserByUseName",userName);
		sqlSession.close();
		return list;
	}

	@Override
	public void insertUser(User user) {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
		sqlSession.insert("user.insertUser", user);
		
		sqlSession.close();
	}

}

daoimplTest

package com.dao.impl.test;

import static org.junit.Assert.*;

import java.util.Date;
import java.util.List;

import org.junit.Test;

import com.dao.UserDao;
import com.dao.impl.UserDaoImpl;

import pojo.User;

public class UserDaoImplTest {

	@Test
	public void testGetUserById() {
		UserDao dao = new UserDaoImpl();
		User user = dao.getUserById(27);
		System.out.println(user);
	}

	@Test
	public void testGetUserByUserName() {
		UserDao dao = new UserDaoImpl();
		List<User> userName = dao.getUserByUserName("张");
		for (User user : userName) {
			System.out.println(user);
		}
	}

	@Test
	public void testInsertUser() {
		UserDao dao = new UserDaoImpl();
		User user = new User();
		user.setUsername("湖北");
		user.setSex("男");
		user.setBirthday(new Date());
		user.setAddress("武汉");
		dao.insertUser(user);
	}

}

四、 动态代理

动态代理 开发规则
1.namespace一定是全路径名
2.接口的方法名与sqlid一致
3.接口的如入参有与parametertype类型一致
4.接口的返回值必须与resultType类型一致

<?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">

<!-- 
 	动态代理 开发规则
 		1.namespace一定是全路径名
 		2.接口的方法名与sqlid一致
 		3.接口的如入参有与parametertype类型一致
 		4.接口的返回值必须与resultType类型一致
 		
 -->
<!-- 查看 -->
<mapper namespace="mapper.UserMapper">
	<select id = "getUserById" parameterType = "int" resultType="pojo.User">
	SELECT * FROM `user`
	where id = #{id2}
	</select>
	
	<!-- 模糊查询 -->
	<select id="getUserByUseName" parameterType="string" resultType="pojo.User">
	SELECT * FROM `user`

	WHERE username LIKE '%${value}%'
	</select>
	
	<insert id ="insertUser" parameterType="pojo.User">
	INSERT INTO user (
		username,
		birthday,
		sex,
		address
	 )
	 VALUES(
	 #{username},
	 #{birthday},
	 #{sex},
	 #{address}
	 )
	 </insert>
</mapper>

接口mapper

package mapper;

import java.util.List;

import pojo.User;

public interface UserMapper {
	//根据用户id查询用户信息
	/**
	 * 根据用户的id来查询用户的信息
	 * @param id
	 * @return
	 */
    User getUserById(Integer id);
	//根据用户名查询用户列表
	/**
	 * 根据用户的名字来查询数据库
	 * @param userName
	 * @return
	 */
    List<User> getUserByUserName(String userName);
	/**
	 * //添加用户
	 * @param user
	 */
    void insertUser(User user);
}

实现接口

package com.dao.impl.test;

import static org.junit.Assert.*;

import java.util.Date;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.pakage.SqlSessionFactoryUtils;

import mapper.UserMapper;
import pojo.User;

public class UserMapperTest {

	@Test
	public void testGetUserById() {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
		//获取接口的代理实现类
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		User id = userMapper.getUserById(27);
		System.out.println(id);
		sqlSession.close();
	}

	@Test
	public void testGetUserByUserName() {
	SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
	UserMapper mapper = sqlSession.getMapper(UserMapper.class);
	List<User> userName = mapper.getUserByUserName("张");   
	for (User user : userName) {
		System.out.println(user);
	}
	sqlSession.close();
	}

	@Test
	public void testInsertUser() {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(true);
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		User user = new User();
		user.setAddress("小日本");
		user.setBirthday(new Date());
		user.setSex("1");
		user.setUsername("安倍晋三");
		mapper.insertUser(user);
		sqlSession.close();	}

}

SqlMapConfig配置的顺序

1.properties (属性)
2.setting (全局配置参数)
3.typeAliases (类型别名)
4.typeHandlers (类型处理器)
5.objectFactory (对象工厂)
6.plugins(插件)
7.environments(环境集合属性对象)
8.environment(环境子属性对象)
9.transactionManager(事务管理器)
10.dataSource (数据源)
11.mappers (映射器)

属性配置规则

文件加载时,先加载内部标签 ,在加载外部文件,名称相同时,会替换相同名称的内容


	<properties resource="jdbc.properties">
		<property name="jdbc.username" value="root"/>
		<property name="jdbc.password" value="admin"/>
	</properties>

可以在在下面的环境配置中使用改属性

<property name="driver" value="com.mysql.cj.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />

别名配置

typeAliases
mybatis默认支持java基本数据类型的别名识别详细参考教案。

自定义别名

<typeAliases>
		<!-- 单个别名定义 -->
		<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
		<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
		<package name="com.itheima.mybatis.pojo"/>
	</typeAliases>

mapper


<mappers>
		<!-- 第一种方式,加载 resource-->
		<mapper resource="mapper/user.xml"/>
		<!-- <mapper resource="mapper/UserMapper.xml"/> -->
		
		<!-- 第二种方式,class扫描器要求:
			 1、映射文件与接口同一目录下
			 2、映射文件名必需与接口文件名称一致
		 -->
		<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper"/> -->
		
		<!-- 第三种方式,包扫描器要求(推荐使用此方式):
			 1、映射文件与接口同一目录下
			 2、映射文件名必需与接口文件名称一致
		-->
		<package name="com.itheima.mybatis.mapper"/>
</mappers>



版权声明:本文为qq_43702747原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。