MyBatis的总结(上)

一:走进MyBatis

框架:
	
	1:是一系列jar包,其本质是对JDK功能的拓展.
	
	2:框架是一组程序的组合,包含了一系列的最佳实践,作用是解决某一个领域的问题.
WEB开发中的最佳实践:根据职责的纵向划分:控制层 业务层  持久层

	控制层:WEB/MVC: 负责处理页面交互的相关操作(Struts2/Spring MVC)
	
	业务层:service: 负责复杂的业务逻辑计算和判断(Spring)
	
	持久层:dao:     负责将业务逻辑数据进行持久化存储(MyBatis/Hibernate)
	

最佳实践图:
最佳实践图

ORM框架:
	
		遵循ORM思想实现的技术,解决的是持久层的问题(和数据库做CRUD):
	
一个良好的持久层应该保证:

		当持久层的实现技术改变的时候,不会影响上一层的代码(service).
	

ORM思想图:
ORM思想

MyBatis:
	
		MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎

所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,

将接口和 Java 的 POJOs(PlainOld Java Objects,普通的 Java对象)映射成数据库中的记录。
		 
		https://mybatis.github.io/mybatis-3/zh/index.html 手册里面足够学习了

二:基础操作:

MyBatis依赖jar包:  在github下载里面有好多好的项目源码 多动手敲代码

	1):MySQL驱动包:mysql-connector-java-5.1*jar
		
	2):核心包:mybatis-3.54.jar
	
	3):其他依赖.lib目录中所有的jar(有需要再拷贝)
		
	  mysql-connector-java-5.1.40.jar
	  

MyBatis的配置文件AND映射文件:
MyBatis的配置文件AND映射文件
MyBatis-Config.xml
MyBatis-Config.xml

日志文件的输出:
	
	先拷贝jar包:
	
		slf4j-api-1.7.21.jar
	
		slf4j-log4j12-1.7.21.jar
	
		并配合log4j-1.2.17.jar一起使用

	log4j.properties文件内容:
	
		#设置全局的日志配置:输出Error级别,输出到控制台  日志的级别:ERROR>WARN>INFO>DEBUG>TRACE级别越低,输出的信息越详细
		log4j.rootLogger=ERROR, stdout
		#设置自定义的日志级别  每次记得修改包名
		log4j.logger.cn.wolfcode.mybatis.hello=TRACE
		log4j.appender.stdout=org.apache.log4j.ConsoleAppender
		log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
		log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

OGNL表达式:
OGNL表达式

resultMap:

	主要解决表的列名跟属性名称不匹配的问题:
	

resultMap

Mapper接口:
	
	Mapper接口的原理:动态代理:Spring的时候重点来讲解
	

Mapper组件
Mapper组件

参数处理:

	//方式一:把多个参数封装成一个JavaBean
	Client login1(LoginVO vo);
	
	//方式二:使用Map对象来封装多个参数
	Client login2(Map<String, Object> paramMap);
	
	//方式三:使用Param注解,原理是方式二
	Client login3(@Param("username")String username,@Param("password")String password);
	
	List<Client> login4(@Param("orderby")String orderby);
	<select id="login1" parameterType="LoginVO" resultType="client">
		SELECT id,username,password FROM client Where username = #{username}
		AND password = #{password}
	</select>
	
	<select id="login2" parameterType="map" resultType="client">
		SELECT id,username,password FROM client Where username = #{username1}
		AND password = #{password1}
	</select>
	
	<select id="login3" resultType="client">
		SELECT id,username,password FROM client Where username = #{username}
		AND password = #{password}
	</select>
	
	<select id="login4" resultType="client">
		SELECT id,username,password FROM client
		ORDER BY ${orderby}
	</select>
	@Test
	public void testLogin1() throws Exception {
		LoginVO vo = new LoginVO("will","1111");
		SqlSession session = MyBatisUtil.getSession();
		ClientMapper clientMapper = session.getMapper(ClientMapper.class);
		Client client = clientMapper.login1(vo);
		session.close();
		System.out.println(client);
	}
	
	@Test
	public void testLogin2() throws Exception {
		Map<String,Object> paramMap = new HashMap<String,Object>(){
			{
				this.put("username1", "will");
				this.put("password1", 1111);
			}
		};
		SqlSession session = MyBatisUtil.getSession();
		ClientMapper clientMapper = session.getMapper(ClientMapper.class);
		Client clietn = clientMapper.login2(paramMap);
		session.close();
		System.out.println(clietn);
	}
	
	@Test
	public void testLogin3() throws Exception {
		SqlSession session = MyBatisUtil.getSession();
		ClientMapper clientMapper = session.getMapper(ClientMapper.class);
		Client clietn = clientMapper.login3("will","1111");
		session.close();
		System.out.println(clietn);
	}
	
	@Test
	public void testLogin4() throws Exception {
		SqlSession session = MyBatisUtil.getSession();
		ClientMapper clientMapper = session.getMapper(ClientMapper.class);
		List<Client> clietn = clientMapper.login4("id desc");
		session.close();
		for (Client c : clietn) {
			System.out.println(c);
		}
	}

