java框架复习——Mybatis

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_35262405/article/details/98676717

概述

Mybatis的特点

  • 对jdbc做了很好的封装
  • 容易掌握
  • 灵活性强

Mybatis文件夹结构
在这里插入图片描述

  • lib:第三方的依赖包
  • mybatis-3.1.1.jar:核心包
  • mybatis-3.1.1.pdf:说明文档
  • mybatis-3.1.1-javadoc.jar:mybatis的api
  • mybatis-3.1.1-source.jar:源代码

Mybatis示例

1.第一步创建java项目

2.导入所需要的jar
在这里插入图片描述
3.建表

4.建立实体类

5.创建配置文件

创建sqlMapConfig.xml文件
在这里插入图片描述
6.库表的mapping映射文件

创建数据库表的映射文件PersonMapper.xml
在这里插入图片描述
7.编写测试代码

public class PersonTest {
	
	/**
	 * 创建session工厂
	 */
	SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp() throws Exception {
		String resource = "sqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}

	
	/**
	 * 根据id查询person
	 */
	@Test
	public void selectPersonById() {
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		try {
			//第一个参数namespace+"."+sql的id,第二个参数就是sql所需要的参数
			Person person = session.selectOne(
					"cn.itcast.model.Person.selectPersonById", 1);
			System.out.println(person);
		}finally {
			//关闭连接
			session.close();
		}
	}
}

resultType、parameterType、resultMap和parameterMap


详细介绍
https://blog.csdn.net/CSDN_Terence/article/details/60779889


这四个属性都是映射文件中的,其中resultType和resultMap为一组,parameterType和parameterMap为一组,一般只会出现每组中的最多其中一个。

示例如下:

<select id="selectPersonById" parameterType="int" resultMap="BaseResultMap" useCache="true">
	select * from person where person_id = #{id}
</select>

resultType

这个属性表示查询结果集与java对象之间的一种关系,处理查询结果集,映射到java对象或者基本属性。

可以直接指定为基本数据类型,注意首字母一定要小写

resultType还可以使用map接收查询结果,其中map的键就是查询的字段名字,值就是字段的值,多数情况下不使用。

<!-- 
	返回不需要字段映射的就可以使用resultType
 -->
<select id="selectPersonCount" resultType="int">
	select count(*) from person
</select>

同样也可以直接指定为一个java对象,但是需要注意的是,如果是自定义的实体类,属性名字有大写那么一般就会和数据库表中的字段名不相同,那样就无法映射到指定属性,也无法获取查询结果。

这个时候一般不会用resultType而是使用resultMap。

resultMap

同样的这个属性也表示查询结果集与java对象之间的一种关系,处理查询结果集,映射到java对象或者基本属性。

使用这个属性需要和resultMap标签一起用起来,为的就是解决resultType无法解决的问题——对象的字段和数据库的字段无法相互映射。

可以看出personId和personAddr是无法自动映射的字段

<resultMap type="person" id="BaseResultMap">
	<!-- 
		id列只有一个
		column:表的字段名
		property:实体类的属性名
	 -->
	<id column="person_id" property="personId"/>
	<result column="name" property="name"/>
	<result column="gender" property="gender"/>
	<result column="person_addr" property="personAddr"/>
	<result column="birthday" property="birthday"/>
</resultMap>

如果这个标签加了extends属性,那么设置的属性值就是需要继承的另外一个resultMap标签,会把这个标签的映射字段全部继承。

如果这个需要映射的实体类和其他的实体类在数据库中还有一对多或者多对多的关系,并且实体类中还有集合类型属性,那么需要在其中用collection做映射。

<resultMap type="person" id="selectRoleByPersonIdRM" extends="BaseResultMap">
	<!-- 
		collection一对多的关联查询
		property:一中多的属性名
		ofType:指的是多的数据类型
	 -->
	<collection property="roleList" ofType="com.rl.model1.Role">
		 <id column="ROLE_ID" property="roleId" jdbcType="INTEGER" />
   		<result column="ROLE_NAME" property="roleName" jdbcType="VARCHAR" />
   		<result column="DESCPRIT" property="descprit" jdbcType="VARCHAR" />
	</collection>
</resultMap>

如果这个需要映射的实体类和其他的实体类在数据库中还有多对一或者一对一的关系,并且实体类中还有其他实体类属性,那么需要在其中用association做映射。

<resultMap type="person" id="selectIdCardByPersonIdRM" extends="BaseResultMap">
	<association property="ic" javaType="com.rl.model1.IdCard">
		<id column="PERSON_ID" property="personId" jdbcType="INTEGER" />
   		<result column="CARD_NO" property="cardNo" jdbcType="VARCHAR" />
	</association>	
</resultMap>

注意:必须把 <association>放在 <result>后面
否则会发生的后果

parameterType

这个属性则是sql语句中待填写的数值的映射,和resultType同样可以支持基本数据类型和实体类对象,同样基本类型首字母小写,不过一般不会使用实体类对象,会发生映射问题。

parameterType同样还可以使用map传值,这也是多数情况下使用的,其中map的键就是映射的名字。

#{}和${}中的就是parameterType传入的数值,如果parameterType传入的是单个值,那么括号里填的是什么都只会映射到哪个值,但是如果是用map传入多个值,那么就需要与括号内的名字相匹配。

至于#{}和${}的区别在于#{}属于预编译,${}则只是单纯的在输出sql前把值传入进去。具体区别请看下面的Mybatis的sql预编译。

<!-- 
	id:sql的唯一标识
	parameterType:传递给sql的参数的数据类型
	resultType:返回数据结果的类型
	#{id}:用于接收参数的语法{}中的内容,如果是接收一个参数内容任意 select * from person_test where id = ?
	,#{}使用预编译的方式生成sql,防止sql的注入
	useCache:是否启用二级缓存true是启用false是禁用,默认是true
 -->
<select id="selectPersonById" parameterType="int" resultMap="BaseResultMap" useCache="true">
	select * from person where person_id = #{id}
</select>

parameterMap

与resultMap是同样的用法,只不过是输入的参数映射,但是一般情况下不会使用这个属性,多用parameterType。

Mybatis的sql预编译

参考文章如下

https://segmentfault.com/a/1190000004617028

Select 的语句的基本使用

List实体类的方式集合的查询

在这里插入图片描述

/**
	 * 查询person的集合
	 */
	@Test
	public void selectPersonList(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		try {
			//第一个参数namespace+"."+sql的id,第二个参数就是sql所需要的参数
			List<Person> personList = session.selectList(ns+"selectPersonList");
			for(Person person : personList){
				System.out.println(person);
			}
			
		}finally {
			//关闭连接
			session.close();
		}
	}

以map方式返回实体

在这里插入图片描述

/**
	 * 根据id查询person返回map实体
	 */
	@Test
	public void selectPersonByIdForMap(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		try {
			//第一个参数namespace+"."+sql的id,第二个参数就是sql所需要的参数
			Map<String, Object> person = session.selectOne(
					"cn.itcast.model.Person.selectPersonByIdForMap", 1);
			System.out.println(person);
		}finally {
			//关闭连接
			session.close();
		}
	}

返回map的集合

在这里插入图片描述

/**
	 * 返回map的集合
	 */
	@Test
	public void selectPersonListForMap(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		try {
			//第一个参数namespace+"."+sql的id,第二个参数就是sql所需要的参数
			List<Map<String, Object>> personMapList = session.selectList(ns+"selectPersonListForMap");
			System.out.println(personMapList);
		}finally {
			//关闭连接
			session.close();
		}
	}

ResultMap的使用

<!-- 
	resultMap:组装从数据库表中查询出来的自定义实体的
	type:实体的数据类型
	id:resultMap的唯一标识
 -->
<resultMap type="person" id="BaseResultMap">
	<!-- 
		id列只有一个
		column:表的字段名
		property:实体类的属性名
	 -->
	<id column="person_id" property="personId"/>
	<result column="name" property="name"/>
	<result column="gender" property="gender"/>
	<result column="person_addr" property="personAddr"/>
	<result column="birthday" property="birthday"/>
</resultMap>
<!-- 
	id:sql的唯一标识
	parameterType:传递给sql的参数的数据类型
	resultType:返回数据结果的类型
	#{id}:用于接收参数的语法{}中的内容,如果是接收一个参数内容任意 select * from person_test where id = ?
	,#{}使用预编译的方式生成sql,防止sql的注入
	useCache:是否启用二级缓存true是启用false是禁用,默认是true
 -->
<select id="selectPersonById" parameterType="int" resultMap="BaseResultMap" useCache="true">
	select * from person where person_id = #{id}
</select>
	/**
	 * 测试person表的selectPersonById
	 */
	@Test
	public void selectPersonById() {
		//创建SqlSession
		SqlSession session = sessionFactory.openSession();
		try {
			//selectOne:第一个参数:要执行的sql,命名空间.sql的id
			//第二个参数是传递给sql的实际参数
			Person person = session.selectOne("com.rl.mapper.PersonMapper.selectPersonById", 1);
			System.out.println(person);
		} finally{
			session.close();
		}	
	}

模糊查询

<!-- 
	${}:非预编译,使用直接拼接字符串的方式生成sql, {}中的内容必须从map或者查询对象中获得
	
