文章目录
1. MyBatis 的连接池
1.1 MyBatis 的连接池的配置
通过配置文件 SqlMapConfig.xml 中的 dataSource 标签来实现 MyBatis 的连接池的配置
<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>
1.2 MyBatis 连接池的分类
dataSource 标签中的 type 属性表示采用何种连接池方式,type 属性有三种取值:
- POOLED:采用传统的 javax.sql.DataSource 规范中的连接池,mybatis 中有针对规范的实现
- UNPOOLED:采用传统的获取连接的方式,虽然也实现 Javax.sql.DataSource 接口,但是并没有使用池的思想。
- JNDI:采用服务器提供的 JNDI 技术实现,来获取 DataSource 对象,不同的服务器所能拿到 DataSource 是不一样。
注意:在这三种连接池方式中,我们一般采用的是 POOLED 方式
2. MyBatis 的事务控制
2.1 MyBatis 的事务提交方式
观察 Connection 的整个变化过程可以得知,MyBatis 会把 setAutoCommit() 设置为 false,所以我们需要通过 sqlSession.commit() 方法来实现手动提交,才能实现事务控制
@After
public void destory() throws IOException {
sqlSession.commit();
// 7.释放资源
sqlSession.close();
in.close();
}
2.2 MyBatis 自动提交事务的设置
如果我们想把事务设置为自动提交,可以在创建 SqlSession 对象时,设置自动提交事务为 true
// 创建 SqlSession 对象
session = factory.openSession(true);
注意:在实际开发中,设置为自动提交方式为 false 再根据情况决定是否进行提交,这种方式更常用
3. Mybatis 的动态 SQL 语句
3.1 if 标签
-
需求
我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
-
持久层 Dao 接口
/** * 根据用户信息,查询用户列表 * @param user * @return */ List<User> findByUser(User user);
-
持久层 Dao 映射配置
<!--根据用户信息,查询用户列表--> <select id="findByUser" parameterType="user" resultType="user"> select * from user where 1 = 1 <if test="username != null"> and username like #{username} </if> <if test="birthday != null"> and birthday like #{birthday} </if> <if test="sex != null"> and sex like #{sex} </if> <if test="address != null"> and address like #{address} </if> </select>
-
测试类
@Test public void testFindByUser(){ User user = new User(); user.setUsername("%王%"); user.setSex("%男%"); List<User> users = mapper.findByUser(user); for (User user1 : users) { System.out.println(user1); } }
3.2 where 标签
-
需求
为了简化上面 where 1=1 的条件拼装,我们可以采用 where 标签来简化开发。
-
持久层 Dao 映射配置
<!--根据用户信息,查询用户列表--> <select id="findByUser" parameterType="user" resultType="user"> select * from user <where> <if test="username != null"> and username like #{username} </if> <if test="birthday != null"> and birthday like #{birthday} </if> <if test="sex != null"> and sex like #{sex} </if> <if test="address != null"> and address like #{address} </if> </where> </select>
3.3 foreach 标签
-
需求
传入多个 id 查询用户信息,需要用以下的 sql 语句实现
select * from user where id in (42,46,52)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。
-
在 QueryVo 中加入一个 List 集合用于封装参数
public class QueryVo implements Serializable { private User user; private List<Integer> ids; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public List<Integer> getIds() { return ids; } public void setIds(List<Integer> ids) { this.ids = ids; } }
-
持久层 Dao 接口
/** * 根据 id 集合查询用户 * @param queryVo * @return */ List<User> findByQueryVo(QueryVo queryVo);
-
持久层 Dao 映射配置
<!--根据 id 集合查询用户--> <select id="findByQueryVo" parameterType="queryVo" resultType="user"> select * from user <where> <if test="ids != null and ids.size() > 0"> <foreach collection="ids" open="id in ( " close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>
foreach 标签用于遍历集合,它的属性:
- collection:代表要遍历的集合元素
- open:代表语句的开始部分
- close:代表结束部分
- item:代表遍历集合的每个元素,生成的变量名
- sperator:代表分隔符
-
测试类
@Test public void testFindByQueryVo(){ QueryVo queryVo = new QueryVo(); ArrayList<Integer> ids = new ArrayList<Integer>(); ids.add(42); ids.add(46); ids.add(52); queryVo.setIds(ids); List<User> users = mapper.findByQueryVo(queryVo); for (User user : users) { System.out.println(user); } }
3.4 简化 SQL 片段
-
需求
可将重复的 sql 提取出来,使用时用 include 引用即可,实现 sql 重用的目的。
-
定义代码片段
<!--抽取重复语句代码片段--> <sql id="defaultSql"> select * from user </sql>
注意:抽取的代码片段如果还要用来拼接,最后不要加分号
-
引用代码片段
<!--配置查询所有用户--> <select id="findAll" resultType="user"> <include refid="defaultSql"></include> </select>
4. Mybatis 多表查询
4.1 表之间的几种关系
-
表之间的几种关系
- 一对一
- 一对多
- 多对一
- 多对多
-
举例
- 人和身份证号的关系就是一对一(一个人只能有一个身份证号,一个身份证号只能属于一个人)
- 用户和订单就是一对多(一个用户可以下多个订单)
- 订单和用户就是多对一(多个订单属于同一个用户)
- 老师和学生之间就是多对多(一个学生可以被多个老师教过,一个老师可以交多个学生)
-
注意
在多对一的关系中,因为拿出每一个订单,它都只能属于一个用户,所以 Mybatis 就把多对一看成了一对一
4.2 一对一,一对多关系实例
-
需求
实现用户和账户的关系,一个用户可以有多个账户,一个账户只能有一个用户
-
步骤
- 建立两张表,用户表和账户表
- 建立两个实体类,用户实体类和账户实体类
- 建立两个持久层 Dao 接口,用户 Dao 和账户 Dao
- 建立两个配置文件,用户配置文件和账户配置文件
- 建立 SqlMapConfig.xml 配置文件
- 建立测试类
- 增加功能:查询所有账户,同时包含用户名和地址信息(一对一)
- 增加功能:查询所有用户,同时包含用户下的所有账户信息(一对多)
-
实现
-
建立两张表
用户表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` datetime DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性别', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8;
账户表
DROP TABLE IF EXISTS `account`; CREATE TABLE `account` ( `ID` int(11) NOT NULL COMMENT '编号', `UID` int(11) DEFAULT NULL COMMENT '用户编号', `MONEY` double DEFAULT NULL COMMENT '金额', PRIMARY KEY (`ID`), KEY `FK_Reference_8` (`UID`), CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
建立两个实体类
用户实体类
public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
账户实体类
public class Account { private Integer id; private Integer uid; private Double money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + '}'; } }
-
建立两个持久层 Dao 接口
用户 Dao
/** * 用户持久层接口 */ public interface UserDao { /** * 查询所有用户 * @return */ public List<User> findAll(); /** * 查询单个用户 * @param id */ User findById(Integer id); }
账户 Dao
/** * 账户持久层接口 */ public interface AccountDao { /** * 查询所有账户 * @return */ public List<Account> findAll(); }
-
建立两个配置文件
用户配置文件
<?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"> <mapper namespace="com.zt.dao.UserDao"> <!--配置查询所有用户--> <select id="findAll" resultType="user"> select * from user </select> <!--查询单个用户--> <select id="findById" parameterType="java.lang.Integer" resultType="com.zt.domain.User"> select * from user where id=#{id}; </select> </mapper>
账户配置文件
<?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"> <mapper namespace="com.zt.dao.AccountDao"> <!--配置查询所有账户--> <select id="findAll" resultType="account"> select * from account </select> </mapper>
-
建立 SqlMapConfig.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 resource="jdbcConfig.properties"></properties> <typeAliases> <!--批量别名,用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写--> <package name="com.zt.domain"></package> </typeAliases> <!-- 配置 mybatis 的环境 --> <environments default="mysql"> <!-- 配置 mysql 的环境 --> <environment id="mysql"> <!-- 配置事务的类型 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置连接数据库的信息:用的是数据源(连接池) --> <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> <!-- 告知 mybatis 映射配置的位置 --> <mappers> <package name="com.zt.dao"></package> </mappers> </configuration>
-
建立测试类
MybatisTest
public class MybatisTest { private InputStream in; private SqlSession sqlSession; private UserDao mapper; @Before public void init() throws IOException { // 1.读取配置文件 in = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 3.使用构建者创建工厂对象 SqlSessionFactory SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in); // 4.使用 SqlSessionFactory 生产 SqlSession 对象 sqlSession = sqlSessionFactory.openSession(); // 5.使用 SqlSession 创建 dao 接口的代理对象 mapper = sqlSession.getMapper(UserDao.class); } @After public void destory() throws IOException { sqlSession.commit(); // 7.释放资源 sqlSession.close(); in.close(); } @Test public void testFindAll() { List<User> all = mapper.findAll(); for (User user : all) { System.out.println(user); } } @Test public void testFindById(){ User user = mapper.findById(52); System.out.println(user); } }
MybatisTest2
public class MybatisTest2 { private InputStream in; private SqlSession sqlSession; private AccountDao mapper; @Before public void init() throws IOException { // 1.读取配置文件 in = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 3.使用构建者创建工厂对象 SqlSessionFactory SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in); // 4.使用 SqlSessionFactory 生产 SqlSession 对象 sqlSession = sqlSessionFactory.openSession(); // 5.使用 SqlSession 创建 dao 接口的代理对象 mapper = sqlSession.getMapper(AccountDao.class); } @After public void destory() throws IOException { sqlSession.commit(); // 7.释放资源 sqlSession.close(); in.close(); } @Test public void findAll() { List<Account> accounts = mapper.findAll(); for (Account account : accounts) { System.out.println(account); } } }
-
增加功能:查询所有账户,同时包含用户名和地址信息
-
修改账户实体类
public class Account { private Integer id; private Integer uid; private Double money; // 从表实体应该包含一个主表实体的对象引用 private User user; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + ", user=" + user + '}'; } }
-
修改账户 Dao
/** * 查询所有账户,并带有用户名和地址信息 * @return */ public List<Account> findAllWithUser();
-
修改账户配置文件
<mapper namespace="com.zt.dao.AccountDao"> <!-- 定义封装 account和 user 的 resultMap --> <resultMap id="accountUserMap" type="account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!-- 一对一的关系映射:配置封装user的内容--> <association property="user" javaType="user"> <id property="id" column="id"></id> <result column="username" property="username"></result> <result column="address" property="address"></result> <result column="sex" property="sex"></result> <result column="birthday" property="birthday"></result> </association> </resultMap> <!--配置查询所有账户--> <select id="findAll" resultType="account"> select * from account </select> <!--配置查询所有账户,并带有用户名和地址信息--> <select id="findAllWithUser" resultMap="accountUserMap"> select a.id as aid, a.uid, a.money, u.* from account a, user u where u.id = a.uid; </select> </mapper>
-
修改测试类
@Test public void testFindAllWithUser() { List<Account> allWithUser = mapper.findAllWithUser(); for (Account account : allWithUser) { System.out.println(account); } }
-
-
增加功能:查询所有用户,同时包含用户下的所有账户信息(一对多)
-
修改用户实体类
public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; // 一对多关系映射:主表实体应该包含从表实体的集合引用 private List<Account> accounts; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + ", accounts=" + accounts + '}'; } }
-
修改用户 Dao
/** * 查询所有用户,同时包含用户下的所有账户信息 * @return */ public List<User> findAllWithAccount();
-
修改用户配置文件
<?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"> <mapper namespace="com.zt.dao.UserDao"> <!-- 定义封装 user和 account 的 resultMap --> <resultMap id="UserAccountMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> <!-- 配置 user 对象中 accounts 集合的映射 --> <collection property="accounts" ofType="account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> </collection> </resultMap> <!--配置查询所有用户--> <select id="findAll" resultType="user"> select * from user </select> <!--查询单个用户--> <select id="findById" parameterType="java.lang.Integer" resultType="com.zt.domain.User"> select * from user where id=#{id}; </select> <!--配置查询所有用户,同时包含用户下的所有账户信息--> <select id="findAllWithAccount" resultMap="UserAccountMap"> select a.id as aid, a.uid, a.money, u.* from user u left join account a on u.id = a.uid </select> </mapper>
-
修改测试类
@Test public void testFindAllWithAccount() { List<User> allWithAccount = mapper.findAllWithAccount(); for (User user : allWithAccount) { System.out.println(user); } }
-
-
4.3 多对多关系实例
-
需求
实现用户和角色的关系,一个用户可以有多个角色,一个角色可以赋予多个用户
-
步骤
- 建立三张表,用户表,角色表,中间表(中间表中有两个外键,分别是用户表和角色表的主键)
- 建立两个实体类,用户实体类和角色实体类(各自包含对方一个集合引用)
- 建立两个持久层 Dao 接口,用户 Dao 和角色 Dao
- 建立两个配置文件,用户配置文件和角色配置文件
- 建立 SqlMapConfig.xml 配置文件
- 建立测试类
- 增加功能:查询用户,可以同时得到用户所包含的角色信息(多对多)
- 增加功能:查询角色,可以同时得到角色的所赋予的用户信息(多对多)
-
实现
-
建立三张表
用户表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '用户名称', `birthday` datetime DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性别', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8;
角色表
DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `ID` int(11) NOT NULL COMMENT '编号', `ROLE_NAME` varchar(30) DEFAULT NULL COMMENT '角色名称', `ROLE_DESC` varchar(60) DEFAULT NULL COMMENT '角色描述', PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
中间表
DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `UID` int(11) NOT NULL COMMENT '用户编号', `RID` int(11) NOT NULL COMMENT '角色编号', PRIMARY KEY (`UID`,`RID`), KEY `FK_Reference_10` (`RID`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
建立两个实体类
用户实体类
public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
角色实体类
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } @Override public String toString() { return "Role{" + "roleId=" + roleId + ", roleName='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + '}'; } }
-
建立两个持久层 Dao 接口
用户 Dao
/** * 用户持久层接口 */ public interface UserDao { /** * 查询所有用户 * @return */ List<User> findAll(); /** * 查询单个用户 * @param id */ User findById(Integer id); }
角色 Dao
/** * 角色持久层接口 */ public interface RoleDao { /** * 查询所有角色 * @return */ List<Role> findAll(); }
-
建立两个配置文件
用户配置文件
<?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"> <mapper namespace="com.zt.dao.UserDao"> <!--配置查询所有用户--> <select id="findAll" resultType="user"> select * from user </select> <!--查询单个用户--> <select id="findById" parameterType="java.lang.Integer" resultType="com.zt.domain.User"> select * from user where id=#{id}; </select> </mapper>
角色配置文件
<?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"> <mapper namespace="com.zt.dao.RoleDao"> <resultMap id="roleMap" type="role"> <id property="roleId" column="id"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> </resultMap> <!--配置查询所有角色--> <select id="findAll" resultMap="roleMap"> select * from role </select> </mapper>
-
建立 SqlMapConfig.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 resource="jdbcConfig.properties"></properties> <typeAliases> <!--批量别名,用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写--> <package name="com.zt.domain"></package> </typeAliases> <!-- 配置 mybatis 的环境 --> <environments default="mysql"> <!-- 配置 mysql 的环境 --> <environment id="mysql"> <!-- 配置事务的类型 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置连接数据库的信息:用的是数据源(连接池) --> <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> <!-- 告知 mybatis 映射配置的位置 --> <mappers> <package name="com.zt.dao"></package> </mappers> </configuration>
-
建立测试类
public class MybatisTest2 { private InputStream in; private SqlSession sqlSession; private RoleDao mapper; @Before public void init() throws IOException { // 1.读取配置文件 in = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 3.使用构建者创建工厂对象 SqlSessionFactory SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in); // 4.使用 SqlSessionFactory 生产 SqlSession 对象 sqlSession = sqlSessionFactory.openSession(); // 5.使用 SqlSession 创建 dao 接口的代理对象 mapper = sqlSession.getMapper(RoleDao.class); } @After public void destory() throws IOException { sqlSession.commit(); // 7.释放资源 sqlSession.close(); in.close(); } @Test public void testFindAll() { List<Role> all = mapper.findAll(); for (Role role : all) { System.out.println(role); } } }
-
增加功能:查询所有用户,可以同时得到用户所包含的角色信息
-
修改用户实体类
public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; // 多对多的关系映射:一个用户可以有多个角色 private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + ", roles=" + roles + '}'; } }
-
修改用户 Dao
/** * 查询所有用户,可以同时得到用户所包含的角色信息 * @return */ List<User> findAllWithRole();
-
修改用户配置文件
<?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"> <mapper namespace="com.zt.dao.UserDao"> <resultMap id="userMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> <collection property="roles" ofType="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> </collection> </resultMap> <!--配置查询所有用户--> <select id="findAll" resultType="user"> select * from user </select> <!--查询单个用户--> <select id="findById" parameterType="java.lang.Integer" resultType="com.zt.domain.User"> select * from user where id=#{id}; </select> <!--配置查询所有用户,可以同时得到用户所包含的角色信息--> <select id="findAllWithRole" resultMap="userMap"> select u.*, r.id as rid, r.role_name, r.role_desc from user u left join user_role ur on u.id = ur.uid left join role r on r.id = ur.rid; </select> </mapper>
-
修改测试类
@Test public void testFindAllWithRole() { List<User> allWithRole = mapper.findAllWithRole(); for (User user : allWithRole) { System.out.println(user); } }
-
-
增加功能:查询所有角色,可以同时得到角色的所赋予的用户信息
-
修改角色实体类
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; // 多对多的关系映射:一个角色可以赋予多个用户 private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } @Override public String toString() { return "Role{" + "roleId=" + roleId + ", roleName='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + '}'; } }
-
修改角色 Dao
/** * 查询所有角色,可以同时得到角色的所赋予的用户信息 * @return */ List<Role> findAllWithUser();
-
修改角色配置文件
<?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"> <mapper namespace="com.zt.dao.RoleDao"> <resultMap id="roleMap" type="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> <collection property="users" ofType="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="birthday" column="birthday"></result> <result property="sex" column="sex"></result> <result property="address" column="address"></result> </collection> </resultMap> <!--配置查询所有角色--> <select id="findAll" resultMap="roleMap"> select * from role </select> <!--配置查询所有角色,可以同时得到角色的所赋予的用户信息--> <select id="findAllWithUser" resultMap="roleMap"> select r.id as rid, r.role_name, r.role_desc, u.* from role r left join user_role ur on r.id = ur.rid left join user u on u.id = ur.uid; </select> </mapper>
-
修改测试类
@Test public void testFindAllWithUser() { List<Role> allWithUser = mapper.findAllWithUser(); for (Role role : allWithUser) { System.out.println(role); } }
-
-