参数处理:
参数处理

MyBatipse插件:

		MyBatipse是Eclipse的一个插件,提供了内容提示和MyBatis的配置文件验证功能!

三:注解开发

开发和配置MyBatis框架:

		方式一:使用XML配置,SQL和映射写在XML文件中.   推荐!
	
		方式二:使用注解配置,SQL和映射写在JAVA代码中(Mapper接口).
public interface UserMapper {
	
	@Insert("insert into t_user value (#{id},#{name},#{salary})")
	@Options(useGeneratedKeys=true,keyProperty="id")
	void save(User u);
	
	@Update("UPDATE t_user set name = #{name}, salary = #{salary} where id = #{id}")
	void update(User u);
	
	@Delete("DELETE FROM t_user WHERE id = #{id}")
	void delete(Long id);
	
	@Select("SELECT * FROM t_user WHERE ID = #{id}")
	@Results(id="BaseResultMap",value={
			@Result(column="id",property="id"),
			@Result(column="name",property="name"),
			@Result(column="salary",property="salary")
	})
	User get(Long id);
	
	@Select("SELECT * FROM t_user")
	@ResultMap("BaseResultMap")
	List<User> listAll();
}
	既然修改了mapper文件,那么
	
	mybatis-config.xml文件中修改为<mapper> <mappec class=""/> </mapper>

四:动态SQL

choose:选择,if  else 一个意思
	<choose>
		<when test="deptId > 0"> AND deptId = #{deptId}</when>
		<otherwise>AND deptId IS NOT NULL</otherwise>
	</choose>
Where:若果条件以AND或者OR开头,就应该替换为WHERE

set:如果中间以有值就输入,最后一个去掉逗号,
	<set>
		<if test="name!=null">
			name = #{name},
		</if>
		<if test="password != null">
		password = #{password},
		</if>
	</set>
trim:可以替代whereset 一般不用

trim的作用图:
trim的作用

mapper文件:

public interface EmployeeMapper {
	List<Employee> query(
			@Param("minSalary")BigDecimal minSalary,
			@Param("maxSalary")BigDecimal maxSalary,
			@Param("deptId") Long deptId
			);
	
	void batchDelete(@Param("ids") List<Long> ids);
	
	void batchSave(@Param("emps") List<Employee> emps);
}
		<!-- 
		foreach元素:
		collection属性:表示对哪一个集合或数组做迭代
						如果参数是数组类型,此时Map的可以为array
						如果参数是List类型,此时Map的key为list
						我们可以在参数上使用Param注解,规定死Map中key是什么.@Param("ids")
						open属性:在迭代集合之前,拼接什么符号.
						close属性:在迭代集合之后,拼接什么符号.
						separator属性:在迭代元素时,每一个元素之间用什么符号分割开来.	
						item属性:被迭代的每一个元素的变量
						index属性:迭代的索引	
		 -->
	<delete id="batchDelete">
		DELETE employee where id in
		<foreach collection="ids"  open="(" close=")" separator="," item="id">
			#{id}
		</foreach>
	</delete>
