欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis框架详解

程序员文章站 2024-03-17 13:47:46
...

MyBatis属于orm框架,MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情:

封装JDBC操作

利用反射打通Java类与SQL语句之间的相互转换

MyBatis使用简单的XML或注解用于配置和原始映射,将接口和java的POJOs(Plain Old Java Objects,普通的java对象)映射成数据库中的记录。

MyBatis的执行流程是:加载配置、SQL解析、SQL执行、结果映射

MyBatis的开发流程:

1、导包:

MyBatis框架详解

2、建表

MyBatis框架详解

3、在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>
	<!-- 属性文件 -->
	<properties>  
		<property name="jdbc.driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
		<property name="jdbc.username" value="mybatis"/>
		<property name="jdbc.password" value="Jredu12345"/>
	</properties>
	<typeAliases>
		<!-- 解析类的别名 -->
		<!-- <typeAlias alias="U" type="com.jereh.entity.User"/> -->
		<!-- 扫描包下的所有类文件,这个包下的所有类都是简写 -->
		<package name="com.jredu.entity"/>
	</typeAliases>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<!-- POOLED:采用连接池的方式 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driverClassName}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- 四种配置方式 -->
		<!-- 找寻对应的xml文件 -->
		<!-- <mapper resource="com/jereh/dao/UserDao.xml"/> -->
		<!-- 找寻接口文件,自动匹配对应的xml文件 -->
		<!-- <mapper class="com.jereh.dao.UserDao"/> -->
		<!-- 找寻磁盘目录下的对应xml文件 --> 
		<!-- <mapper url="file:///E:\workspaces\myeclipse\MyBatis\src\com\jereh\dao\UserDao.xml" /> -->
		<!-- 扫描包下的所有xml文件,该包下的所有映射都会匹配 -->
		<package name="com.jredu.dao"/>
	</mappers>
</configuration>
4、新建实体类

package com.jredu.entity;

import java.util.List;

/**
 * 用户
 * @author Administrator
 *
 */
public class User {
	
	private int id;
	private String name;
	private String pwd;
	private Adress adress;
	private List<Comment> comments;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public Adress getAdress() {
		return adress;
	}
	public void setAddress(Adress adress) {
		this.adress = adress;
	}
	public List<Comment> getComments() {
		return comments;
	}
	public void setComments(List<Comment> comments) {
		this.comments = comments;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", pwd=" + pwd
				+ ", adress=" + adress + ", comments=" + comments + "]";
	}
	

}
5、在UserDao.xml中编写配置文件

package com.jredu.dao;

import java.util.List;
import java.util.Map;

import com.jredu.entity.User;

/**
 * 用户的Dao层
 * @author Administrator
 *
 */
public interface UserDao {

	//添加数据
	int insert(User user);
	
	//更新一条数据
	int update(User user);
	
	//删除一条数据
	int delete(int id);
	
	//查询一条数据
	User select(int id);
	
	//查询全部数据
	List<User> selectAll();
	
	//方法 1:一对一查询
	User findUserWithAdress(int id);
	
	//方法2:一对一查询(重点掌握)
	User findUserWithAdress2(int id);
	
	//一对多查询
	User findUserWithAdressAndComments(int id);
	
	//动态SQL
	//if:根据条件拼接
	User findUserByCondition(User user);
	
	//动态sql
	//choose when otherwise
	//类似switch,只执行一个分支
	User findUserByCondition2(Map<String, Object> map);
	
	//动态SQL
	//where:代替了where关键字
	//where的作用
	//1、添加一个where关键字
	//2、把where子句中第一个出现的and去掉
	User findUserByCondition3(User user);
	
	
	/**
	 * trim:作用跟where类似
	 * 1、可以添加关键字
	 * 2、根据前缀规则可以去掉匹配到的第一个关键字
	 */
	User findUserByCondition4(User user);
	
	
	/**
	 * foreach
	 * 可以循环添加多个参数,遍历一个集合
	 */
	List<User> findUserByCondition5(Map map);
	
	/**
	 * set:添加一个set关键字
	 * 添加一个set关键字
	 * 
	 * @param user
	 * @return
	 */
	int updateByCondition(User user);
	
	/**
	 * 多参数使用
	 * 1、使用实体类(实体类中包含参数属性)
	 * 2、使用map对象
	 * 3、使用多个参数(使用参数对应的下标来获取值)
	 */
	User selectByCondition(String name,String pwd);
}