 -->
<select id="selectPersonByName" parameterType="java.util.Map" resultMap="BaseResultMap">
	select * from person t where t.name  like '%${name}%'
</select>
	@Test
	public void selectPersonByName() {
		//创建SqlSession
		SqlSession session = sessionFactory.openSession();
		try {
			Map<String, Object> map = new HashMap<String,Object>();
			map.put("name", "满");
			List<Person> pList = session.selectList("com.rl.mapper.PersonMapper.selectPersonByName",map);
			for(Person p : pList){
				System.out.println(p);
			}
		} finally{
			session.close();
		}
	}

insert的使用

基本插入

在这里插入图片描述

/**
	 * insert
	 */
	@Test
	public void insert(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		
		Person person = new Person();
		person.setPersonName("张三");
		person.setPersonAge(300);
		person.setPersonAddress("盘丝洞");
		
		try {
			//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交
			session.insert(ns + "insert", person);
			//手动提交
			session.commit();
		} catch (Exception e) {
			session.rollback();
		}finally{
			session.close();
		}
	}

主键的返回

有些时候需要在键数据插入到数据库中后立刻得到数据的主键,那么就需要主键自动返回

<insert id="insert" parameterType="person">
	<!-- 
		selectKey是做主键返回的
		keyProperty:接收返回主键的属性
		order:insert语句和生成主键的sql的执行顺序mysql是AFTER,oracle是BEFORE
		resultType:返回主键的数据类型
		生成主键的sql select LAST_INSERT_ID()
	 -->
	<selectKey keyProperty="personId" order="AFTER" resultType="int">
		select LAST_INSERT_ID()
	</selectKey>
	insert into person (person_id, name, gender, person_addr, birthday)
	values(#{personId}, #{name}, #{gender}, #{personAddr}, #{birthday})
</insert>
	/**
	 * 	OrderDao orderDao;
	 * 
	 * 	OrderDetailDao detailDao;
	 * 
	 * pubic void saveOrder(Orders order, OrderDetail od){
	 *  返回订单编号
	 * 	orderDao.save(order);
	 *  od.setOrderId(order.getOrderId());
	 *  detailDao.save(od);
	 * 
	 * 
	 * }
	 * 
	 * 插入数据主键返回
	 */
	@Test
	public void insert1(){
		SqlSession session = sessionFactory.openSession();
		Person p = new Person();
		p.setName("黄盖");
		p.setGender(1);
		p.setPersonAddr("北京");
		p.setBirthday(new Date());
		try {
			int count = session.insert("com.rl.mapper.PersonMapper.insert", p);
			//数据库的变更都要提交事务
			session.commit();
			System.out.println(count);
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}finally{
			session.close();
		}
	}

update的使用

注意:某些不设置会出现值被置空的情况,如果不想发生这种情况需要使用动态sql
在这里插入图片描述

/**
	 * update
	 */
	@Test
	public void update(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		
		Person person = new Person();
		person.setPersonId(2);
		person.setPersonName("李四");
		//如果某些字段不设置会出现值被置空的情况,需要使用动态sql来解决
		//person.setPersonAge(100);
		//person.setPersonAddress("花果山");
		try {
			//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交
			session.update(ns + "update", person);
			//clazz.setclassId(person.getPersonId());
			//手动提交
			session.commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}finally{
			session.close();
		}
	}

delete使用

注意在删除的时候,sql中不要使用别名
在这里插入图片描述

/**
	 * update
	 */
	@Test
	public void delete(){
		//创建session
		SqlSession session = sqlSessionFactory.openSession();
		
		try {
			//瞬间改了mysql的数据库的隔离级别,把它变成可提交读,需要手动的提交
			session.delete(ns + "delete", 2);
			//手动提交
			session.commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}finally{
			session.close();
		}
	}

别名的定义

定义一个数据类型的别名

在sqlMapConfig.xml中定义,文件放在classpath下

<typeAliases>
	<!-- 
		type:要被定义成别名的数据类型
	 -->
	<typeAlias type="com.rl.model.Person" alias="person"/>
	<typeAlias type="com.rl.model.QueryCondition" alias="qc"/>
	
</typeAliases>

要在后面引入要使用别名的mapper配置文件

<mappers>
	<mapper resource="com/rl/mapper/PersonMapper.xml" />
</mappers>

别名的使用
在这里插入图片描述

定义一段sql语句

在这里插入图片描述
在这里插入图片描述

动态sql

动态sql可以解决很多问题,也可以提高sql的复用率,也是mybatis的一大特点

select动态组合条件查询(where标签的使用)

注意:

  • <where>会给我们自动的处理第一个and
  • 当实体类里面定义了基本的数据类型,where里面的判断空就不起作用了,因为基本数据类型会有初始值
<!-- 
	<where>用于动态条件组合查询,可以去掉where后的第一个and
 -->
<select id="selectPersonByCondition" parameterType="qc" resultMap="BaseResultMap">
	select * from person t
	<where>
		<if test="name != null">
			t.name like '%${name}%'
		</if>
		<if test="gender != null">
			and t.gender = #{gender}
		</if>
		<if test="personAddr != null">
			and t.person_addr like '%${personAddr}%'
		</if>
		<if test="birthday != null">
			<![CDATA[
				and t.birthday < #{birthday}
			]]>
		</if>
	</where>
</select>

update动态更新(set标签的使用)

注意:

  • <set>会给我们自动的处理最后一个逗号
  • 当实体类里面定义了基本的数据类型,where里面的判断空就不起作用了
    在这里插入图片描述

foreach标签使用(In查询、批量插入和删除)

In查询

<!-- 
	(1,2,3)
	map.put("ids", Integer[])
	
	foreach遍历集合来组装sql
	collection:map中集合的key
	open:以某种字符开始
	close:以某种字符结束
	item:集合中的元素
	separator:以某种字符分隔
	index:当前遍历到的索引号
 -->
<select id="selectPersonByIn" parameterType="map" resultMap="BaseResultMap">
	select * from person t where t.person_id in 
	<foreach collection="ids" open="(" close=")" item="personId" separator="," index="index">
		#{personId}
	</foreach>
</select>
@Test
public void selectPersonByIn() {
	//创建SqlSession
	SqlSession session = sessionFactory.openSession();
	try {
		Integer [] ids = {1,2,3};
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("ids", ids);
		List<Person> pList = session.selectList("com.rl.mapper.PersonMapper.selectPersonByIn", map);
		for(Person p :pList){
			System.out.println(p);
		}
	} finally{
		session.close();
	}
}

批量插入

<!-- 
	map.put("personList", List<Person> list)
	insert into person(id, name)values(1, 'zhansan'),(2, 'lisi'),...
 -->
<insert id="insertBatch" parameterType="map">
	
	<selectKey keyProperty="personId" order="AFTER" resultType="int">
		select LAST_INSERT_ID()
	</selectKey>
	insert into person (person_id, name, gender, person_addr, birthday)
	values
	<foreach collection="personList" separator="," item="person">
		(#{person.personId}, #{person.name}, #{person.gender}, #{person.personAddr}, #{person.birthday})
	</foreach>
</insert>

需要注意这里的item如果是一个实体类,那么要获得它的属性要通过.属性名

@Test
public void insertBatch(){
	SqlSession session = sessionFactory.openSession();
	List<Person> pList = new ArrayList<Person>();
	Map<String,Object> map = new HashMap<String,Object>();
	
	try {
		for(int i = 0; i < 1000008; i++){
			Person p = new Person();
			p.setName("黄盖"+i);
			p.setGender(1);
			p.setPersonAddr("北京"+i);
			p.setBirthday(new Date());
			pList.add(p);
			if(i%100 == 0){
				map.put("personList", pList);
				session.insert("com.rl.mapper.PersonMapper.insertBatch", map);
				pList.clear();
			}
		}
		map.put("personList", pList);
		session.insert("com.rl.mapper.PersonMapper.insertBatch", map);
	
		
		//数据库的变更都要提交事务
		session.commit();
		
	} catch (Exception e) {
		e.printStackTrace();
		session.rollback();
	}finally{
		session.close();
	}
}

批量删除

<!-- 
	(1,2,3)
	map.put("ids", Integer[])
	
	foreach遍历集合来组装sql
	collection:map中集合的key
	open:以某种字符开始
	close:以某种字符结束
	item:集合中的元素
	separator:以某种字符分隔
	index:当前遍历到的索引号
 -->
<delete id="deleteBatch" parameterType="map">
	delete from person where person_id in
	<foreach collection="ids" open="(" close=")" item="personId" separator="," index="index">
		#{personId}
	</foreach>
</delete>
@Test
public void deleteBatch(){
	SqlSession session = sessionFactory.openSession();
	List<Integer> idList = new ArrayList<Integer>();
	Map<String,Object> map = new HashMap<String,Object>();
	
	try {
		for(int i = 106; i <= 1000113; i++){
			idList.add(i);
			if(i%100 == 0){
				map.put("ids", idList);
				session.delete("com.rl.mapper.PersonMapper.deleteBatch", map);
				idList.clear();
			}
		}
		map.put("ids", idList);
		session.delete("com.rl.mapper.PersonMapper.deleteBatch", map);
		//数据库的变更都要提交事务
		session.commit();
		
	} catch (Exception e) {
		e.printStackTrace();
		session.rollback();
	}finally{
		session.close();
	}
}

关联查询

多对一或一对一的关联查询

在这里插入图片描述
在这里插入图片描述

一对多或多对多的关联查询

在这里插入图片描述
在这里插入图片描述

延迟加载

在做联合查询是查出首层实体对象,具体实体对象内部的关联对象只有用到的时候才去查询使用。

首先在mybatis核心配置文件中配置:

  • lazyLoadingEnabled:true使用延迟加载,false禁用延迟加载,默认为true
  • aggressiveLazyLoading:true启用时不使用延迟加载,false使用延迟加载
<settings>
		<!-- 
			延迟加载的总开关
		-->
	 	<setting name="lazyLoadingEnabled" value="true"/>
	 	<!-- 
		 	aggressiveLazyLoading设置成false才是启用延迟加载
		 -->
	 	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

一对多或多对多延迟加载

需要两条sql语句配合使用

<!-- 
		Collection:是person内部的集合,
		select:延迟加载的sql语句
		column:延迟加载sql语句的查询条件的列名 
-->
<resultMap type="cn.itcast.model.Person" id="personLazyRM" extends="personRM">
	<collection property="ordersList" column="person_id" select="mybatis.sqlMap.OrdersMapper.selectOrderByPersonId">
	</collection>
</resultMap>
<!-- 查询语句-->
<select id="selectForLazy" parameterType="int" resultMap="personLazyRM">
	select * from person p where p.person_id = #{personId}
</select>
<!-- 延迟加载的查询语句-->
<select id="selectOrderByPersonId" parameterType="int" resultMap="BaseResultMap">
	select * from orders o where  o.person_id = #{personId}
</select>

多对一或一对一的延迟加载

同样需要两条sql语句配合使用

<!-- ResultMap -->
<resultMap type="cn.itcast.model.Orders" id="lazyRM" extends="BaseResultMap">
 	<association property="person" column="order_id" select="cn.itcast.model.Person.selectPersonByOrderId">
   	</association>
</resultMap>

<!-- 查询语句 -->
<select id="selectByPrimaryKeyForLazy" resultMap="lazyRM" parameterType="java.lang.Integer" >
   select  * from orders where order_id = #{orderId}
 </select>
<!-- 延迟加载的查询语句 -->
<select id="selectPersonByOrderId" parameterType="int" resultMap="personRM">
	select p.* from person p, orders o where p.person_id = o.person_id and o.order_id = #{orderId}
</select>

一级缓存

可以参考hibernate的一级缓存

https://blog.csdn.net/qq_35262405/article/details/97970327

二级缓存

一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要
每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的。

开启Mybatis默认的缓存

  1. 在核心配置文件中加入<setting name=“cacheEnabled” value=“true”/>
    在这里插入图片描述
  2. 要在你的Mapper映射文件中添加一行: <cache />
    在这里插入图片描述
  3. 在select语句中useCache=false可以禁用当前的语句的二级缓存,即每次查询夸session的查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
    在这里插入图片描述
  4. 映射文件中所有的insert、update和delete语句将刷新缓存,三个语句中有flushCache=“true” 属性,默认情况下为true,即同个sessionFactory中当有sql语句更新时缓存自动被刷新以保证数据的实时性,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读, 缓存将使用LRU(Least Recently Used)最近最少使用策略算法来回
    在这里插入图片描述

二级缓存框架

采用mybatis的二级缓存框架ehcache

引入缓存的依赖包
在这里插入图片描述
引入缓存配置文件ehcache.xml
在这里插入图片描述
在这里插入图片描述
defaultCache配置说明:

  • maxElementsInMemory:内存中最大缓存对象数。当超过最大对象数的时候,ehcache会按指定的策略去清理内存
  • eternal:缓存对象是否永久有效。一但设置了,timeout将不起作用.
  • timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
  • timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间,仅当element是永久有效时使用,默认是0,也就是element存活时间无穷大
  • overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
  • diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB,每个Cache都应该有自己的一个缓冲区
  • maxElementsOnDisk:磁盘中最大缓存对象数。若是0表示无穷大
  • diskPersistent:是否在重启服务的时候清楚磁盘上的缓存数据。true不清除
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔
  • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用),你可以设置为FIFO(先进先出)或是LFU(较少使用)

修改mapper文件中缓存类型
在这里插入图片描述

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

Mybatis基于注解的开发的示例

初始化环境

使用注解的开发需要提供一个接口,即dao的接口,不需要实现类,初始化环境时要把接口注册。

@Before
public void setUp() throws Exception {
	String sqlMapConfig = "sqlMapConfig.xml";
	//读取mybatis的核心配置文件
	InputStream in = Resources.getResourceAsStream(sqlMapConfig);
	//实例化会话工厂
	sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
	sqlSessionFactory.getConfiguration().addMapper(PersonDao.class);
}

查询所有员工

接口方法
	@Select("select * from person1")
	//@Options(useCache =true, flushCache =false, timeout =10000)
	@Results(value = {
		@Result(id =true, property ="personId", column ="person_id"),
		@Result(property ="personName", column ="person_name"),
		@Result(property ="birthday", column ="birthday"),
		@Result(property ="address", column ="address"),
		@Result(property ="gender", column ="gender")
	})
	public List<Person> queryPersonAll();
调用方法
@Test
public void queryPersonAllTest() {
	//打开会话
	SqlSession session = sqlSessionFactory.openSession();
	try {
		PersonDao personDao = session.getMapper(PersonDao.class);
		List<Person> pList = personDao.queryPersonAll();
		for(Person person : pList){
			System.out.println(person);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		session.close();
	}
}

根据id查询员工

接口方法
@Select("select * from person1 t where t.person_id = #{personId}")
@Results(value = {
		@Result(id =true, property ="personId", column ="person_id"),
		@Result(property ="personName", column ="person_name"),
		@Result(property ="birthday", column ="birthday"),
		@Result(property ="address", column ="address"),
		@Result(property ="gender", column ="gender")
	})
public Person getPersonById(Integer personId);
调用方法
@Test
public void getPersonByIdTest(){
	SqlSession session = sqlSessionFactory.openSession();
	try {
		PersonDao personDao = session.getMapper(PersonDao.class);
		Person person = personDao.getPersonById(1);
		System.out.println(person);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		session.close();
	}
}

根据不同条件查询

接口方法
@Select("select * from person1 t where t.person_name like '%${personName}%' and t.gender = #{gender}")
@Results(value = {
		@Result(id =true, property ="personId", column ="person_id"),
		@Result(property ="personName", column ="person_name"),
		@Result(property ="birthday", column ="birthday"),
		@Result(property ="address", column ="address"),
		@Result(property ="gender", column ="gender")})
public List<Person> getPersonByParam(Map<String, Object> map);
调用方法
@Test
public void getPersonByParamTest(){
	SqlSession session = sqlSessionFactory.openSession();
	try {
		PersonDao personDao = session.getMapper(PersonDao.class);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("personName", "赵六");
		map.put("gender", "0");
		List<Person> pList = personDao.getPersonByParam(map);
		for(Person person : pList){
			System.out.println(person);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		session.close();
	}
}

联合查询

注意:需要结合配置文件方式的resultMap

调用方法
@Select("select * from person1 p, orders o where p.PERSON_ID = o.PERSON_ID and p.PERSON_ID = #{personId}")
@ResultMap(value="cn.itcast.model.Person.personWithOrderRM")
public Person getPersonOne2Many(Integer personId);
配置文件中的resultMap
<resultMap type="person" id="personWithOrderRM" extends="personRM">
		<collection property="orderList" ofType="cn.itcast.model.Orders">
			<id column="ORDER_ID" jdbcType="INTEGER" property="orderId" />
		    <result column="PERSON_ID" jdbcType="INTEGER" property="personId" />
		    <result column="ORDER_NO" jdbcType="VARCHAR" property="orderNo" />
		    <result column="TOTAL_SUM" jdbcType="REAL" property="totalSum" />
		    <result column="ORDER_ADDR" jdbcType="VARCHAR" property="orderAddr" />
		</collection>
</resultMap>
调用方法
@Test
public void getPersonOne2ManyTest(){
	SqlSession session = sqlSessionFactory.openSession();
	try {
		PersonDao personDao = session.getMapper(PersonDao.class);
		Person person = personDao.getPersonOne2Many(1);
		System.out.println(person);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		session.close();
	}
}

修改

接口方法
@Update(value="update person1 t set"
		+" t.person_name = #{personName} , "
		+" t.birthday = #{birthday}, "
		+" t.address=#{address},"
		+" t.gender = #{gender}"
		+" where  t.person_id = #{personId}")
public void update(Person person);
调用方法
@Test
public void updateTest() throws Exception{
	//打开会话
	SqlSession session = sqlSessionFactory.openSession();
	try{
		PersonDao personDao = session.getMapper(PersonDao.class);
		Person person = new Person();
		person.setPersonId(1);
		person.setPersonName("李武");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date = format.parse("1992-12-10");
		person.setBirthday(date);
		personDao.update(person);
		session.commit();
		
	}catch(Exception ex){
		session.rollback();
		ex.printStackTrace();
	}finally{
		session.close();
	}
}

插入

接口方法
@Insert("insert into person1 (person_id, person_name, birthday, address, gender)values(#{personId},#{personName},#{birthday},#{address},#{gender})")
@SelectKey(keyProperty="personId",  before = false, resultType = Integer.class, statement = { "select last_insert_id()" })
public void save(Person person);
调用方法
@Test
public void insertTest() throws Exception{
	//打开会话
	SqlSession session = sqlSessionFactory.openSession();
	try{
		PersonDao personDao = session.getMapper(PersonDao.class);
		Person person = new Person();
		person.setPersonName("王五");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date = format.parse("1990-12-10");
		person.setAddress("beijing");
		person.setBirthday(date);
		person.setGender("0");
		personDao.save(person);
		session.commit();
		
	}catch(Exception ex){
		session.rollback();
		ex.printStackTrace();
	}finally{
		session.close();
	}
}

动态条件组合查询

接口方法
@SelectProvider(type=SQLHelp.class,method="getSql")
public List<Person> queryPersonByCondition(Map<String, Object> map);
获得sql的帮助类
public class SQLHelp {
	
	public String getSql(Map<String, Object> parameters) {
		String personName = (String) parameters.get("personName");
		Date birthday = (Date) parameters.get("birthday");
		String address = (String) parameters.get("address");
		String gender = (String) parameters.get("gender");
		
		BEGIN();
		SELECT("*");
		FROM("person1");
		if(personName != null){
			WHERE("person_name = #{personName}");
		}
		if(birthday != null){
			WHERE("birthday < #{birthday}");
		}
		if(address != null){
			WHERE("address = #{address}");
		}
		if(gender != null){
			WHERE("gender = #{gender}");
		}
		
		return SQL();
	}
}
调用方法
@Test
public void queryPersonByConditionTest() throws Exception{
	//打开会话
	SqlSession session = sqlSessionFactory.openSession();
	try{
		PersonDao personDao = session.getMapper(PersonDao.class);
		Map<String, Object> map = new HashMap<String, Object>();
		//map.put("personName", "五");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date = format.parse("1990-04-01");
		map.put("birthday", date);
		//map.put("address", "beijing2");
		map.put("gender", "0");
		List<Person> personList = personDao.queryPersonByCondition(map);
		for(Person person : personList){
			System.out.println(person);
		}
		session.commit();
		
	}catch(Exception ex){
		session.rollback();
		ex.printStackTrace();
	}finally{
		session.close();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_35262405/article/details/98676717