【Mybatis day02】Mybatis接口方式、mybatis关联映射、模型匹配、多表orm映射、sql、resultMap、if、choose、where、set、trim、foreach标签
Mybatis底层还是用的jdbc
用配置替换代码
把所有的可变化的,必须变化的数据,用配置来体现(xml,properties)清单文件
不变的,用java代码写,就是框架,框架需要清单指定框架如何工作
用注解替换配置
不变的还是用java代码写,,把变化的数据用注解来替代
Mybatis原生的api,已经讲过
Mybatis接口方式(底层还是用的mybatis原生api):
创建UserMapper接口
package com.tarena.dao; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.MapKey; import com.tarena.entity.User; import com.tarena.vo.Page; public interface UserMapper { public User findUserById(Integer id); public List<User> findUserByPage1(Page page); @MapKey("id") public Map<String,User> findUserByPage2(Page page); public int addUser(User user); public int deleteUser(Integer id); public int updateUser(User user); }
创建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="com.tarena.dao.UserMapper" 命名空间,不代表具体目录 其实就是一个用于区分和定位的逻辑名 此命名空间是全路径接口名 com.tarena.dao.UserMapper.findUserById com.tarena.dao.UserMapper.addUser com.tarena.dao.UserMapper.deleteUser com.tarena.dao.UserMapper.findUserByPage --> <mapper namespace="com.tarena.dao.UserMapper"> <sql id="select_user"> select id, username, userpassword, age from t_user </sql> <!-- 解决了结果集的列名字根属性的名字不匹配问题 id:唯一个一个id值 type:某一个具体类型 property:第一个字母大写加上get或set,去type对应类中匹配方法 column:结果集列名字 autoMapping="true" 不需要写那么多result节点,前提是属性名和结果集列名字 必须忽略大小写比较是真值 --> <resultMap type="User" id="userMap"> <id property="id" column="id"/> <result property="userName" column="username"/> <result property="userPassword" column="userPassword"/> <result property="age" column="age"/> </resultMap> <!-- id:接口中的方法名 parameterType="int" java.lang.Integer --> <select id="findUserById" parameterType="int" resultMap="userMap"> <include refid="select_user"></include> where id=#{id} </select> <!-- 分页查询 --> <select id="findUserByPage1" parameterType="Page" resultType="User"> <include refid="select_user"></include> where username like #{userNameKeyWord} and userpassword like #{userPasswordKeyWord} limit #{begin},#{pageSize} </select> <select id="findUserByPage2" parameterType="Page" resultType="User"> <include refid="select_user"></include> where username like #{userNameKeyWord} and userpassword like #{userPasswordKeyWord} limit #{begin},#{pageSize} </select> <!-- 插入 #{userName} userName 构建成getUserName,去User对象中取数据 keyProperty="id" keyColumn="id" useGeneratedKeys="true 上面的三个属性,把插入的数据后,自动生成id 存储parameterType="User" 所有指定的对象中 #{userName,javaType=string,jdbcType=VARCHAR}, jie解决java类型和数据库类型不能匹配问题 --> <insert id="addUser" parameterType="User" keyProperty="id" keyColumn="id" useGeneratedKeys="true"> insert into t_user ( username,userpassword,age ) values ( #{userName,javaType=string,jdbcType=VARCHAR}, #{userPassword}, #{age} ) </insert> <!-- 删除 int:不是java类型,是mybatis的类型 int 映射 java.lang.Integer --> <delete id="deleteUser" parameterType="int"> delete from t_user where id=#{id} </delete> <!-- 修改 hashmap不是java的类型,是mybatis的类型 hashmap 映射 java.util.HashMap #{uname} uname对应parameterType="hashmap"对象的key --> <update id="updateUser" parameterType="User"> update t_user set username=#{userName}, userpassword=#{userPassword}, age=#{age} where id=#{id} </update> </mapper>
创建测试类:
package com.tarena.test; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import com.tarena.dao.UserMapper; import com.tarena.entity.User; import com.tarena.vo.Page; public class TestMapperClass { private SqlSessionFactory sqlSessionFactory; @Before public void befor() { try { String resource = "conf/configuration.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Test public void testFindUserById() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); User user=mapper.findUserById(1); System.out.println(user); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testFindUserByPage1() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); Page page=new Page(); page.setCurrentPage(1);; page.setPageSize(3); page.setUserNameKeyWord("a"); page.setUserPasswordKeyWord("a"); List<User> users=mapper.findUserByPage1(page); for(User user :users) { System.out.println(user); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testFindUserByPage2() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); Page page=new Page(); page.setCurrentPage(1);; page.setPageSize(3); page.setUserNameKeyWord("a"); page.setUserPasswordKeyWord("a"); Map<String,User> users=mapper.findUserByPage2(page); for(User user :users.values()) { System.out.println(user); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testAddUser() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); User user=new User(); user.setUserName("大宝剑2"); user.setUserPassword("dbj2"); user.setAge(20); int rowAffect=mapper.addUser(user); System.out.println("rowAffect="+rowAffect); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testUpdateUser() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); User user=new User(); user.setId(21); user.setUserName("大宝剑3"); user.setUserPassword("dbj3"); user.setAge(20); int rowAffect=mapper.updateUser(user); System.out.println("rowAffect="+rowAffect); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testDeleteUser() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); User user=new User(); int rowAffect=mapper.deleteUser(21); System.out.println("rowAffect="+rowAffect); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } }
sql标签:sql语句复用
<sql id="select_user"> select id, username, userpassword, age from t_user </sql> <!-- id:接口中的方法名 parameterType="int" java.lang.Integer --> <select id="findUserById" parameterType="int" resultMap="userMap"> <include refid="select_user"></include> where id=#{id} </select>
resultMap标签:解决了结果集的列名字根属性的名字不匹配问题
<!-- 解决了结果集的列名字根属性的名字不匹配问题 id:唯一个一个id值 type:某一个具体类型 property:第一个字母大写加上get或set,去type对应类中匹配方法 column:结果集列名字 autoMapping="true" 不需要写那么多result节点,前提是属性名和结果集列名字 必须忽略大小写比较是真值 --> <resultMap type="User" id="userMap"> <id property="id" column="id"/> <result property="userName" column="username"/> <result property="userPassword" column="userPassword"/> <result property="age" column="age"/> </resultMap> <select id="findUserById" parameterType="int" resultMap="userMap"> <include refid="select_user"></include> where id=#{id} </select>
动态sql:sql语句拼装,需要根据某些条件来确定最后要执行的sql
if标签,没有else
<!-- 动态sql语句 resultMap="userMap" userMap,根本的类型User 因为属性名字跟列的名字不匹配才定义的resultMap,根本给User对象封装数据 test="userName != null" userName对应parameterType="User" 中的setUserName 如果userName的值为null userPassword为null select id,username,userpassword,age from t_user where age=22 如果userName的值为zhangsan userpassword为null select id,username,userpassword,age from t_user where age=22 and username like 'zhangsan' 其他情形类似... --> <select id="findUsersByIf" resultMap="userMap" parameterType="User"> <include refid="select_user"></include> where age=22 <if test="userName != null"> AND username like #{userName} </if> <if test="userPassword !=null"> and userpassword like #{userPassword} </if> </select> @Test public void testFindUsersByIf() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); User user=new User(); user.setUserName("%a%"); user.setUserPassword(null); List<User> users=mapper.findUsersByIf(user); for(User u : users) { System.out.println(u); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
choose (when, otherwise)标签
<!-- choose when otherwise --> <select id="findUsersByChoose" resultMap="userMap" parameterType="java.util.HashMap"> <include refid="select_user"></include> where age=22 <choose> <when test="uname != null"> and username like #{uname} </when> <when test="upwd != null"> and userpassword like #{upwd} </when> <otherwise> and username like '%a%' and userpassword like '%a%' </otherwise> </choose> </select> @Test public void testFindUsersByChoose() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); HashMap data=new HashMap(); //data.put("uname", "%a%"); //data.put("upwd", "%a%"); List<User> users=mapper.findUsersByChoose(data); for(User u : users) { System.out.println(u); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
where标签: 只能用查询语句中
<!-- where标签 <where>标签中的所有条件都不成立 sql语句中不会有where关键字 只要有一个条件成立sql语句添加where 关键字,并连接上成立的条件 如果在where关键字后的条件中有and开头,会自动去掉and关键字 --> <select id="findUsersByWhere" parameterType="hashmap" resultMap="userMap"> <include refid="select_user"></include> <where> <if test="age == 22"> age=22 </if> <if test="uname != null"> and username like #{uname} </if> <if test="upwd !=null"> and userpassword like #{upwd} </if> </where> </select> @Test public void testFindUsersByWhere() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); HashMap data=new HashMap(); //data.put("uname", "%a%"); //data.put("upwd", "%a%"); List<User> users=mapper.findUsersByWhere(data); for(User u : users) { System.out.println(u); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
set标签:只能用在更新语句中
<!-- set标签,应用在更新语句中 如果第一个if条件成立,后两个条件不成立,会在末尾多一个逗号, 如果是set标签下,会自动去掉逗号 --> <update id="updateUserBySet" parameterType="hashmap"> update t_user <set> <if test="uname != null"> username=#{uname}, </if> <if test="upwd != null"> userpassword=#{upwd}, </if> <if test="uage != null"> age=#{uage} </if> </set> where id=#{uid} </update> @Test public void testFindUsersBySet() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); HashMap data=new HashMap(); data.put("uname", "大宝剑123"); data.put("upwd", "dbj123"); data.put("uage", 22); data.put("uid", 19); int rowAffect=mapper.updateUserBySet(data); System.out.println("rowAffect="+rowAffect); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
trim (where, set),用trim可以替换where 和set
<!-- trim标签演示1 prefix="WHERE" prefix:前缀 prefixOverrides 前缀覆盖 如果前缀中带有and或or,就去掉(覆盖掉) --> <select id="findUsersByTrim1" parameterType="hashmap" resultMap="userMap"> <include refid="select_user"></include> <trim prefix="WHERE" prefixOverrides="AND|OR "> <if test="age == 22"> age=22 </if> <if test="uname != null"> and username like #{uname} </if> <if test="upwd !=null"> and userpassword like #{upwd} </if> </trim> </select> <!-- prefix="SET" 前缀 是set suffixOverrides="," 后缀覆盖 suffix:后缀 --> <update id="updateUserByTrim2" parameterType="hashmap"> update t_user <trim prefix="SET" suffixOverrides=","> <if test="uname != null"> username=#{uname}, </if> <if test="upwd != null"> userpassword=#{upwd}, </if> <if test="uage != null"> age=#{uage} </if> </trim> where id=#{uid} </update> @Test public void testFindUsersByTrim1() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); HashMap data=new HashMap(); data.put("uname", "%a%"); //data.put("upwd", "%a%"); List<User> users=mapper.findUsersByTrim1(data); for(User u : users) { System.out.println(u); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } } @Test public void testFindUsersByTrim2() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); HashMap data=new HashMap(); data.put("uname", "大宝剑1"); data.put("upwd", "dbj1"); data.put("uage", 22); data.put("uid", 19); int rowAffect=mapper.updateUserByTrim2(data); System.out.println("rowAffect="+rowAffect); sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
foreach: 一般用在 where id in()
<!-- foreach标签 item="id" 是一个局部变量 记录遍历的值 index="index" 是一个局部变量,遍历到第几个元素 要求collection="list(list集合)" array(数组) collection="list" 还可以有array,map,set 类型都是mybatis的类型 open="(" 以(开始 close=")" 以)结束 separator="," 小括号中的内容是#{id} 这些id用逗号间隔 --> <select id="findUsersByForeach" resultMap="userMap" parameterType="list"> <include refid="select_user"></include> where id in <foreach item="id" index="index" collection="list" open="(" separator="," close=")"> #{id} </foreach> </select> @Test public void testFindUsersByForeach() { //mybatis加载总清单文件 SqlSession sqlSession=null; try { //开一个连接,开启事务 sqlSession=sqlSessionFactory.openSession(); //mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口 //用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中 //调用的是selectOne或selectList或selectMap UserMapper mapper=sqlSession.getMapper(UserMapper.class); List<Integer> ids=new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(3); List<User> users=mapper.findUsersByForeach(ids); for(User user :users) { System.out.println(user); } sqlSession.commit();//提交事务 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); sqlSession.rollback();//回滚事务 }finally { sqlSession.close();//关闭会话 } }
mybatis关联映射:
ORM object relation mapping or映射
Object对象端 模型不匹配 Relation关系端
Java对象 模型不匹配 表中的数据对象
模型匹配:
jdbc:java端sql语句字符串从关系端查询数据,由程序员写代码
把resultset中的数据对应List集合中,
由程序员手动写代码做o和r之间映射
CommonDao和spring jdbc :也是手动o和r映射
mybatis 半自动映射 O:User,HashMap 对象 R:数据库中表
hibernate 全自动orm映射
多表的orm映射:
在关系端,表和表之间关系是主外键关系,只要有关系列
有主外键就一定有关系类
有关系类不一定有主外键
主外键是用来约束关系数据
在java端,是对象的包含关系
分为:
一对一关系,一个人只能有一个身份证
一对多关系,一个组可以由多个用户
多对一关系,多个用隶属一个组
多对多关系,多个学生可以被多个老师教
多个老师可以教多个学生
多对多对象关系Student类中有一个Teacher的集合
Teacher类中有一个Student的集合
多对多的数据表关系 (t_student ,t_teacher ,student_teacher)
student_teacher表 student_id,teacher_id,是联合主键
给外检表的外键添加外键约束
alter table t_user add constraint Fk_user_groupid
foreign key(group_id) references t_group(id);
在mybatis中只用两种关联映射
对一关系:
对多关系:
对一关联和对多关联:
<!-- mybatis的关联映射 -->
<!-- 对一关联 -->
<resultMap id="user_Map" type="User">
<id property="id" column="id"/>
<result property="userName" column="username"/>
<result property="userPassword" column="userPassword"/>
<result property="age" column="age"/>
<association property="group" javaType="Group">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="loc" column="loc"/>
</association>
</resultMap>
<!-- 对多关联 -->
<resultMap type="Group" id="group_Map" >
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="loc" column="loc"/>
<collection property="users"
ofType="User"
javaType="java.util.List" >
<id property="id" column="uid"/>
<result property="userName" column="username"/>
<result property="userPassword" column="userPassword"/>
<result property="age" column="age"/>
</collection>
</resultMap>
<!-- 查询用户信息 -->
<select id="findUsersBy_association"
resultMap="user_Map">
select
u.id,u.username,u.userpassword,u.age,
g.name,g.loc
from t_user u
left join t_group g
on u.group_id=g.id
</select>
<!-- 查询组的信息 -->
<select id="findGroupBy_collection"
resultMap="group_Map">
select g.id,g.name,g.loc,
u.id uid,u.username,u.userpassword,u.age
from t_group g
left join t_user u
on g.id=u.group_id
</select>
@Test
public void testFindUsersBy_association() {
//mybatis加载总清单文件
SqlSession sqlSession=null;
try {
//开一个连接,开启事务
sqlSession=sqlSessionFactory.openSession();
//mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口
//用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中
//调用的是selectOne或selectList或selectMap
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
List<User> users=mapper.findUsersBy_association();
for(User user :users) {
System.out.println(user);
}
sqlSession.commit();//提交事务
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
sqlSession.rollback();//回滚事务
}finally {
sqlSession.close();//关闭会话
}
}
@Test
public void testFindUsersBy_collection() {
//mybatis加载总清单文件
SqlSession sqlSession=null;
try {
//开一个连接,开启事务
sqlSession=sqlSessionFactory.openSession();
//mapper对象实际上是一个代理对象(jdk),UserMapper是一个接口
//用代理对象调用目标方法,在InvocationHandler接口实现方法invoke中
//调用的是selectOne或selectList或selectMap
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
List<Group> groups=mapper.findGroupBy_collection();
for(Group group : groups) {
System.out.println(group);
}
sqlSession.commit();//提交事务
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
sqlSession.rollback();//回滚事务
}finally {
sqlSession.close();//关闭会话
}
}

浙公网安备 33010602011771号