一、引言
1.1 原始jdbc操作
//1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
connection = DriverManager.getConnection(url, username, password);
//3. 获取statement
preparedStatement = connection.prepareStatement(sql);
//4. 执行更新或查询
resultSet = preparedStatement.executeQuery(sql);
//5. 遍历结果集
while (resultSet.next()) {
System.out.println(resultSet.getInt("id")+'-'+resultSet.getString("username")+','+resultSet.getString("password"));
UserEntity userEntity = new UserEntity();
userEntity.setId(resultSet.getInt("id"));
userEntity.setUsername(resultSet.getString("username"));
userEntity.setPassword(resultSet.getString("password"));
System.out.println(userEntity);
}
//6. 释放资源
resultSet.close();
preparedStatement.close();
connection.close();
1.2 原始jdbc存在的问题及解决方案
问题
- 数据库连接创建、释放频繁造成系统资源浪费从而影响性能。
- java代码和sql语句耦合死,sql语句是硬编码,代码不易维护。
- 查询操作需要手动将结果集封装到实体中,增删改手动将实体数据设置到sql语句的占位符
解决方案
- 使用数据库连接池初始化连接资源
- 将sql语句抽取到xml配置文件中。
- 使用反射、内省等底层技术自动将实体属性和表字段进行映射。
二、认识mybatis
2.1 什么是mybatis?
* mybatis是一个优秀的基于java代码的持久层框架,内部封装了jdbc,开发者只关注sql语句本身。
* mybatis通过xml配置或注解的方式将要执行的各种statement配置,并通过java对象和statement中sql动态参数进行映射生成最终的sql语句。
* mybatis执行的sql并将结果映射为java对象并返回。采用ORM思想解决实体和数据库表映射问题,对jdbc进行封装,屏蔽了jdbc API底层访问细节,使我们不用和jdbc API打交道就完成了数据库的持久化操作。
我的理解: Mybatis是一个持久层框架。其内部隐藏了jdbc繁杂的API。使得开发者只需要关注sql语句本身。它能够将数据库表字段和java中的实体对象的属性进行自动映射。
详情学习可以参照官网。
补充:
ORM思想:(Object Relational Mapping)思想:对象关系映射。
ORM框架自动实现Entity实体的属性与关系型数据库字段的映射。CRUD的工作则可以交给ORM来自动生成代码方式实现。
帮助我们开发人员跟踪实体的变化,并将实体的变化翻译成sql脚本,执行到数据库中去,也就是将实体的变化映射到了表的变化。
2.2 mybatis的快速入门
下面先通过一个入门案例感受一下mybatis操作数据持久层
- 先导入pom.xml相关mybatis依赖
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!--日志依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
- 创建一张user数据表
- 准备user实体类
public class User {
private int id;
private String username;
private String password;
private String phoneNum;
private int status;
// 自行生成get/set方法、构造器、toString方法
- 编写映射文件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">
<mapper namespace="userMapper">
<select id="findAll" resultType="cn.hfnu.domain.User">
select * from t_user
</select>
</mapper>
- 编写核心配置文件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>
<!--配置数据源环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_test?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="cn/hfnu/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
- 测试
@Test
public void test1() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句 参数:命名空间 . id
List<User> userList = sqlSession.selectList("userMapper.findAll");
System.out.println("=======userList=========>"+userList);
//释放资源
sqlSession.close();
}
效果图
三、mybatis的映射文件的概述
<?xml version="1.0" encoding="UTF-8" ?>
<!--映射文件DTD的约束头-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--根标签的命名空间属性与下面的id组成查询的标识-->
<mapper namespace="userMapper">
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultType="cn.hfnu.domain.User">
/*要执行的sql语句*/
select * from t_user
</select>
</mapper>
mybatis的增删改操作
<!--添加操作-->
<insert id="add" parameterType="cn.hfnu.domain.User">
insert into t_user (username, password, phone_num, status) values (#{username}, #{password}, #{phoneNum}, #{status})
</insert>
@Test
public void test2() throws IOException {
//创建一个user对象
User user = new User();
user.setUsername("大梦");
user.setPassword("3344");
user.setPhoneNum("139555001212");
user.setStatus(1);
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句 参数:命名空间 . id
int count = sqlSession.insert("userMapper.add", user);
System.out.println("=========count========>"+count);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
<!--修改操作-->
<update id="update" parameterType="cn.hfnu.domain.User">
update t_user set username=#{username}, phone_num = #{phoneNum}, status = #{status} where id = #{id};
</update>
@Test
public void test3() throws IOException {
//创建一个user对象
User user = new User();
user.setId(7);
user.setUsername("大梦初醒");
user.setPhoneNum("15043995110");
user.setStatus(0);
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句 参数:命名空间 . id
int count = sqlSession.update("userMapper.update", user);
System.out.println("=========count========>"+count);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
<!--删除操作-->
<delete id="delete" parameterType="java.lang.Integer">
delete from t_user where id = #{id}
</delete>
@Test
public void test4() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句 参数:命名空间 . id
int count = sqlSession.delete("userMapper.delete", 7);
System.out.println("=========count========>"+count);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
四、mybatis的核心配置文件的标签
mapper标签:用来加载映射文件的,其加载方式:
- 使用相对于类路径的资源引用
- 使用完全限定资源定位符(URL)、
- 使用映射器接口实现类的完全限定类名
- 将包名内的映射器接口实现全部注册为映射器
properties标签:将数据源信息单独抽成一个properties。
<!--通过properties标签加载外部properties文件-->
<properties resource="jdbc.properties"></properties>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_test?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
typeAliases标签:类型别名
<!--自定义配置别名-->
<typeAliases>
<typeAlias type="cn.hfnu.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--查询操作-->
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultType="user">
/*要执行的sql语句*/
select * from t_user
</select>
typehandlers标签:类型处理器获取的值以合适的值转换成Java类型。
准备实体类User
```
public class User {
private int id;
private String username;
private String password;
private String phoneNum;
private int status;
private Date birth;
//getter()/setter()方法略
报错信息:
自定义日期类型处理器
//将java的属性的类型转化成数据库的字段对应的类型
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i, time);
}
//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
//获取结果集中需要的数据(long)类型转换成date类型的数据
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
//获取结果集中需要的数据(long)类型转换成date类型的数据
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
//将数据库的字段的类型转换成java的属性类型
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
<!--自定义类型处理器-->
<typeHandlers>
<typeHandler handler="cn.hfnu.handler.DateTypeHandler"/>
</typeHandlers>
<!--添加操作-->
<insert id="add" parameterType="user">
insert into t_user (username, password, phone_num, status, birth)
values (#{username}, #{password}, #{phoneNum}, #{status}, #{birth})
</insert>
public void add(User user);
@Test
public void test4() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("meng");
user.setPassword("000");
user.setPhoneNum("13911220011");
user.setStatus(1);
user.setBirth(new Date());
mapper.add(user);
sqlSession.commit();
sqlSession.close();
}
效果图
<!--根据id查询-->
<select id="findById" parameterType="int" resultType="user">
select * from t_user where id = #{id};
</select>
@Test
public void test5() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findById(8);
System.out.println("========birth=========>"+user.getBirth());
sqlSession.close();
}
效果图
plugins标签:扩展功能,PageHelper分页的复杂操作进行封装。
<!--分页助手的依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.5</version>
</dependency>
<!--配置分页助手插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
//设置分页所需要的参数 当前页 + 每页显示的条数
PageHelper.startPage(2, 3);
//设置分页所需要的参数 当前页 + 每页显示的条数
PageHelper.startPage(3, 3);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
//获得分页相关的参数
PageInfo<User> pageInfo = new PageInfo<User>(userList);
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示的条数:"+pageInfo.getPageSize());
System.out.println("总的记录数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("上一页:"+pageInfo.getPrePage());
System.out.println("下一页:"+pageInfo.getNextPage());
System.out.println("是否到首页:"+pageInfo.isIsFirstPage());
System.out.println("是否是尾页:"+pageInfo.isIsLastPage());
效果图
五、mybatis的API简介
略
六、mybatis的持久层实现
6.1 传统的方式
手动对dao层的实现 userdao接口:
List findAll();
userdaoimpl实现类:
private SqlSessionFactory factory;
public UserDaoImpl(SqlSessionFactory factory) { this.factory = factory; }
@Override
public List findAll() {
SqlSession session = factory.openSession();
List users = session.selectList("com.itheima.dao.IUserDao.findAll"); session.close();
return users;
}
6.2 代理开发的方式(重点)
1.mapper.xml文件中namespace与mapper接口的全限定名相同
2.mapper接口方法名和mapper.xml定义的每个statement的id相同。
3.mapper接口方法的输入参数类型和mapper.xml定义的每一个sql的parameterType的类型相同
4.mapper接口的输出参数和mapper.xml定义的每一个sql的resulttype的类型相同。
<mapper namespace="cn.hfnu.dao.UserMapper">
<!--查询操作-->
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultType="user">
/*要执行的sql语句*/
select * from t_user
</select>
</mapper>
public interface UserMapper {
public List<User> findAll() throws IOException;
}
@Test
public void test1() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> all = mapper.findAll();
System.out.println(all);
}
效果图
七、mybatis的映射文件
7.1 动态sql
引入log4j.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:\axis.log
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
<!--根据条件查询-->
<select id="findByCondition" parameterType="user" resultType="user">
select * from t_user
<where>
<if test="username != null and username != ''">
and username=#{username}
</if>
<if test="password != null and password != ''">
and password=#{password}
</if>
<if test="status != null and status != ''">
and status=#{status};
</if>
</where>
</select>
public List<User> findByCondition(User user);
@Test
public void test2() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
//user.setUsername("张三");
user.setPassword("123");
user.setStatus(0);
List<User> userList = mapper.findByCondition(user);
System.out.println("=============userList=========>"+userList);
}
效果图
<!--根据ids进行查询-->
<select id="findByIds" parameterType="list" resultType="user">
select * from t_user
<where>
<foreach collection="list" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
public List<User> findByIds(List<Integer> ids);
@Test
public void test3() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(3);
ids.add(4);
List<User> userList = mapper.findByIds(ids);
System.out.println("========userList=========>"+userList);
}
效果图
7.2 sql片段
<!--sql语句的抽取-->
<sql id="selectUser">
select username, status from t_user
</sql>
<!--根据ids进行查询-->
<select id="findByIds" parameterType="list" resultType="user">
<include refid="selectUser"></include>
<where>
<foreach collection="list" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
八、 mybatis的多表操作
8.1 一对一的模型映射
public class Orders {
private int id;
private Date orderTime;
private double total;
//当前订单所属哪一个用户
private User user;
//getter/setter方法省略
public interface OrderMapper {
public List<Orders> findAll();
<!--自定义配置别名-->
<typeAliases>
<typeAlias type="cn.hfnu.domain.User" alias="user"></typeAlias>
<typeAlias type="cn.hfnu.domain.Orders" alias="order"></typeAlias>
</typeAliases>
<!--加载映射文件-->
<mappers>
<mapper resource="cn/hfnu/mapper/UserMapper.xml"></mapper>
<mapper resource="cn/hfnu/mapper/OrderMapper.xml"></mapper>
</mappers>
<mapper namespace="cn.hfnu.dao.OrderMapper">
<resultMap id="orderMap" type="order">
<!--设置实体属性和表字段的映射关系-->
<id column="oid" property="id"></id>
<result column="order_time" property="orderTime"></result>
<result column="total" property="total"></result>
<result column="user_id" property="user.id"></result>
<result column="username" property="user.username"></result>
<result column="password" property="user.password"></result>
<result column="phone_num" property="user.phoneNum"></result>
<result column="status" property="user.status"></result>
<result column="birth" property="user.birth"></result>
</resultMap>
<select id="findAll" resultMap="orderMap">
SELECT *,o.id oid from t_orders o, t_user u WHERE o.user_id = u.id
</select>
</mapper>
<resultMap id="orderMap" type="order">
<!--设置实体属性和表字段的映射关系-->
<id column="oid" property="id"></id>
<result column="order_time" property="orderTime"></result>
<result column="total" property="total"></result>
<!--<result column="user_id" property="user.id"></result>
<result column="username" property="user.username"></result>
<result column="password" property="user.password"></result>
<result column="phone_num" property="user.phoneNum"></result>
<result column="status" property="user.status"></result>
<result column="birth" property="user.birth"></result>-->
<!--1:1的映射配置-->
<association property="user" javaType="user">
<id column="user_id" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="phone_num" property="phoneNum"></result>
<result column="status" property="status"></result>
<result column="birth" property="birth"></result>
</association>
</resultMap>
@Test
public void test1() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<Orders> ordersList = mapper.findAll();
for (Orders orders : ordersList) {
System.out.println("=========orders===========>"+orders);
}
sqlSession.close();
}
效果图
8.2 一对多的模型映射
<resultMap id="userMap" type="user">
<id column="user_id" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="phone_num" property="phoneNum"></result>
<result column="status" property="status"></result>
<result column="birth" property="birth"></result>
<!--配置集合信息-->
<collection property="ordersList" ofType="order">
<!--封装订单信息-->
<id column="oid" property="id"></id>
<result column="order_time" property="orderTime"></result>
<result column="total" property="total"></result>
</collection>
</resultMap>
<!--查询操作-->
<!--具体的数据操作(增删改查)以及操作的结果对应的实体类型-->
<select id="findAll" resultMap="userMap">
/*要执行的sql语句*/
/* select * from t_user*/
select *,o.id oid from t_user u, t_orders o where u.id = o.user_id
</select>
public class User {
private int id;
private String username;
private String password;
private String phoneNum;
private int status;
private Date birth;
//描述当前用户存在哪些订单中
private List<Orders> ordersList;
//getter()/setter()方法省略
@Test
public void test2() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
8.3 多对多的模型映射
public List<User> findUserAndRoleAll();
<resultMap id="userRoleMap" type="user">
<!--封装user信息-->
<id column="user_id" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="phone_num" property="phoneNum"></result>
<result column="status" property="status"></result>
<result column="birth" property="birth"></result>
<!--封装user内部的rolelist信息-->
<collection property="roleList" ofType="role">
<id column="role_id" property="id"></id>
<result column="role_name" property="roleName"></result>
<result column="role_desc" property="roleDesc"></result>
</collection>
</resultMap>
<select id="findUserAndRoleAll" resultMap="userRoleMap">
SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND r.id = ur.role_id
</select>
public class User {
private int id;
private String username;
private String password;
private String phoneNum;
private int status;
private Date birth;
//描述当前用户存在哪些订单中
private List<Orders> ordersList;
//描述当前用户所具有的哪些角色
private List<Role> roleList;
//geter/setter方法省略
@Test
public void test3() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过mapper代理获取代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userAndRoleAll = mapper.findUserAndRoleAll();
for (User user : userAndRoleAll) {
System.out.println(user);
}
sqlSession.close();
}
九、mybatis的注解开发
9.1 以注解的方式完成CRUD
usermapper的接口
@Insert("insert into t_user values (#{id}, #{username}, #{password}, #{phoneNum}, #{status}, #{birth})")
public void add(User user);
@Update("update t_user set username=#{username}, password=#{password} where id=#{id}")
public void update(User user);
@Delete("delete from t_user where id=#{id}")
public int delete(int id);
@Select("select * from t_user where id=#{id}")
public User findById(int id);
@Select("select * from t_user")
public List<User> findAll();
<!—注解方式加载映射关系-->
<mappers>
<!--加载接口所在的包-->
<package name="cn.hfnu.mapper"></package>
</mappers>
private UserMapper mapper;
@Before
public void before() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void add(){
User user = new User();
user.setUsername("林心如");
user.setPassword("123");
user.setPhoneNum("139333210101");
user.setStatus(1);
mapper.add(user);
}
@Test
public void update(){
User user = new User();
user.setId(10);
user.setUsername("心茹");
user.setPassword("777");
mapper.update(user);
}
@Test
public void delete(){
int count = mapper.delete(8);
System.out.println("========count===>"+count);
}
@Test
public void findById(){
User user = mapper.findById(13);
System.out.println("=======user=========>"+user);
}
@Test
public void findAll(){
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println("========userList=========>"+user);
}
}
效果图
9.2 mybatis的注解实现复杂的映射关系
9.2.1 1:1的模型
public class Orders {
private int id;
private String orderTime;
private double total;
//当前的订单所属哪一个用户 1 :1
private User user;
//getter/setter方法省略
@Select("select *,u.id uid, o.id oid from t_orders o, t_user u WHERE o.user_id = u.id")
@Results({
@Result(column = "oid", property = "id"),
@Result(column = "order_time", property = "orderTime"),
@Result(column = "total", property = "total"),
@Result(column = "user_id", property = "user.id"),
@Result(column = "username", property = "user.username"),
@Result(column = "password", property = "user.password"),
@Result(column = "phone_num", property = "user.phoneNum"),
@Result(column = "status", property = "user.status"),
@Result(column = "birth", property = "user.birth"),
})
public List<Orders> findAll();
private OrderMapper mapper;
@Before
public void before() throws IOException {
//加载核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(OrderMapper.class);
}
@Test
public void findAll(){
List<Orders> ordersList = mapper.findAll();
for (Orders orders : ordersList) {
System.out.println("==========orders========>"+orders);
}
}
效果图
@Select("select * from t_orders")
@Results({
@Result(column = "oid", property = "id"),
@Result(column = "order_time", property = "orderTime"),
@Result(column = "total", property = "total"),
@Result(
property = "user", //要封装的属性名称
column = "user_id", //根据哪个字段查询user表的数据
javaType = User.class, //要封装的实体类型
//select属性:代表查询哪个接口的方法获得数据
one = @One(select = "cn.hfnu.mapper.UserMapper.findById")
)
})
public List<Orders> findAll();
效果图
9.2.2 1:n 的映射模型
@Select("select * from t_user")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "passsword", property = "password"),
@Result(column = "phone_num", property = "phoneNum"),
@Result(column = "status", property = "status"),
@Result(
property = "ordersList",
column = "id",
javaType = List.class,
many = @Many(select = "cn.hfnu.mapper.OrderMapper.findByUid")
)
})
public List<User> findUserAndOrderAll();
@Select("select * from t_orders where user_id = #{user_id}")
public List<Orders> findByUid(int user_id);
@Test
public void findUserAndOrderAll(){
List<User> userAndOrderAll = userMapper.findUserAndOrderAll();
for (User user : userAndOrderAll) {
System.out.println("===========user======>"+user);
}
}
9.2.3 m:n模型映射
//当前用户具有哪些角色
private List<Role> roleList;
public interface RoleMapper {
@Select("SELECT * from t_user_role ur, t_role r WHERE ur.role_id = r.id AND ur.user_id = #{user_id}")
public List<Role> findByUserId(int user_id);
}
@Select("select * from t_user")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "password", property = "password"),
@Result(column = "phone_num", property = "phoneNum"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "cn.hfnu.mapper.RoleMapper.findByUserId")
)
})
public List<User> findUserAndRoleAll();
@Test
public void findUserAndOrderAll(){
List<User> userAndRoleAll = userMapper.findUserAndRoleAll();
for (User user : userAndRoleAll) {
System.out.println("========user========>"+user);
}
}
以上步骤按部就班的完成对数据持久层框架有基础的入门学习,这只是个人的学习记录。如果你在看就点“在看”,点个“赞”,滴,IT学习面试就业必胜卡,坚持一件事情不容易,我们的目标和和人民日报站在一起!