MyBatis入门详细

MyBatis入门

环境搭建

1、eclipse项目创建

java项目或者WEB项目都可以

2、添加jar包

jar包 说明
asm-3.3.1.jar 操作java字节码的类库
javassist-3.24.1-GA.jar 编辑Java字节码的类库
cglib-3.2.10.jar 动态代理
slf4j-api-1.7.26.jar 日志
slf4j-log4j12-1.7.26.jar 日志依赖
commons-logging-1.2.jar 包含了日志功能
log4j-1.2.17.jar log4日志文件
mybatis-3.2.2.jar mybati s核心依赖jar
mysql-connector-java-5.1.0-bin. jar mysql驱动

选中jar包,点击右键Add to buildPath(添加到项目路径)

3、核心配置文件

  • 在项目中新建资源文件夹(-般命名为resources)。

  • 添加链接数据库信息的属性文件(database.properties)。

  driver=com. mysq1. jdbc . Driver
  #在和mysq1传递数据的过程中,使用unicode编码格式,并且字符集设置为utf-8
  ur1=jdbc :mysq1://127.0.0.1: 3306/smbms ?useuni code=true&characterEncoding=utf-8
  user=root
  passwor d=root		

* 新建Mybatis配置文件,默认的名字configuration.xml(-般命名为mybatis-config.xml)。 I
  该配置文件配置内容大体上有: mybatis的运行行为,运行环境,别名,sql映射文件等。

