注释都在代码里,最好复制了再看!
1.创建表
CREATE TABLE sys_user(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户 ID',
user_name VARCHAR(50) COMMENT '用户名',
user_password VARCHAR(50) COMMENT '密码',
user_email VARCHAR(50) COMMENT '邮箱',
user_info TEXT COMMENT '简介',
head_img BLOB COMMENT '头像',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_user COMMENT '用户表';
CREATE TABLE sys_role(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '角色 ID',
role_name VARCHAR(50) COMMENT '角色名',
enabled INT COMMENT '有效标志',
create_by BIGINT COMMENT '创建人',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_role COMMENT '角色表';
CREATE TABLE sys_prvilege(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '权限 ID',
privilege_name VARCHAR(50) COMMENT '权限名称',
privilege_url VARCHAR (200) COMMENT '权限 URL',
PRIMARY KEY (id)
);
ALTER TABLE sys_prvilege COMMENT '权限表';
CREATE TABLE sys_user_role(
user_id BIGINT COMMENT '用户 ID ',
role_id BIGINT COMMENT '角色 ID'
);
ALTER TABLE sys_user_role COMMENT '用户角色关联表';
CREATE TABLE sys_role_prvilege(
role_id BIGINT COMMENT '角色ID',
privilege_id BIGINT COMMENT 'ID'
);
ALTER TABLE sys_role_prvilege COMMENT '角色权限关联表';
2.插入数据
CREATE TABLE sys_user(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户 ID',
user_name VARCHAR(50) COMMENT '用户名',
user_password VARCHAR(50) COMMENT '密码',
user_email VARCHAR(50) COMMENT '邮箱',
user_info TEXT COMMENT '简介',
head_img BLOB COMMENT '头像',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_user COMMENT '用户表';
CREATE TABLE sys_role(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '角色 ID',
role_name VARCHAR(50) COMMENT '角色名',
enabled INT COMMENT '有效标志',
create_by BIGINT COMMENT '创建人',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_role COMMENT '角色表';
CREATE TABLE sys_prvilege(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '权限 ID',
privilege_name VARCHAR(50) COMMENT '权限名称',
privilege_url VARCHAR (200) COMMENT '权限 URL',
PRIMARY KEY (id)
);
ALTER TABLE sys_prvilege COMMENT '权限表';
CREATE TABLE sys_user_role(
user_id BIGINT COMMENT '用户 ID ',
role_id BIGINT COMMENT '角色 ID'
);
ALTER TABLE sys_user_role COMMENT '用户角色关联表';
CREATE TABLE sys_role_prvilege(
role_id BIGINT COMMENT '角色ID',
privilege_id BIGINT COMMENT 'ID'
);
ALTER TABLE sys_role_prvilege COMMENT '角色权限关联表';
INSERT INTO sys_user VALUES ('2','admin','123456','admin@mybatis.tk','管理员',NULL,'2016-04-01 17:00:58');
INSERT INTO sys_user VALUES ('1001','test','123456','test@mybatis.tk','测试用户',NULL,'2016-04-01 17:00:58');
INSERT INTO sys_role VALUES ('1','管理员','1','1','2016-04-01 17:02:14');
INSERT INTO sys_role VALUES ('2','普通用户','1','1','2016-04-01 17:02:34');
INSERT INTO sys_user_role VALUES ('1','1');
INSERT INTO sys_user_role VALUES ('1','2');
INSERT INTO sys_user_role VALUES ('3','2');
INSERT INTO sys_prvilege VALUES ('1','用户管理','/users');
INSERT INTO sys_prvilege VALUES ('2','角色管理','/roles');
INSERT INTO sys_prvilege VALUES ('3','系统日志','/logs');
INSERT INTO sys_prvilege VALUES ('4','人员维护','/persons');
INSERT INTO sys_prvilege VALUES ('5','单位维护','/companies');
INSERT INTO sys_role_prvilege VALUES ('1','l');
INSERT INTO sys_role_prvilege VALUES ('1','1001');
INSERT INTO sys_role_prvilege VALUES ('1','2');
INSERT INTO sys_role_prvilege VALUES ('2','4');
INSERT INTO sys_role_prvilege VALUES ('2','5');
3.创建实体类
package tk.mybatis.simple.model;
import java.util.Date;
import lombok.Data;
@Data
public class SysUser {
private Long id;
private String userName;
private String userPassword;
private String userInfo;
private byte[] headImg;
private Date createTime;
private String userEmail;
}
@Date可以省略get、set方法,要导入依赖、下载插件才可以使用
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency>
package tk.mybatis.simple.model;
import lombok.Data;
@Data
public class SysUserRole {
private Long userId;
private Long roleId;
}
4.Mapper
创建一下文件
xml:
需要注意 是<mapper >根标签 name space 属性。当 app 接口和 XM 文件关联的时候,命名空间口amespace 值就需要配置成接口的全限定名称,例如 UserMapper 接口对 应的 tk.mybat. simple.mapper.UserMapper内部就是通过这个值将接口和XML 关联起来的。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 需要注意 是<mapper >根标签 name space 属性。当 app 接口和 XM 文件关联的-->
<!-- 时候,命名空间口amespace 值就需要配置成接口的全限定名称,例如 UserMapper 接口对-->
<!-- 应的 tk mybat simple .mapper . UserMapper, is 内部就是通过这个值将接口和-->
<!-- XML 关联起来的。-->
<mapper namespace="tk.mybatis.simple.mapper.UserMapper">
</mapper>
mybatis-config.xml
<mappers>
<mapper resource="mapper/CountryMapper.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/RoleMapper.xml"/>
<mapper resource="mapper/PrivilegeMapper.xml"/>
<mapper resource="mapper/UserRoleMapper.xml"/>
<mapper resource="mapper/RolePrivilegeMapper.xml"/>
</mappers>
5.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 需要注意 是<mapper >根标签 name space 属性。当 app 接口和 XM 文件关联的-->
<!-- 时候,命名空间口amespace 值就需要配置成接口的全限定名称,例如 UserMapper 接口对-->
<!-- 应的 tk mybat simple .mapper . UserMapper, is 内部就是通过这个值将接口和-->
<!-- XML 关联起来的。-->
<mapper namespace="tk.mybatis.simple.mapper.UserMapper">
<!-- constructor: 通过构造方法注入属性的结果值 构造方法中的 idArg 、arg 参数分别对应着 resultMap 中的 id result 标签,它们的含义相同,只是注入方式不同-->
<!-- resultMap :中的 id result 标签包含的属性相同,不同的地方在于, id 表的是主键(或唯一值)的字段(可以有多个),它们的属性值是通过 setter 方法注入的-->
<resultMap id="userMap" type="tk.mybatis.simple.model.SysUser">
<!-- id :必填,并且唯一。 select 标签中, resultMap 指定的值即为此处 id 所设置的值。
type :必填,用于配置查询列所映射到的 Java 对象类型。
extends :选填,可以配置当前的 resultMap 继承自其他的 re sultMap ,属性值为继承 resultMap id
autoMapping :选填,可选值为 true false ,用于配置是否启用非映射字段(没有在 resultMap 中配置的字段〉的自动映射功能 该配置可以覆盖全局的
autoMappingBehavior 配置。以上是 resultMap 的属性, resultMap 包含的所有标签如下。
constructor :配置使用构造方法注入结果,包含以下两个子标签
idArg: id 参数,标记结果作为 id (唯 值),可以帮助提高整体性能。
arg :注入到构造方法的 个普通结果。
id :一个id 结果,标记结果作为 id (唯 值),可以帮助提高整体性能。
result :注入到 Java 对象属性的普通结果。
association: 一个复杂的类型关联,许多结果将包成这种类型
collection :复杂类型的集合。
discriminator :根据结果值来决定使用哪个结果映射。
case: 基于某些值的结果映射。-->
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userPassword" column="user_password"/>
<result property="userEmail" column="user_email"/>
<result property="userInfo" column="user_info"/>
<result property="headImg" column="head_img" jdbcType="BLOB"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<!-- id result 标签包含的属性。-->
<!-- column :从数据库中得到的列名 或者是列的别名。-->
<!-- property :映射到列结果的属性。可以映射简单的如“username ”这样的属性,也-->
<!-- 可以映射 些复杂对象中的属性 例如“ address.street.number ”,这会通过“ .”-->
<!-- 方式的属性嵌套赋值。-->
<!-- javaType Ja 类的完全限定名,或 个类型别名(通过 typeAlias 配置或者-->
<!-- 默认的类型)。如果映射到 JavaBean,mybatis通常可以自动判断属性的类型。如-->
<!-- 果映射到 HashMap ,则需要明确地指定 av a Type 属性-->
<!-- jdbcType 列对应的数据库类型。 JDB 类型仅仅需要对插入、更新、删除操作可能-->
<!-- 为空的列进行处理。这是 JDB j dbcType 的需要,而不是 My atis 的需要-->
<!-- typeHandler :使用这个属性可以覆盖默认的类型处理器。这个属性值是类的完全限-->
<!-- 定名或类型别名。-->
</resultMap>
<!-- XML 中的 select 标签的 id 属性值和定义的接口方法名是 样的ρMyBatis
就是通过这种方式将接口方法和 XML 定义的 SQL 语句关联到 起的,如果接口方法没有和
XML 中的 id 属性值相对应,启动程序便会报错。-->
<select id="selectById" resultMap="userMap">
<!-- select 映射查询语句使用的标签。
id :命名空间中的唯 标识符,可用来代表这条语句。
resultMap :用于设置返回值的类型和映射关系
-->
select * from sys_user where id = #{id}
<!-- # {id} : MyBatis SQL 中使用预编译参数的一种方式,大括号中的 id 是传入的参数名。
在上面的 elect 中,使用 resultMap 设置返回值的类型,这里的 userMap 就是上面
<res ultMap 中的 id 属性值,通过 id 引用需要的<resultMap >。-->
</select>
<!-- 当只使用 XML 而不使用接 口的时候 names pace 的值可以设置为任意不重复的名称
标签的 id 属性值在任何 候都不能出现英文句号“.”
并且同 个命名 间下不能现重复的 id
因为接口方法是可以重载的,所以接口中可以出现多个同名但参数不同的方法,但是XML id 的值不能重复,
因而接口中的所有同名方法会对应着 XML 中的同 id的方法。
最常见的用法就是,同名方法中其中一个方法增加 RowBound 类型的参数用于实现分页查询。-->
<select id="selectAll1" resultType="tk.mybatis.simple.model.SysUser" >
select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo ,
head img headImg,
create_time createTime
from sys_user
</select>
<!-- selectByid selectAll 的区别 selectByid 中使用
resultMap 来设置结果映射,而 selectAll 中则通过 resultType 直接指定了返回结果
的类型。可以发现,如果使用 result Type 来设置返回结果的类型,需要在 SQL 中为所有列
名和属性名不 致的列设置别名,通过设置别名使最终的查询结果列和 result Type 指定对象
的属性名保持 致,进而实现自动映射。 -->
<select id= "selectAll2" resultType="tk.mybatis.simple.model.SysUser" >
select id, user_name , user_password, user_email , user_info, head_img, create_time from sys_user
</select>
</mapper>
6.BaseMapperTest
package tk.mybatis.simple.mapper;
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.BeforeClass;
import java.io.IOException;
import java.io.Reader;
public class BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void init () {
try {
Reader reader = Resources.getResourceAsReader ("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException ignore) {
ignore.printStackTrace();
}
}
public SqlSession getSqlSession () {
return sqlSessionFactory.openSession();
}
}
7.CountryMapperTest
package tk.mybatis.simple.mapper;
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.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import tk.mybatis.simple.model.Country;
import tk.mybatis.simple.model.SysUser;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class CountryMapperTest extends BaseMapperTest {
private static SqlSessionFactory sqlSessionFactory;
// @BeforeClass
// public static void init() {
// try {
通过 Resources 工具类将 ti -config.xm 配置文件读入 Reader
// Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
再通过 SqlSessionFactoryBuilder 建造类使用 Reader 创建 SqlSessionFactory工厂对象。
在创建 SqlSessionFactory 对象的过程中
首先解 mybatis-config.xml 配置文件,读取配置文件中的 mappers 配置后会读取全部的 Mapper xml 进行具体方法的解析,
在这些解析完成后, SqlSessionFactory 就包含了所有的属性配置和执行 SQL 的信息。
// sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
使用时通过 SqlSessionFactory 工厂对象获取 splSession
// reader.close();
// } catch (IOException ignore) {
// ignore.printStackTrace();
// }
// }
//
// private void printCountryList(List<Country> countryList) {
// for (Country country : countryList) {
// System.out.printf("%-4d%4s%4s\n", country.getId(), country.getCountryname(), country.getCountrycode());
// }
// }
@Test
public void testSelectByid() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
SysUser user = userMapper.selectById((long) 1);
Assert.assertNotNull(user);
Assert.assertEquals("admin", user.getUserName());
} finally {
sqlSession.close();
}
}
@Test
public void testSelectAll() {
SqlSession sqlSession = getSqlSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<SysUser> userList = userMapper.selectAll();
Assert.assertNotNull(userList);
Assert.assertTrue(userList.size() > 0);
} finally {
sqlSession.close();
}
}
}
8.运行结果
9.总结
(1)mapper接口存放在java下的mapper包里,mapper.xml存放在资源包下面!
namespace的值是对应的mapper接口的全限定名称
(2)实体类用驼峰命名法,sql 里的映射
1.用别名法映射
2.自动映射
配置:
3.使用 resultMap