<?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对应接口地址 (相当于一个实现类)-->
<mapper namespace="com.jredu.dao.UserDao">

<!-- 方法1:定义一个用户结果集 -->
<resultMap type="User" id="u1">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="pwd" column="pwd"/>
	<!-- 代表一对一关系 -->
	<association property="adress" javaType="Adress">
		<result property="id" column="adress_id"/>
		<result property="province" column="province"/>
		<result property="city" column="city"/>
		<result property="area" column="area"/>
	</association>
</resultMap>


<!--方法2: 定义一个用户结果集 -->
<resultMap type="User" id="u2">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="pwd" column="pwd"/>
	<!-- 代表一对一关系 -->
	<association property="adress" column="adress_id" select="com.jredu.dao.AdressDao.select">
		
	</association>
</resultMap>

<!--一对多查询: 定义一个用户结果集 -->
<resultMap type="User" id="u3">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="pwd" column="pwd"/>
	<!-- 代表一对一关系 -->
	<association property="adress" column="adress_id" select="com.jredu.dao.AdressDao.select">
		
	</association>
	
	<!-- 一对多查询 -->
	<collection property="comments" column="id" select="com.jredu.dao.CommentDao.selectByUserId"></collection>
</resultMap>


<!--相当于一个SQL语句;id:关联对应的方法  -->
<insert id="insert" parameterType="User">
	insert into users values(users_seq.nextval,#{name},#{pwd})
</insert> 

<!-- name=#{name}:前一个name是数据库中的字段,后一个name是实体类中的 -->
<update id="update" parameterType="User">
	update users set name=#{name},pwd=#{pwd} where id=#{id}
</update>

<delete id="delete" parameterType="int">
	delete from users where id=#{id}
</delete>
<!--查询一条数据  -->
<select id="select" parameterType="int" resultType="User">
	select * from users where id=#{id}
</select>

<select id="selectAll" resultType="User">
		select * from users
</select>


<!--resultMap="u1":给结果集中的id相对应  -->
<select id="findUserWithAdress" resultType="int" resultMap="u1">
	select u.id,u.name,u.pwd,a.id adress_id,a.province,a.city,a.area from users u ,adress a where u.id=#{id} and u.adress_id=a.id
</select>

<select id="findUserWithAdress2" resultType="int" resultMap="u2">
	select * from users where id=#{id}
</select>

<!--resultType="int":参数类型  -->
<select id="findUserWithAdressAndComments" parameterType="int" resultMap="u3">
	select * from users where id=#{id}
</select>

<!--动态sql  -->
<!-- if -->
<select id="findUserByCondition" parameterType="User" resultType="User">
	select * from users where 1=1
	<if test="id>0">
		and id=#{id}
	</if>
	<if test="name!=null">
		and name=#{name}
	</if>
	<if test="pwd!=null">
		and pwd=#{pwd}
	</if>
</select>

<!--动态sql
	choose when otherwise  -->
<select id="findUserByCondition2" parameterType="Map" resultType="User">
	select * from users where 1=1
	<choose>
	<!--by=='id':根据id进行查询。因为id是字符串所以要加''  -->
		<when test="by=='id'">
			and id=#{id}
		</when>
		<when test="by=='name'">
			and name=#{name}
		</when>
		<otherwise>
			and pwd=#{pwd}
		</otherwise>
	</choose>
</select>

<!--动态SQL
	where:代替了where关键字  -->
<select id="findUserByCondition3" parameterType="User" resultType="User">
	select * from users 
	<where>
		<if test="id>0">
			and id=#{id}
		</if>
		<if test="name!=null">
			and name=#{name}
		</if>
		<if test="pwd!=null">
			and pwd=#{pwd}
		</if>
	</where>
	
</select>

<!-- trim:作用跟where类似 -->
<select id="findUserByCondition4" parameterType="User" resultType="User">
	select * from users 
	<trim prefix="where" prefixOverrides="and">
		<if test="id>0">
			and id=#{id}
		</if>
		<if test="name!=null">
			and name=#{name}
		</if>
		<if test="pwd!=null">
			and pwd=#{pwd}
		</if>
	</trim>
</select>

<!-- foreach
	  可以循环添加多个参数,遍历一个集合 -->
<select id="findUserByCondition5" parameterType="Map" resultType="User">
	select * from users where id in
	<foreach collection="ids" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</select>

<!--set  -->
<update id="updateByCondition" parameterType="Map">
	update users
	<set>
		<if test="name!=null">
			name=#{name},
		</if>
		<if test="pwd!=null">
			pwd=#{pwd},
		</if>
	</set>
	where id=#{id}
</update>

<!--多参数  -->
<select id="selectByCondition" resultType="User">
    select * from users where name=#{0} and pwd=#{1}
</select>
</mapper> 

6、在mybatis-config.xml中注册映射文件:

<mappers>
		<!-- 四种配置方式 -->
		<!-- 找寻对应的xml文件 -->
		<!-- <mapper resource="com/jereh/dao/UserDao.xml"/> -->
		<!-- 找寻接口文件,自动匹配对应的xml文件 -->
		<!-- <mapper class="com.jereh.dao.UserDao"/> -->
		<!-- 找寻磁盘目录下的对应xml文件 --> 
		<!-- <mapper url="file:///E:\workspaces\myeclipse\MyBatis\src\com\jereh\dao\UserDao.xml" /> -->
		<!-- 扫描包下的所有xml文件,该包下的所有映射都会匹配 -->
		<package name="com.jredu.dao"/>
	</mappers>

7、编写测试类

package com.jredu.junit;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.jredu.dao.UserDao;
import com.jredu.entity.User;
import com.jredu.util.SqlSessionFactoryUtil;

public class UserTest {
	
	private SqlSession session;
	private UserDao dao;
	private Logger logger=Logger.getLogger(getClass());
	

	/**
	 * 运行测试前需要执行的方法
	 * @throws Exception
	 */
	@Before 
	public void setUp() throws Exception {
		session=SqlSessionFactoryUtil.openSession();
		dao=session.getMapper(UserDao.class);
	}

	/**
	 * 运行测试后需要执行的方法
	 * @throws Exception
	 */
	@After
	public void tearDown() throws Exception {
		session.close();
	}

	@Test
	public void test1() {
		List<User> list = dao.selectAll();
		logger.info(list);
	}
	
	@Test
	public void test2(){
		User user= dao.findUserWithAdress(2);
		logger.info(user);
	}
	
	@Test
	public void test3(){
		User user= dao.findUserWithAdress2(2);
		logger.info(user);
	}
	
	@Test
	public void test4(){
		User user= dao.findUserWithAdressAndComments(2);
		logger.info(user);
	}
	
	//动态sql
	//if
	@Test
	public void test5(){
		User user= new User();
		user.setId(2);
		user=dao.findUserByCondition(user);
		System.out.println(user);
	}
	
	//动态sql
	//choose when otherwise
	@Test
	public void test6(){
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("by", "id");
		map.put("id", 2);
		User user=dao.findUserByCondition2(map);
		System.out.println(user);
	}
	
	//动态SQL
	//where:代替了where关键字
	@Test
	public void test7(){
		User user = new User();
		user.setId(3);
		user=dao.findUserByCondition3(user);
		System.out.println(user);
	}
	
	/**
	 * trim:作用跟where类似
	 * 1、可以添加关键字
	 * 2、根据前缀规则可以去掉匹配到的第一个关键字
	 */
	@Test
	public void test8(){
		User user = new User();
		user.setId(3);
		user=dao.findUserByCondition4(user);
		System.out.println(user);
	}
	
	/*
	 * foreach
	 * 可以循环添加多个参数,遍历一个集合
	 */
	@Test
	public void test9(){
		Map map= new HashMap();
		List list= new ArrayList();
		list.add(2);
		list.add(3);
		map.put("ids",list);
		List<User> user=dao.findUserByCondition5(map);
		System.out.println(user);
	}
	
	/**
	 * set:添加一个set关键字
	 * 添加一个set关键字
	 * 
	 * @param user
	 * @return
	 */
	@Test
	public void test10(){
		User user = new User();
		user.setId(2);
		user.setName("老王");
		int code =dao.updateByCondition(user);
		if(code>0){
			session.commit();
			System.out.println("更新成功");
		}
	}
	
	/**
	 * 多参数
	 */
	public void test11(){
		User user = dao.selectByCondition("小张", "111111");
		System.out.println(user);
	}
	
}


配置文件的基本结构:

MyBatis框架详解
MyBatis框架详解