```xml-dtd

<configuration>
	
	<properties resource="database.properties">properties>
	
	
	
	<typeAliases>
		<package name="cn.com.pojo" />
	typeAliases>
	
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			dataSource>
		environment>
	environments>
	
	<mappers>
		<mapper resource="cn/com/mapper/UserMapper.xml" />
		<mapper resource="cn/com/mapper/ProviderMapper.xml" />
	mappers>
configuration>
  • Mapper.xml文件配置模板:

<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
select>
mapper>

添加上面文件的头信息

4、关联约束文件

作用:编写配置文件内容的时候有提示。联网的情况下不需要手动关联

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sBavmGlS-1593354693608)(C:\Users\23792\AppData\Roaming\Typora\typora-user-images\image-20200604184052710.png)]

  • eclipse中如何配置约束文件?

    MyBatis-config.xml命名空间:-//mybatis.org//DTD Config 3.0//EN

    xxxMapper.xml命名空间:-//mybatis.org//DTD Mapper 3.0//EN

windows—>preferences—>搜索 “xml” —>XML Catalog—>Add—>File System

注意:添加的时候confing.dtd对应Config 3.0命名空间,Mapper.dtd对应Mapper 3.0命名空间,否则配置文件出错。

5、编写实体类

实体类放在cn.jbit.pojo包下

注意:实体类名称、字段名与数据库名保持一致,并且提供set和get方法。

6、SQL映射文件

  • 普通字段、对象、集合映射
		
		
		
		
		
		
		
		
		
			
		association>

	
	
	
	
		
		
	collection>
		resultMap>

别名映射方式(不推荐):

	<select id="getUserRoleName" resultType="User">
		SELECT u.*,roleName AS userRoleName 
		FROM
		smbms_user u,smbms_role r
		WHERE u.userRole = r.id
		AND userName LIKE CONCAT('%' , #{param1}, '%')
		AND userRole=#{param2}
	select>
	注意:JavaBean中添加字段userRoleName。

7、编写SQL语句

	<sql>	
		id,
		userCode,
		userName,
		userPassword,
		gender,
		birthday,
		phone,
		address,
		userRole,
		createdBy,
		creationDate,
		modifyBy,
		modifyDate
	sql>
	
	<insert id="saveUser">
		INSERT INTO smbms.smbms_user
		<trim prefix="VALUES(" suffix=")" suffixOverrides=",">
			NULL,
			#{userCode},
			#{userName},
			#{userPassword},
			#{gender},
			#{birthday},
			#{phone},
			#{address},
			#{userRole},
			#{createdBy},
			#{creationDate},
			#{modifyBy},
			#{modifyDate},
		trim>
	insert>
	
	<select id="getUserList" resultType="User">
		 SELECT <include refid="userCol">include>
	  	 FROM smbms_us
	select>

	
	<delete id="deleteUser">
		DELETE FROM smbms.smbms_user
		<where>
			<if test="uid != null and uid != 0">
				id = #{uid}
			if>
		where>
	delete>
	
	<update id="updateUser">
		UPDATE smbms.smbms_user
		<set>
			userPassword = #{pwd}
		set>
		<where>
			<if test="uid != null and uid != 0">
				id = #{uid}
			if>
		where>
	update>

8、编写测试代码

代码测试除了常用的Main方法外,还可以使用 junit 第三方插件进行测试

JUnit在eclipse中使用

1.右击项目–>Bulid Path–> configure Build Path–>Libraryies–>Add Libraryies -->选择JUnit

2.创建测试类方法上边使用@Test注解

3.右击方法 --> Run --> JUint Test

  • 方式一:
		String resource = "mybatis-config.xml";//指定配置文件
		InputStream inputStream = Resources.getResourceAsStream(resource);//读取配置文件,转换为输入流
		SqlSessionFactory sqlSessionFactory =
		new SqlSessionFactoryBuilder().build(inputStream);//构建一个会话工厂
		
		//类似为connection的对象,封装了connection
		SqlSession session = sqlSessionFactory.openSession();
		int count = session.selectOne("countTeacher");
		System.out.println(count);
		session.close();
  • 方式二:
		try {
			String resource = "mybatis-config.xml";	//资源文件路径
			//使用IO流读取资源配置文件
			InputStream input = Resources.getResourceAsStream(resource);
			SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
			//构建SqlSession工厂对象
			SqlSessionFactory factory = builder.build(input);
			//构建SqlSession会话
			session = factory.openSession();
			//持久化操作
			UserMapper mapper = session.getMapper(UserMapper.class);
			Integer count = mapper.getUserCount();
			if(count>0){
				System.out.println("总共有:"+count);
			}else{
				System.out.println("程序异常!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();//释放资源
		}

9、小结

● MyBatis中的SQL传参:
1、单个参数
a、传入的是基本数据类型:参数名自定义(因为只有一个参数,不会混淆)
b、传入的是对象类型:直接写对象的属性名即可
2、多个参数
a、可以用下标表示,例如#{0} #{1}
b、可以用参数关键字表示,例如#{param1} #{param2}
c、用一个Map来封装多个参数,取值的时候用的是Key
d、使用@Param注解,例如@Param(“name”) @Param(“age”)

● 断言:Assert.assertEquals(rowCount,1);

● 类型别名:

		
		
		
		
		
		
	

● 模糊查找:SELECT * FROM teacher WHERE teaName like concat(’%’,#{name},’%’)

●节点id可以和接口中方法名保持-致,也可不一致,但是如果使用getmapper. () api就必须保持一-致
resultType : sql语句返回的结果类型, 可以使用别名,如果遇到复杂的sql不知道结果类型写什么,笨办法,看看当前接口中该方法的返

问题:若两种方式同时都用了,那么哪种方式优先?

答案:外部优先使用。 resource 属性值的优先级高于property子节点配置的值。

●resultType和resultMap的区别是什么?
1、resultType直接表示返回类型
基本数据类型
复杂数据类型
2、resultMap :对外部resultMap的引用
数据库字段信息与对象属性不致.
复杂的联合查询,自由控制映射搭巢
注意:二者不能同时存在,本质上都是Map数据结构

●Mybatis中sql语句的占位符#{}和${}

#{}:表示一个占位符号,通过 #{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型
转换。#{} 可以有效防止 sql注入。#{} 可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类
型值,#{} 括号中可以是 value 或其它名称。

${}: 表示拼接sql串,通过 ${} 可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,不能防止sql
注入问题, 可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,{} 括号中只能是 value。

●日志:添加log4j.jar 添加配置文件 开发:DEBUG 发布:INFO

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pEP3aX6e-1593354693610)(F:\Program Files\我的办公文档\学习笔记\y2\image-20200604185457262.png)]

示例:

<settings>
	
	
	
settings>

问题:导入配置文件database.properties若两种方式同时都用了,那么哪种方式优先?
结论:外部优先使用。 resource 属性值的优先级高于property子节点配置的值

问题:MyBatis框架总体执行流程?
回答:加载配置文件 解析Sql Sql的执行,映射结果

10、MyBatisUtil工具类


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 MyBatisUtil {
	private static SqlSessionFactory sqlSessionFactory;
	private static final String CONFIG_FILE = "mybatis-config.xml";

	static {
		InputStream inputStream = null;
		try {
			// 使用IO流读入资源文件
			inputStream = Resources.getResourceAsStream(CONFIG_FILE);
			// 构建一个会话工厂
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static SqlSession getSession() {
		return sqlSessionFactory.openSession();
	}
}

a、Dao层接口


import java.util.List;

import cn.mybatis.pojo.User;

public interface UserMapper {
	/**
	 * 统计用户记录
	 * @return
	 */
	Integer getUserCount();
	/**
	 * 查询所有
	 * @return
	 */
	List getUsers();

}

注意:id 可以和接口b中的命名保持一致,使用getmapper()api必须保持一致

b、对用的Mapper文件




<mapper namespace="cn.mybatis.mapper.UserMapper">
	
	
	<select id="getUserCount" resultType="int">
		SELECT count(1) FROM smbms_user
	select>
	<sql id="userCol">
		id,
		userCode,
		userName,
		userPassword,
		gender,
		birthday,
		phone,
		address,
		userRole,
		createdBy,
		creationDate,
		modifyBy,
		modifyDate
	sql>
	<select id="getUsers"  resultType="cn.mybatis.pojo.User">
		SELECT<include refid="userCol"/>
	    FROM smbms_user
	select>
mapper>

c

c、测试方法

package cn.com.test;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import cn.com.mapper.MyBatisUtil;
import cn.com.mapper.ProviderMapper;
import cn.com.mapper.UserMapper;
import cn.com.pojo.Provider;
import cn.com.pojo.User;

public class TestMyBatis {
	@Test
	public void testGetUserCount() {
		SqlSession session = null;
		try {
			session = MyBatisUtil.getSession(); // 通过BaseDao获取SqlSession会话
			// 持久化操作
			UserMapper mapper = session.getMapper(UserMapper.class);
			Integer count = mapper.getCount();
			if (count > 0) {
				System.out.println("共有:" + count + "条");
			} else {
				System.out.println("程序异常");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close(); // 释放资源
			}
		}
	}

	@Test
	public void testUserList() {
		SqlSession session = null;
		try {
			session = MyBatisUtil.getSession(); // 通过BaseDao获取SqlSession会话
			// 持久化操作
			UserMapper mapper = session.getMapper(UserMapper.class);
			List<User> list = mapper.getUserList();
			if(list.size() > 0){
				for (User user : list) {
					System.out.println(user);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close(); // 释放资源
			}
		}
	}
}

动态SQL

1、理论即概念

概念:通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

  • if
 <select id="selectUseIf" parameterType="com.soft.test.model.DynamicTestModel" resultMap="userMap">
        select * from t_user where 1=1
		
        <if test='id != null'>
            and id=#{id}
        if>
    select>
  • where

	<select id="getUsersMap" resultType="User" parameterType="User">
		SELECT
		<include refid="userCol">include>
		FROM smbms_user
		
		<where>
			<if test="userName != null and userName != ''">
				AND userName LIKE CONCAT('%',#{userName},'%')
			if>
			<if test="urole != null and urole != 0">
				and userRole =#{urole}
			if>
		where>
	select>
  • trim

    prefix :前缀
    suffix :后缀
    prefixOverrides :对前缀的替换
    suffixOverrides :对后缀的替换


	<select id="getUsersAnno" resultType="User">
		SELECT
		<include refid="userCol">include>
		FROM smbms_user
		<trim prefix="WHERE" prefixOverrides="and | or">
			<if test="uname != null and uname != ''">
				and userName LIKE CONCAT('%' ,#{uname}, '%')
			if>
			<if test="urole != null and urole != 0">
				and userRole =#{urole}
			if>
		trim>
	select>
  • set
	
	<update id="updateUser">
		UPDATE smbms.smbms_user
		
		<set>
			userPassword = #{pwd}
		set>
		<where>
			<if test="uid != null and uid != 0">
				id = #{uid}
			if>
		where>
	update>
  • choose

  • foreach


	<select id="getProviderListByArray" resultType="Provider">
		SELECT * FROM smbms_provider WHERE id IN
		<foreach collection="array" item="ids" open="(" separator=","
			close=")">
			#{ids}
		foreach>
	select>
	
	<select id="getProviderListByList" resultType="Provider">
		SELECT * FROM smbms_provider WHERE id IN
		<foreach collection="list" item="idsList" open="(" separator=","
			close=")">
			#{idsList}
		foreach>
	select>
	
	<select id="getProviderListBySingleMap" resultType="Provider">
		SELECT * FROM smbms_provider
		WHERE proAddress LIKE CONCAT('北京市','%')
		AND id IN
		<foreach collection="idsMap" item="ids" open="(" separator=","
			close=")">
			#{ids}
		foreach>
	select>
	
	<select id="getProviderListByDoubleMap" resultType="Provider">
		SELECT * FROM smbms_provider
		WHERE proAddress LIKE CONCAT(#{address},'%')
		AND id IN
		<foreach collection="idsMap" item="ids" open="(" separator=","
			close=")">
			#{ids}
		foreach>
	select>

a、如果传入的是单个参数
1-如果传入的是数组,则用array表示
2-如果传入的是集合,则用list表示
3-如果传入的事Map,则用Key值表示
b、如果有取别名@param,则直接用别名

  • 动态sql-if
    1.单参
    注意:如果参数没有使用注解那么if标签中test表达式应该判断属性
    如果参数使用注解,那么if标签中test表达式应该根据注解名称来判断
    2.多参
    注意:如果参数时封装在对象中,那么if标签中test表达式应该根据对象中的属性判断
    如果参数封装在map中,那么if标签中test表达式应该根据测试方法中map的key判断
    如果参数封装使用注解,那么if标签中test表达式应该根据参数的注解名称来判断
    动态sq1 -where
    where元素会自动识别标签中是否有返回值,如果有就会自动插入where关键字,
    而且也能将改标签返回的内容以and或者or开头的关键字,自动剔除掉。

  • 动态sql if+trim 替换if+where
    区别: where元素会自动的自动追加一先判断 其包含的内容是否有返回值,如果有就自动追加where关键字,
    而且在拼接sql时会自动忽略and或者or开头的关键字
    trim替换是用其属性来指定,
    比如:判断trim包含内容不为空需要追加where
    这时候需要使用属性prefix来指定,
    而sq1拼接或略的and或者or关键字需要用属性prefixoverrides来指定

  • 去除重复查询distinct
    语法:SELECT DISTINCT 列名称 FROM 表名称

果有取别名@param,则直接用别名

  • 动态sql-if
    1.单参
    注意:如果参数没有使用注解那么if标签中test表达式应该判断属性
    如果参数使用注解,那么if标签中test表达式应该根据注解名称来判断
    2.多参
    注意:如果参数时封装在对象中,那么if标签中test表达式应该根据对象中的属性判断
    如果参数封装在map中,那么if标签中test表达式应该根据测试方法中map的key判断
    如果参数封装使用注解,那么if标签中test表达式应该根据参数的注解名称来判断
    动态sql-where
    where元素会自动识别标签中是否有返回值,如果有就会自动插入where关键字,
    而且也能将改标签返回的内容以and或者or开头的关键字,自动剔除掉。

  • 动态sql if+trim 替换if+where
    区别: where元素会自动的自动追加一先判断 其包含的内容是否有返回值,如果有就自动追加where关键字,
    而且在拼接sql时会自动忽略and或者or开头的关键字
    trim替换是用其属性来指定,
    比如:判断trim包含内容不为空需要追加where
    这时候需要使用属性prefix来指定,
    而sq1拼接或略的and或者or关键字需要用属性prefixoverrides来指定

  • 去除重复查询distinct:
    语法:SELECT DISTINCT 列名称 FROM 表名称

你可能感兴趣的:(MyBatis入门详细)