MyBatis两种开发方式和MyBatis的核心配置文件

MyBatis两种开发方式

使用MyBatis开发Dao,通常有两种方式,即原始Dao开发方式和Mapper接口动态代理开发方式。推荐使用第二种。

MyBatis核心API说明:

(1)SqlSession的使用范围

SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建。
SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。

(2)SqlSessionFactoryBuilder

SqlSessionFactoryBuilder用于创建SqlSessionFactory,SqlSessionFactory一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。

(3)SqlSessionFactory

 SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory

(4)SqlSession

  SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
  每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
    打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下:
SqlSession session = sqlSessionFactory.openSession();

try {

     // do work

} finally {
    session.close();

}
1.1 MyBatis工具类的封装

为了方便使用SqlSession对象,需要封装工具类MyBatisUtils.java

package com.qf.utils;

import java.io.IOException;
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;

public class MyBatisUtils {
	public  static SqlSessionFactory factory;
	static{
		try {
			//0获取流
			InputStream is=Resources.getResourceAsStream("SqlMapConfig.xml");
			//1FactoryBuilder
			factory=new SqlSessionFactoryBuilder().build(is);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static SqlSession openSession(){
		return factory.openSession();
	}
}	
1.2 原始Dao方式

原始Dao开发方法需要程序员编写Dao接口和Dao实现类。

实现功能:

使用MyBatis开发DAO实现以下的功能:
(1)根据用户id查询一个用户信息
(2)根据用户名称模糊查询用户信息列表
(3)添加用户信息
第一步:编写映射文件
<?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,还有一个很重要的作用,后面会讲 -->
<mapper namespace="test">

	<!-- 根据id查询用户 -->
	<select id="queryUserById" parameterType="int"
		resultType="cn.qf.MyBatis.pojo.User">
		select * from user where id = #{id}
	</select>

	<!-- 根据username模糊查询用户 -->
	<select id="queryUserByUsername" parameterType="string"
		resultType="cn.qf.MyBatis.pojo.User">
		select * from user where username like '%${value}%'
	</select>

	<!-- 保存用户 -->
	<insert id="saveUser" parameterType="cn.qf.MyBatis.pojo.User">
		<selectKey keyProperty="id" keyColumn="id" order="AFTER"
			resultType="int">
			SELECT LAST_INSERT_ID()
		</selectKey>
		insert into user(username,birthday,sex,address)
		values(#{username},#{birthday},#{sex},#{address})
	</insert>

</mapper>

第二步:创建DAO接口
public interface UserDao {
	/**
	 * 根据id查询用户
	 * 
	 * @param id
	 * @return
	 */
	User queryUserById(int id);

	/**
	 * 根据用户名模糊查询用户
	 * 
	 * @param username
	 * @return
	 */
	List<User> queryUserByUsername(String username);

	/**
	 * 保存用户
	 * 
	 * @param user
	 */
	void saveUser(User user);
}
第三步:Dao实现类
public class UserDaoImpl implements UserDao {
	

	@Override
	public User queryUserById(int id) {
		// 创建SqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();
		// 执行查询逻辑
		User user = sqlSession.selectOne("queryUserById", id);
		// 释放资源
		sqlSession.close();

		return user;
	}

	@Override
	public List<User> queryUserByUsername(String username) {
		// 创建SqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();

		// 执行查询逻辑
		List<User> list = sqlSession.selectList("queryUserByUsername", username);
		// 释放资源
		sqlSession.close();
		return list;
	}

	@Override
	public void saveUser(User user) {
		// 创建SqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();

		// 执行保存逻辑
		sqlSession.insert("saveUser", user);
		// 提交事务
		sqlSession.commit();
		// 释放资源
		sqlSession.close();
	}
}
第四步:测试

代码略

1.3 Mapper接口动态代理方式(重点)

Mapper接口动态代理方式(重点)Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由MyBatis框 架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

MyBatis运行时 会使用JDK(有接口)动态代理为DAO生成proxy对象 代理对象会拦截接口方法,转而执行MapperStatement所代表的sql 然后将sql返回
 

Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

开发规范:

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:
1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同(注意:mapper.xml中parameterType可不写,如果不写则由Mapper接口中的方法参数类型决定)
4、Mapper接口方法的返回值类型和mapper.xml中定义的每个sql的resultType(输出参数类型)的类型相同
第一步:编写映射文件

在com.qf.mapper包中添加UserMapper.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 -->
<!-- 还有一个很重要的作用,使用动态代理开发DAO,1. namespace必须和Mapper接口类路径一致 -->
<mapper namespace="com.qf.mapper.UserMapper">
	<!-- 根据用户id查询用户 -->
	<!-- 2. id必须和Mapper接口方法名一致 -->
	<!-- 3. parameterType必须和接口方法参数类型一致 -->
	<!-- 4. resultType必须和接口方法返回值类型一致 -->
	<select id="queryUserById" parameterType="int"
		resultType="cn.qf.MyBatis.pojo.User">
		select * from user where id = #{id}
	</select>

	<!-- 根据用户名查询用户 -->
	<select id="queryUserByUsername" parameterType="string"
		resultType="cn.qf.MyBatis.pojo.User">
		select * from user where username like '%${value}%'
	</select>

	<!-- 保存用户 -->
	<insert id="saveUser" parameterType="com.qf.pojo.User">
		<selectKey keyProperty="id" keyColumn="id" order="AFTER"
			resultType="int">
			select last_insert_id()
		</selectKey>
		insert into user(username,birthday,sex,address) values
		(#{username},#{birthday},#{sex},#{address});
	</insert>

</mapper>
第二步: 创建DAO接口

在com.qf.mapper包中添加UserMapper.java接口

public interface UserMapper {
	/**
	 * 根据id查询
	 * 
	 * @param id
	 * @return
	 */
	User queryUserById(int id);

	/**
	 * 根据用户名查询用户
	 * 
	 * @param username
	 * @return
	 */
	List<User> queryUserByUsername(String username);

	/**
	 * 保存用户
	 * 
	 * @param user
	 */
	void saveUser(User user);
}
第三步: 加载映射文件
  <mappers>
       <mapper resource=*"com.qf.mapper/UserMapper.xml"* />
   </mappers>
第四步:测试
@Test
	public void testQueryUserById() {
		// 获取sqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 执行查询方法
		User user = userMapper.queryUserById(1);
		System.out.println(user);

		// 和spring整合后由spring管理
		sqlSession.close();
	}

	@Test
	public void testQueryUserByUsername() {
		// 获取sqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 执行查询方法
		List<User> list = userMapper.queryUserByUsername("张");
		for (User user : list) {
			System.out.println(user);
		}

		// 和spring整合后由spring管理
		sqlSession.close();
	}

	@Test
	public void testSaveUser() {
		// 获取sqlSession
		SqlSession sqlSession = MyBatisUtils.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 创建保存对象
		User user = new User();
		user.setUsername("李小璐");
		user.setBirthday(new Date());
		user.setSex("1");
		user.setAddress("上海");
		// 执行查询方法
		userMapper.saveUser(user);
		System.out.println(user);


		// 和spring整合后由spring管理
		sqlSession.commit();
		sqlSession.close();
	}

总结:

selectOne和selectList
	动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace
	MyBatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

MyBatis核心配置文件

MyBatis的核心配置mybatis-config.xml中包含内容顺序如下:

    properties(属性)
    settings(全局配置参数)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境集合属性对象)
    environment(环境子属性对象)
    transactionManager(事务管理)
    dataSource(数据源)
    mappers(映射器)
2.1 properties(属性)

自定义db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/MyBatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

mybatis-config.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>
	<!-- 是用resource属性加载外部配置文件 -->
	<properties resource="db.properties">
		<!-- 在properties内部用property定义属性 -->
		<!-- 如果外部配置文件有该属性,则内部定义属性被外部属性覆盖 -->
		<property name="jdbc.username" value="root" />
		<property name="jdbc.password" value="root" />
	</properties>

	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<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>
MyBatis 将按照下面的顺序来加载属性:
(1)在 properties 元素体内定义的属性首先被读取。 
(2)然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性
2.2 typeAliases(类型别名)

MyBatis支持的别名

别名	    映射的类型
_byte 	    byte 
_long 	    long 
_short 	    short 
_int 	    int 
_integer    int 
_double     double 
_float 	    float 
_boolean     boolean 
string 	     String 
byte 	    Byte 
long 	    Long 
short 	    Short 
int 	    Integer 
integer      Integer 
double 	     Double 
float 	     Float 
boolean      Boolean 
date 	     Date 
decimal      BigDecimal 
bigdecimal 	 BigDecimal 
map	         Map

自定义别名

<typeAliases>
		<!-- 单个别名定义 -->
		<typeAlias alias="user" type="cn.qf.MyBatis.pojo.User" />
		<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
		<package name="com.qf.pojo" />
		<package name="其它包" />
</typeAliases>
2在这里插入代码片.3 mappers(映射器)
Mapper配置的几种方法:
1. <mapper resource=" " />
使用相对于类路径的资源(现在的使用方式)
如:<mapper resource="sqlmap/User.xml" />

2. <mapper class=" " />
使用mapper接口类路径
如:<mapper class="com.qf.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

3. <package name=""/>
注册指定包下的所有mapper接口    
如:<package name="com.qf.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

把java目录中配置也编译程序中:

<build>
<resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <!-- 是否替换资源中的属性-->
                <filtering>false</filtering>
            </resource>
  </resources>
  </build>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值