下一篇文章地址:Java之MyBatis【IDEA版】(一篇文章精通系列)增删改查【注解开发】 - 所有知识点(大全)
mybatis 是一个优秀的基于java的持久层框架,
它内部封装了jdbc,使开发者只需要关注sql语句本身,
而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
*
mybatis通过xml或注解的方式将要执行的各种 statement配置起来,
并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句。
*
最后mybatis框架执行sql并将结果映射为java对象并返回。
采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,
屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,
就可以完成对数据库的持久化操作。
MyBatis官网地址:http://www.mybatis.org/mybatis-3/
MyBatis开发步骤:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itbluebox</groupId>
<artifactId>spring-mybatis</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<!--mybatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<!--单元测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--日志坐标-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
</project>
package cn.itbluebox.domain;
public class User {
private int id;
private String username;
private String password;
public User() {
}
public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
<?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">
<!--根据id进行查询-->
<select id="findById" resultType="user" parameterType="int">
select * from user where id=#{id}
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
<?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标签加载外部properties文件-->
<properties resource="jdbc.properties"></properties>
<!--自定义别名-->
<typeAliases>
<typeAlias type="cn.itbluebox.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<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>
<!--加载映射文件-->
<mappers>
<mapper resource="cn/itbluebox/mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
//加载核心配置文件
InputStream resourceAsStream =
Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession工厂对象
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();
添加MyBatis的坐标
创建user数据表
编写User实体类
编写映射文件UserMapper.xml
编写核心文件SqlMapConfig.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">
<!--根据id进行查询-->
<insert id="add" parameterType="cn.itbluebox.domain.User">
insert into user values (#{id},#{username},#{password})
</insert>
</mapper>
package cn.itbluebox.test;
import cn.itbluebox.domain.User;
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.Test;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
//插入一个对象
public void test1()throws IOException {
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session回话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作,参数:namespace+id
int insert = sqlSession.insert("userMapper.add", new User(1, "zhangsan", "2121212"));
//打印数据
System.out.println(insert);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
insert
标签parmeterType
属性指定要插入的数据类型/#{实体属性名}
方式引用实体的属性值sqlSession.insert("命名空间.id",实体对象);
sqlSession
对象显示的提交事务sqlSession.commit()
<update id="update" parameterType="cn.itbluebox.domain.User">
update user set username = #{username},password = #{password} where id = #{id}
</update>
@Test
//修改实体User的代码
public void testUpdateUser()throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(1);
user.setUsername("张三丰");
user.setPassword("12121212121212");
int update = sqlSession.update("userMapper.update", user);
System.out.println(update);
sqlSession.commit();
sqlSession.close();
}
修改语句使用update标签
修改操作使用的API是sqlSession.update(“命名空间.id”,实体对象);
MyBatis的parameterType传入参数类型
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
@Test
//删除User
public void testDeleteUser() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
int delete = sqlSession.delete("userMapper.delete",1);
System.out.println(delete);
sqlSession.commit();
sqlSession.close();
}
删除成功
删除语句使用delete
标签
Sql语句中使用/#{任意字符串}
方式引用传递的单个参数
删除操作使用的API是sqlSession.delete(“命名空间.id”,Object);
数据库当中插入一些数据
<!--查询操作-->
<select id="findAll" resultType="user">
select * from user
</select>
@Test
//查询所有shuju
public void testFindAllUser() throws IOException{
//加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建作用域工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取会话对象
SqlSession sqlSession = sessionFactory.openSession();
List<User> users = sqlSession.selectList("userMapper.findAll");
for (User user : users) {
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
运行结果
<!--查询操作-->
<select id="findAllByname" resultType="user" parameterType="cn.itbluebox.domain.User">
select * from user where username like "%" #{username} "%"
</select>
@Test
//查询所有shuju
public void testFindAllUserByName() throws IOException{
//加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建作用域工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取会话对象
SqlSession sqlSession = sessionFactory.openSession();
User user = new User();
user.setUsername("张");
List<User> users = sqlSession.selectList("userMapper.findAllByname",user);
for (User us : users) {
System.out.println(us);
}
sqlSession.commit();
sqlSession.close();
}
运行测试
<!--查询操作-->
<select id="findById" resultType="user" parameterType="java.lang.Integer">
select * from user where id = #{id}
</select>
@Test
//查询一个对象
public void testFindUserOne() throws IOException {
//加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建作用域工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取会话对象
SqlSession sqlSession = sessionFactory.openSession();
User user = sqlSession.selectOne("userMapper.findById", 1);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
运行测试
数据库环境的配置,支持多环境配置
其中,事务管理器(transactionManager)类型有两种:
JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,
它依赖于从数据源得到的连接来管理事务作用域。
*
MANAGED:这个配置几乎没做什么。
它从来不提交或回滚一个连接,
而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。
默认情况下它会关闭连接,然而一些容器并不希望这样,
因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
其中,数据源(dataSource)类型有三种:
UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
*
POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
*
JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,
容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
该标签的作用是加载映射的,加载方式有如下几种:
使用相对于类路径的资源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>
实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件
类型别名是为Java 类型设置一个短的名字。原来的类型名称配置如下
配置typeAliases,为com.itbluebox.domain.User定义别名为user
上面我们是自定义的别名,mybatis框架已经为我们设置好的一些常用的类型的别名
核心配置文件常用配置:
1、properties标签:该标签可以加载外部的properties文件
<properties resource="jdbc.properties"></properties>
2、typeAliases标签:设置类型别名
<!--自定义别名-->
<typeAliases>
<typeAlias type="cn.itbluebox.domain.User" alias="user"></typeAlias>
</typeAliases>
3、mappers标签:加载映射配置
<!--加载映射文件-->
<mappers>
<mapper resource="cn/itbluebox/mapper/UserMapper.xml"></mapper>
</mappers>
4、environments标签:数据源环境配置标签
<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<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}"/2>
</dataSource>
</environment>
</environments>
常用API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象
String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
其中, Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。
SqlSessionFactory 有多个个方法创建 SqlSession 实例。常用的有如下两个:
SqlSession 实例在 MyBatis 中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。
执行语句的方法主要有:
<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)
操作事务的方法主要有:
void commit()
void rollback()
public interface UserDao {
List<User> findAll() throws IOException;
}
public class UserDaoImpl implements UserDao {
//查询所有shuju
public List<User> findAll() throws IOException{
//加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//创建作用域工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取会话对象
SqlSession sqlSession = sessionFactory.openSession();
List<User> users = sqlSession.selectList("userMapper.findAll");
for (User user : users) {
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
return users;
}
}
@Test
public void testTraditionDao() throws IOException {
UserDao userDao = new UserDaoImpl();
List<User> all = userDao.findAll();
System.out.println(all);
}
采用 Mybatis 的代理开发方式实现 DAO 层的开发,
这种方式是我们后面进入企业的主流。
Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),
由Mybatis 框架根据接口定义创建接口的动态代理对象,
代理对象的方法体同上边Dao接口实现类方法。
Mapper 接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的全限定名相同
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
package cn.itbluebox.mapper;
import cn.itbluebox.domain.User;
public interface UserMapper {
User findById(Integer id);
}
将之前的配置全部清空
写入如下配置
<?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="cn.itbluebox.mapper.UserMapper">
<select id="findById" parameterType="java.lang.Integer" resultType="cn.itbluebox.domain.User">
select * from User where id = #{id}
</select>
</mapper>
@Test
public void testProxyDao() throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(1);
System.out.println(user);
sqlSession.close();
}
代理方式对Dao进行实现:
UserMapper userMapper =
sqlSession.getMapper(UserMapper.class);
Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,
有些时候业务逻辑复杂时,我们的 SQL是动态变化的,
此时在前面的学习中我们的 SQL 就不能满足要求了。
参考的官方文档,描述如下:
<if>
我们根据实体类的不同取值,
使用不同的 SQL语句来进行查询。
比如在 id如果不为空时可以根据id查询,
如果username 不同空时还要加入用户名作为条件。
这种情况在我们的多条件组合查询中经常会碰到。
<select id="findByCondition" parameterType="cn.itbluebox.domain.User" resultType="cn.itbluebox.domain.User">
select * from User
<where>
<if test="id!=0">
and id = #{id}
</if>
<if test="username != null">
and username = #{username}
</if>
</where>
</select>
User findByCondition(User user);
@Test
public void testFindByCondition() throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setUsername("张三");
User us = userMapper.findByCondition(user);
System.out.println(us);
sqlSession.close();
}
@Test
public void testFindByCondition() throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
User us = userMapper.findByCondition(user);
System.out.println(us);
sqlSession.close();
}
<foreach>
SELECT /* FROM USER WHERE id IN (1,2,5)
。编写UserMapper.xml
<select id="findByIds" parameterType="list" resultType="cn.itbluebox.domain.User" >
select * from User
<where>
<foreach collection="array" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
ArrayList<User> findByIds(int ids[]);
@Test
public void testfindByIds() throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int[] ids = new int[]{2,4};
ArrayList<User> users = userMapper.findByIds(ids);
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
运行测试
<foreach>
标签用于遍历集合,它的属性:
collection
:代表要遍历的集合元素,注意编写时不要写/#{}
open
:代表语句的开始部分
close
:代表结束部分
item
:代表遍历集合的每个元素,生成的变量名(自定义任意名称)
sperator
:代表分隔符
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
<?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="cn.itbluebox.mapper.UserMapper">
<sql id="selectUser" >
select * from User
</sql>
<select id="findById" parameterType="java.lang.Integer" resultType="cn.itbluebox.domain.User">
<include refid="selectUser"></include>
where id = #{id}
</select>
<select id="findByCondition" parameterType="cn.itbluebox.domain.User" resultType="cn.itbluebox.domain.User">
<include refid="selectUser"></include>
<where>
<if test="id!=0">
and id = #{id}
</if>
<if test="username != null">
and username = #{username}
</if>
</where>
</select>
<select id="findByIds" parameterType="list" resultType="cn.itbluebox.domain.User" >
<include refid="selectUser"></include>
<where>
<foreach collection="array" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
</mapper>
MyBatis映射文件配置:
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时
还是从结果集中取出一个值时
都会用类型处理器将获取的值以合适的方式转换成 Java 类型。
下表描述了一些默认的类型处理器(截取部分)。
你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。
具体做法为:
实现 org.apache.ibatis.type.TypeHandler
接口,
或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler
,
然后可以选择性地将它映射到一个JDBC类型。
例如需求:一个Java中的Date数据类型,
我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成java的Date,
即java的Date与数据库的varchar毫秒值之间转换。
开发步骤:
BaseTypeHandler<T>
setNonNullParameter
为java
程序设置数据到数据库的回调方法,getNullableResult
为查询时 mysql
的字符串类型转换成 java
的Type
类型的方法package cn.itbluebox.handler;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
public class MyDateTypeHandler extends BaseTypeHandler<Date> {
//将Java 类型转换为数据库需要的类型
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
//将数据中的类型 转换为java类型
//String 类型 要转换的字段名称
//ResultSet 查询出的结果集
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
//获得结果集中需要的数据(long)转换为Date
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
//将数据库当中的类型 转换为Java的类型
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
//将数据库中的类型 转换为Java类型
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.itbluebox.handler.MyDateTypeHandler">
</typeHandler>
</typeHandlers>
package cn.itbluebox.domain;
import java.util.Date;
public class User {
private int id;
private String username;
private String password;
private Date birthday;
public User() {
}
public User(int id, String username, String password, Date birthday) {
this.id = id;
this.username = username;
this.password = password;
this.birthday = birthday;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
'}';
}
}
void save(User user);
<insert id="save" parameterType="user">
insert into User values(#{id},#{username},#{password},#{birthday})
</insert>
//插入数据
@Test
public void testSaveUser()throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//创建user
User user = new User();
user.setUsername("ceshi");
user.setPassword("abc");
user.setBirthday(new Date());
//执行保存造作
mapper.save(user);
sqlSession.commit();
sqlSession.close();
}
运行测试
testFindByCondition刚刚写过的
MyBatis可以使用第三方的插件来对功能进行扩展,
分页助手PageHelper是将分页的复杂操作进行封装,
使用简单的方式即可获得分页的相关数据
开发步骤:
<!-- 分页助手 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
<!--配置分页助手插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"></property>
</plugin>
</plugins>
ArrayList<User> select();
<select id="select" resultType="cn.itbluebox.domain.User">
<include refid="selectUser"></include>
</select>
@Test
public void testPageHelper()throws IOException{
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
PageHelper.startPage(1,3);
ArrayList<User> select = mapper.select();
for (User user : select) {
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
//其他分页的数据
PageInfo<User> pageInfo = new PageInfo<User>(select);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
MyBatis核心配置文件常用标签:
1、properties标签:该标签可以加载外部的properties文件
2、typeAliases标签:设置类型别名
3、environments标签:数据源环境配置标签
4、typeHandlers标签:配置自定义类型处理器
5、plugins标签:配置MyBatis的插件
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
对应的sql语句:select /* from orders o,user u where o.uid=u.id;
查询的结果如下:
在orders表当中添加一些数据
package cn.itbluebox.domain;
import java.util.Date;
public class Orders {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
public Orders() {
}
public Orders(int id, Date ordertime, double total, User user) {
this.id = id;
this.ordertime = ordertime;
this.total = total;
this.user = user;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getOrdertime() {
return ordertime;
}
public void setOrdertime(Date ordertime) {
this.ordertime = ordertime;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", ordertime=" + ordertime +
", total=" + total +
", user=" + user +
'}';
}
}
package cn.itbluebox.mapper;
import cn.itbluebox.domain.Orders;
import java.util.List;
public interface OrderMapper {
List<Orders> 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="cn.itbluebox.mapper.OrderMapper">
<resultMap id="orderMap" type="cn.itbluebox.domain.Orders">
<result property="id" column="id"></result>
<result property="ordertime" column="ordertime"></result>
<result property="total" column="total"></result>
<association property="user" javaType="cn.itbluebox.domain.User">
<result column="id" property="id" ></result>
<result column="username" property="username" ></result>
<result column="password" property="password" ></result>
<result column="birthday" property="birthday" ></result>
</association>
</resultMap>
<select id="findAll" resultMap="orderMap">
select * from orders o,user u where o.id = u.id
</select>
</mapper>
package cn.itbluebox.test;
import cn.itbluebox.domain.Orders;
import cn.itbluebox.mapper.OrderMapper;
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.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class OrderTest {
@Test
public void testFindOrderAll() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<Orders> all = mapper.findAll();
for (Orders order : all) {
System.out.println(order);
}
sqlSession.commit();
sqlSession.close();
}
}
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
对应的sql语句:select /*,o.id oid from user u left join orders o on u.id=o.uid;
查询的结果如下
package cn.itbluebox.domain;
import com.sun.org.apache.xpath.internal.operations.Or;
import java.util.Date;
import java.util.List;
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//带代表当前用户具备的哪些订单
private List<Orders> ordersList;
public User() {
}
public User(int id, String username, String password, Date birthday, List<Orders> ordersList) {
this.id = id;
this.username = username;
this.password = password;
this.birthday = birthday;
this.ordersList = ordersList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
", ordersList=" + ordersList +
'}';
}
}
findUserAll()
List<User> findUserAll();
<resultMap id="userMap" type="cn.itbluebox.domain.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<!--配置集合信息 property:集合名称 ofType:当前集合中的数据类型 -->
<collection property="ordersList" ofType="cn.itbluebox.domain.Orders">
<!--封装order的数据-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
</collection>
</resultMap>
<select id="findUserAll" resultMap="userMap">
select *,o.id oid from user u left join orders o on u.id=o.uid;
</select>
@Test
public void testUserAll() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> all = mapper.findUserAll();
for (User user : all) {
System.out.println(user.getUsername());
List<Orders> ordersList = user.getOrdersList();
for (Orders orders : ordersList) {
System.out.println(orders);
}
System.out.println("----------------------");
}
sqlSession.commit();
sqlSession.close();
}
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
对应的sql语句:
select u.*,r.*,r.id rid
from user u left join user_role ur on u.id=ur.user_id
inner join role r on ur.role_id=r.id;
查询的结果如下:
package cn.itbluebox.domain;
public class Role {
private int id;
private String roleName;
private String roleDesc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
package cn.itbluebox.domain;
import java.util.Date;
import java.util.List;
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//带代表当前用户具备的哪些订单
private List<Orders> ordersList;
private List<Role> roleList;
public User() {
}
public User(int id, String username, String password, Date birthday, List<Orders> ordersList, List<Role> roleList) {
this.id = id;
this.username = username;
this.password = password;
this.birthday = birthday;
this.ordersList = ordersList;
this.roleList = roleList;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", birthday=" + birthday +
", ordersList=" + ordersList +
", roleList=" + roleList +
'}';
}
}
List<User> findAllUserAndRole();
<resultMap id="userRoleMap" type="cn.itbluebox.domain.User">
<result column="id" property="id"></result>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<collection property="roleList" ofType="cn.itbluebox.domain.Role">
<result column="rid" property="id" ></result>
<result column="roleName" property="roleName"></result>
<result column="roleDesc" property="roleDesc"></result>
</collection>
</resultMap>
<select id="findAllUserAndRole" resultMap="userRoleMap">
select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id
inner join role r on ur.role_id=r.id
</select>
@Test
public void testFindAllUserAndRole() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> allUserAndRole = mapper.findAllUserAndRole();
for (User user : allUserAndRole) {
System.out.println(user.getUsername());
List<Role> roleList = user.getRoleList();
for (Role role : roleList) {
System.out.println(role);
}
}
System.out.println("------------");
}
运行
下一篇文章地址:Java之MyBatis【IDEA版】(一篇文章精通系列)增删改查【注解开发】 - 所有知识点(大全)
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_44757034/article/details/120313487
内容来源于网络,如有侵权,请联系作者删除!