创建数据库表
/*
SQLyog Ultimate v12.5.0 (64 bit)
MySQL - 5.7.23-log : Database - test_mybatis
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`test_mybatis` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
USE `test_mybatis`;
/*Table structure for table `account` */
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;
/*Data for the table `account` */
insert into `account`(`ID`,`UID`,`MONEY`) values
(1,46,1000),
(2,45,1000),
(3,46,2000);
/*Table structure for table `role` */
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;
/*Data for the table `role` */
insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values
(1,'院长','管理整个学院'),
(2,'总裁','管理整个公司'),
(3,'校长','管理整个学校');
/*Table structure for table `user` */
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=49 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values
(41,'老王','2018-02-27 17:47:08','男','北京'),
(45,'阿宁','2018-03-04 12:04:06','男','南京'),
(46,'老李','2018-03-07 17:37:26','男','上海'),
(48,'小马宝莉','2018-03-08 11:44:00','女','广东');
/*Table structure for table `user_role` */
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;
/*Data for the table `user_role` */
insert into `user_role`(`UID`,`RID`) values
(41,1),
(45,2),
(46,2),
(45,3),
(48,3);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
多对多的关系是user-------user_role--------role(关系表)
1、搭建一个maven项目
2、引入mybatis需要的依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
3、配置log4j和mysql
在resources目录下新建mybatis的核心配置文件log4j.properties和mysql.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:\\Mybatis\\mybatis
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test_mybatis?useUnicode=true&characterEncoding=UTF-8
jdbc.username = root
jdbc.password = 123456
4、使用 Mybatis 注解实现基本 CRUD
4.1创建User实体类
package com.ning.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author aning
*/
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
}
4.2搭建注解开发环境
在resources目录下新建mybatis的核心配置文件mybatis-config.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>
<!-- 配置连接数据库的信息
resource 属性:
用于指定 properties 配置文件的位置,要求配置文件必须在类路径下 resource="jdbcConfig.properties" -->
<!--配置properties-->
<properties resource="properties/mysql.properties"></properties>
<!--使用typeAliases配置别名,它只能配置entity中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指的是实体类全限定类名,alias属性指定别名,当指定了别名就不在区分大小写-->
<!--<typeAlias alias="Employee" type="com.ning.entity.Employee"/>-->
<!--用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不在区分大小写-->
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="com.ning.entity"/>
<!-- <package name="其他存放实体类的包路径"/> -->
</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>
<!-- 指定带有注解的dao接口所在位置 -->
<mappers>
<!--package标签是用于指定mapper接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了-->
<package name="com.ning.mapper"></package>
</mappers>
</configuration>
4.3编写User的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @author aning
*
* 用户的持久层接口
*/
public interface IUserMapper {
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
List<User> findAll();
/**
* 保存用户
* @param user
*/
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void saveUser(User user);
/**
* 更新用户
* @param user
*/
@Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
void updateUser(User user);
/**
* 删除用户
* @param userId
*/
@Delete("delete from user where id=#{id} ")
void deleteUser(Integer userId);
/**
* 根据id查询用户
* @param userId
* @return
*/
@Select("select * from user where id=#{id} ")
User findById(Integer userId);
/**
* 根据用户名称模糊查询
* @param username
* @return
*/
@Select("select * from user where username like '%${value}%' ")
List<User> findUserByName(String username);
/**
* 查询总用户数量
* @return
*/
@Select("select count(*) from user ")
int findTotalUser();
}
4.4编写测试方法
package test;
import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserMapper iUserMapper;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
iUserMapper = sqlSession.getMapper(IUserMapper.class);
}
//5.执行Dao的方法
/**
* 测试基于注解的删除添加操作
* @param
*/
@Test
public void testSave(){
User user = new User();
user.setUsername("mybatis annotation");
user.setAddress("北京市昌平区");
iUserMapper.saveUser(user);
}
/**
* 测试基于注解的更新操作
* @param
*/
@Test
public void testUpdate(){
User user = new User();
user.setId(57);
user.setUsername("mybatis annotation update");
user.setAddress("北京市海淀区");
user.setSex("男");
user.setBirthday(new Date());
iUserMapper.updateUser(user);
}
/**
* 测试基于注解的删除操作
* @param
*/
@Test
public void testDelete(){
iUserMapper.deleteUser(1);
}
/**
* 测试基于注解的根据id查找操作
* @param
*/
@Test
public void testFindOne(){
User user = iUserMapper.findById(57);
System.out.println(user);
}
/**
* 测试基于注解的根据用户名查找操作
* @param
*/
@Test
public void testFindByName(){
List<User> users = iUserMapper.findUserByName("阿宁");
for(User user : users){
System.out.println(user);
}
}
/**
* 测试基于注解的查询数据总数操作
* @param
*/
@Test
public void testFindTotal(){
int total = iUserMapper.findTotalUser();
System.out.println(total);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
}
5.使用注解实现复杂关系映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置resultMap来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。
5.1复杂关系映射的注解说明
@Results 注解 代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})@Results(@Result())
@Resut 注解 代替了 <id>标签和<result>标签
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。
使用格式: @Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType (一般为 ArrayList)但是注解中可以不定义;
使用格式:@Result(property="",column="",many=@Many(select=""))
5.2使用注解实现一对一复杂关系映射及延迟加载
需求: 加载账户信息时并且加载该账户的用户信息,根据情况可实现延迟加载。(注解方式实现)
5.2.1 添加 User 实体类及 Account 实体类
package com.ning.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author aning
*/
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
}
package com.ning.entity;
import java.io.Serializable;
/**
* @author aning
*/
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//多对一关系映射:从表方应该包含一个主表方的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.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;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
}
5.2.2 添加账户的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.Account;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* @author aning
*
* 账户的持久层接口
*/
public interface IAccountMapper {
/**
* 查询所有账户,并且获取每个账户所属的用户信息
* @return
*/
@Select("select * from account")
@Results(id="accountMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column = "uid",one=@One(select="com.ning.mapper.IUserMapper.findById",
//一对一最好用立即加载 FetchType.EAGER
fetchType= FetchType.EAGER))
})
List<Account> findAll();
}
5.2.3 添加用户的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
/**
* 根据id查询用户
* @param userId
* @return
*/
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday")
})
@Select("select * from user where id=#{id} ")
User findById(Integer userId);
}
5.2.4 测试一对一关联及延迟加载
package test;
import com.ning.entity.Account;
import com.ning.mapper.IAccountMapper;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class AccountTest {
private InputStream in;
private SqlSession sqlSession;
private IAccountMapper iAccountMapper;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
iAccountMapper = sqlSession.getMapper(IAccountMapper.class);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
//5.执行Dao的方法
@Test
public void testFindAll(){
List<Account> accounts = iAccountMapper.findAll();
for(Account account : accounts){
System.out.println("----每个账户的信息-----");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
5.3 使用注解实现一对多复杂关系映射
需求: 查询用户信息时,也要查询他的账户列表。使用注解方式实现。
分析: 一个用户具有多个账户信息,所以形成了用户(User)与账户(Account)之间的一对多关系。
5.3.1 User 实体类加入 List< Account >*
package com.ning.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author aning
*/
public class User implements Serializable {
private Integer userId;
private String username;
private String address;
private String sex;
private Date birthday;
//一对多关系映射:主表实体应该包含从表实体的集合引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", accounts=" + accounts +
'}';
}
}
5.3.2 编写用户的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* @author aning
*
* 用户的持久层接口
*/
public interface IUserMapper {
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "com.ning.mapper.IAccountMapper.findAccountByUid",
//一对多最好用延迟加载FetchType.LAZY
fetchType = FetchType.LAZY))
})
List<User> findAll();
}
@Many:
相当于<collection>的配置
select 属性:代表将要执行的 sql 语句
fetchType 属性:代表加载方式,一般如果要延迟加载都设置为 LAZY 的值
5.3.3 编写账户的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.Account;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author aning
*
* 账户的持久层接口
*/
public interface IAccountMapper {
/**
* 根据用户id查询账户信息
* @param uId
* @return
*/
@Select("select * from account where uid = #{uId}")
List<Account> findAccountByUid(Integer uId);
}
5.3.4 添加测试方法
package test;
import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
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.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserMapper iUserMapper;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
iUserMapper = sqlSession.getMapper(IUserMapper.class);
}
@Test
public void testFindAll(){
List<User> users = iUserMapper.findAll();
for(User user : users){
System.out.println("---每个用户的信息----");
System.out.println(user);
System.out.println();
System.out.println(user.getAccounts());
}
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
}
6. 使用注解实现多对多复杂关系映射
*6.1. User 实体类加入 List< Role> *
package com.ning.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author aning
*/
public class User implements Serializable {
private Integer userId;
private String username;
private String address;
private String sex;
private Date birthday;
//多对多的关系映射:一个用户可以赋予多个角色
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", roles=" + roles +
'}';
}
}
*6.2 Role 实体类加入 List< User> *
package com.ning.entity;
import java.io.Serializable;
import java.util.List;
/**
* @author aning
*/
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 + '\'' +
", users=" + users +
'}';
}
}
6.3 编写用户的持久层接口并使用注解配置
package com.ning.mapper;
import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author aning
*
* 用户的持久层接口
*/
public interface IUserMapper {
/**
* 查询所有用户
* @return
*/
//根据uid查询用户
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
@Result(property = "roles",
column = "id",//User对象对应的数据库主键id字段,作为参数传递到findRoleAndUserByUId中进行查询的参数
many = @Many(select = "com.ning.mapper.IRoleMapper.findRoleAndUserByUId"))
})
List<User> findAll();
/**
*多对多查询(根据id查询用户及其所对应的角色)
* @param rId
* @return
*/
@Select("SELECT * FROM USER u LEFT OUTER JOIN user_role ur ON u.id = ur.uid WHERE ur.rid= #{rId}")
@ResultMap("userMap")
User findUserAndRoleByRId(Integer rId);
}
6.4 编写角色的持久层接口并使用注解配置*
package com.ning.mapper;
import com.ning.entity.Role;
import com.ning.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author aning
*
* 角色的持久层接口
*/
public interface IRoleMapper {
//通过rId查询角色信息
@Select("Select * from role")
@Results(id = "roleMap",value={
@Result(property = "roleId",column = "id"),
@Result(property = "roleName",column = "role_name"),
@Result(property = "roleDesc",column = "role_desc"),
@Result(property = "users",
column = "ID",//Role对象的数据库主键id字段,作为参数传递到findUserAndRoleByRId中进行查询的参数
many = @Many(select = "com.ning.mapper.IUserMapper.findUserAndRoleByRId"))
})
List<Role> findAll();
/**
*多对多查询(根据id查询用户及其所对应的角色)
* @param uId
* @return
*/
@Select("SELECT * FROM Role r LEFT OUTER JOIN user_role ur ON r.id= ur.rid WHERE ur.uid = #{uId}")
@ResultMap("roleMap")
User findRoleAndUserByUId(Integer uId);
}
6.5 编写用户测试类
package test;
import com.ning.entity.Role;
import com.ning.entity.User;
import com.ning.mapper.IUserMapper;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserMapper iUserMapper;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
iUserMapper = sqlSession.getMapper(IUserMapper.class);
}
@Test
public void showAllUserAndRole(){
List<User> users =iUserMapper.findAll();
for (User user:users){
System.out.print(user.getUserId()+"\t"+user.getUsername()+"\t");
for (Role role:user.getRoles()){
System.out.print(" "+role.getRoleId()+" "+role.getRoleName());
}
System.out.println();
}
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
}
6.6 编写角色测试类
package test;
import com.ning.entity.Role;
import com.ning.entity.User;
import com.ning.mapper.IRoleMapper;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class RoleTest {
private InputStream in;
private SqlSession sqlSession;
private IRoleMapper iRoleMapper;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
iRoleMapper = sqlSession.getMapper(IRoleMapper.class);
}
@Test
public void showAllRoleAndUser(){
List<Role> roles =iRoleMapper.findAll();
for (Role role : roles){
System.out.print(role.getRoleId()+"\t"+role.getRoleName());
for (User user:role.getUsers()){
System.out.print(" "+user.getUsername()+" "+user.getSex());
}
System.out.println();
}
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
}
7. mybatis 基于注解的二级缓存
在 SqlMapConfig 中开启二级缓存支持
<!-- 配置二级缓存 --> <settings>
<!-- 开启二级缓存的支持 --> <setting name="cacheEnabled" value="true"/> </settings>
在持久层接口中使用注解配置二级缓存
@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存 public interface IUserMapper {}