mysql的批量插入:

	<insert id="batchSave">
		inset into employee (name,sn,salary) values
		<foreach collection="emps" separator="," item="e">
			(#{e.name},#{e.sn},#{e.salary})
		</foreach>
		
	</insert>
查询操作:

	<select id="query" resultType="Employee">
		SELECT id,name,sn,salary,deptId From employee
		<where>
			<if test="minSalary!=null">
				AND salary >= #{minSalary}
			</if>

			<if test="maxSalary">
				AND salary &lt;= #{maxSalary}
			</if>

			<choose>
				<when test="deptId > 0"> AND deptId = #{deptId}</when>
				<otherwise>AND deptId IS NOT NULL</otherwise>
			</choose>
		</where>
	</select>
bind:可以吧重复的小段代码提出来用

sql:把重复的代码包装起来利用他的id调用

include:文件中插入sql的代码.

分页查询: 回顾一下这一篇博客的知识点

domain

	<select id="query" resultType="Employee">
		SELECT id,name,sn,salary,deptId From employee
		<where>
			<if test="minSalary!=null">
				AND salary >= #{minSalary}
			</if>

			<if test="maxSalary">
				AND salary &lt;= #{maxSalary}
			</if>

			<choose>
				<when test="deptId > 0"> AND deptId = #{deptId}</when>
				<otherwise>AND deptId IS NOT NULL</otherwise>
			</choose>
		</where>
	</select>

mapper

	public interface EmployeeMapper {
		
		List<Employee> queryForList(QueryObject qo);
		
		int queryForCount(QueryObject qo);
	}
	<mapper namespace="cn.wolfcode.mybatis.hello.mapper.EmployeeMapper">
	
		<sql id="base_where">
			<where>
				<if test="keyword != null and keyword != ''">
					<bind name="keywordLike" value="'%'+keyword+'%'"/>
					AND (name like #{keywordLike} OR sn LIKE #{keywordLike})
				</if>
				
				<if test="minSalary!=null">
					AND salary >= #{minSalary}
				</if>
				
				<if test="maxSalary!=null">
					AND salary &lt;= #{maxSalary}
				</if>
				
				<if test="deptId > 0">
					AND deptId = #{deptId}
				</if>
				
			</where>
		</sql>
		
		<!-- 查询结果集 -->
		<select id="queryForList" resultType="Employee">
			Select id,name,sn,salary,deptId FROM employee
			<include refid="base_where" />
			<if test="pageSize > 0">
				LIMIT #{start},#{pageSize}
			</if>
		</select>
	
	
		<!-- 查询结果总数 -->
		<select id="queryForCount" resultType="int">
			SELECT COUNT(id) FROM employee
			<include refid="base_where" />
		</select>
	
	</mapper>

query

@Getter
@Setter
public class EmployeeQueryObject extends QueryObject{
	
	private String keyword;
	private BigDecimal minSalary;
	private BigDecimal maxSalary;
	private Long deptId = -1L;
	
	public String getKeyword(){
		return employ2null(keyword);
	}
}
@Getter
public class PageResult {
	private List<?> result;
	private int totalCount;

	private int currentPage = 1;
	private int pageSize = 3;

	private int prevPage;
	private int nextPage;
	private int totalPage;

	public PageResult(List<?> result, int totalCount, int currentPage, int pageSize) {
		this.result = result;
		this.totalCount = totalCount;
		this.currentPage = currentPage;
		this.pageSize = pageSize;

		this.totalPage = totalCount % pageSize == 0 ? totalCount % pageSize : totalCount % pageSize + 1;
		this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
		this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;
		currentPage = currentPage > totalPage ? totalPage : currentPage;
	}
}

@Getter
@Setter
public class QueryObject {
	private int currentPage = 1;
	private int pageSize = 3;

	public int getStart() {
		return (currentPage - 1) * pageSize;
	}

	//如果说字符串为空字符串,也应该设置为null
	public String employ2null(String str) {
		return hasLength(str) ? str : null;
	}

	public boolean hasLength(String str) {
		return str != null && !"".equals(str.trim());
	}
}

service

public interface IEmployeeService {
	
	PageResult query(QueryObject qo);
}

impl

public class EmployeeServiceImpl implements IEmployeeService{
	
	private EmployeeMapper employeeMapper = MyBatisUtil.getMapper(EmployeeMapper.class);
	
	public PageResult query(QueryObject qo) {
		int rows = employeeMapper.queryForCount(qo);
		if(rows == 0){
			return new PageResult(Collections.EMPTY_LIST,0,1,qo.getPageSize());
		}
		List<Employee> result = employeeMapper.queryForList(qo);
		return new PageResult(result,rows,qo.getCurrentPage(),qo.getPageSize());
	}
}

MyBatisUtil

	public class MyBatisUtil {
		
		private static SqlSessionFactory factory = null;
		
		static{
			InputStream in;
			try {
				//创建SqlSessionFactory对象
				in = Resources.getResourceAsStream("mybatis-config.xml");
				factory = new SqlSessionFactoryBuilder().build(in);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		//返回一个SqlSession对象
		public static SqlSession getSession(){
			//默认false不自动提交事务
			return factory.openSession();
		}
		
		public static <T> T getMapper(Class<T> mapperClass){
			return getSession().getMapper(mapperClass);
		}
	}

mybatis-config.xml

<configuration>
		
		<properties resource="db.properties">
		</properties>
	
		<!-- 日志技术 -->
		<settings>
			<setting name="logImpl" value="LOG4J"/>
		</settings>
		
		<typeAliases>
			<!-- <typeAlias type="cn.wolfcode.mybatis.hello.User" alias="User"/> -->
			<!-- 一般写到domain包就可以了,自动为该包中的类起别名,默认的别名就是简单类名首字母小写,其实不区分大小写 -->
			<package name="cn.wolfcode.mybatis.hello"/>
		</typeAliases>
		
		<!-- 1:配置数据库的环境 -->
		<environments default="dev">
			<!-- 开发环境:在以后事务管理器和连接池都是交给Spring框架来管理的 -->
			<environment id="dev">
				<!-- ①:事务管理器 -->
				<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>
		<!-- 2:关联映射文件 -->
		<mappers>
			<mapper resource="cn\wolfcode\mybatis\hello\mapper\EmployeeMapper.xml"/>
		</mappers>
</configuration>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值