如果有疑问可以先看上一篇博文:mybatis入门环境的部署
下面开始展示Mybatis的增删改查操作
在Maven项目中需要的环境如下:
<!--如下是maven的导包问题--> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
MyBatis框架在操作数据库时,大体经过了8个步骤。具体如下。
(1)读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接。
(2)加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。
(3)构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。
(4)创建SqlSession对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL的所有方法。
(5)MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
(6)在Executor接口的执行方法中,包含一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等。Mapper.xml文件中一个SQL对应一个MappedStatement对象,SQL的id即是MappedStatement的id。
(7)输入参数映射。在执行方法时,MappedStatement对象会对用户执行SQL语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型), Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。
(8)输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型), Executor执行器会通过MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。通过上面对MyBatis框架执行流程的讲解,相信读者对MyBatis框架已经有了一个初步的了解。对于初学者来说,上面所讲解的内容可能不会完全理解,现阶段也不要求读者能完全理解,这里讲解MyBatis框架的执行过程是为了方便后面程序的学习。在学习完MyBatis框架后,读者自然就会明白上面所讲解的内容了。
如上是测试时对配置文件的读取操作是以上八个步骤的演示
如上是映射文件的查询代码
如上是实现方法的接口
测试案例的代码
如上图所示是结果显示的代码
映射文件的完整代码
<?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="top.zyz.dao.UserDao"> <!--配置查询所有--> <select id="findAll" resultType="top.zyz.damain.User"> select *from user </select> <!--保存用户--> <insert id="saveUsers" parameterType="top.zyz.damain.User"> <!-- 配置插入操作后,获取插入数据的id --> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id(); </selectKey> insert into user(username,password,useremail)values(#{username},#{password},#{useremail}); </insert> <!--更新用户的信息--> <update id="updateUser" parameterType="top.zyz.damain.User"> update user set username=#{username},password=#{password},useremail=#{useremail} where id=#{id} </update> <!--删除用户--> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id=#{id} </delete> </mapper>
用户接口类的完整代码
import top.zyz.damain.User; import java.util.List; /* * 用户接口方法 * */ public interface UserDao { /* * 查询所有的用户信息 * */ List<User> findAll(); /* * 保存用户方法 * */ void saveUser(User user); /* * 更新用户操作 * */ void updateUser(User user); /* *删除用户 * */ void deleteUser(int id); }
实现类的完整方法
import com.zyz.dao.UserDao; import com.zyz.domain.Users; 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 MybatisTest2 { private InputStream in; private SqlSession sqlSession; private UserDao usersDao; @Before//用于在测试方法执行之前执行 public void init()throws Exception{ //1.读取配置文件,生成字节输入流 in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.获取SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.获取SqlSession对象 sqlSession = factory.openSession(); //4.获取dao的代理对象 usersDao=sqlSession.getMapper(UserDao.class); } @After//用于在测试方法执行之后执行 public void destroy()throws Exception{ //提交事务 sqlSession.commit(); //6.释放资源 sqlSession.close(); in.close(); } @Test public void test1(){ Users users=new Users(); users.setUsername("test2"); users.setAddress("test2"); users.setSex("男"); users.setBirthday(new Date()); System.out.println("保存操作之前:"+users); //5.执行保存方法 usersDao.saveUsers(users); System.out.println("保存操作之后:"+users); } /*测试查询所有*/ @Test public void test2(){ List<Users> users=usersDao.findAll(); for(Users user:users){ System.out.println(user); } } /*测试更新操作*/ @Test public void test3(){ Users user=new Users(); user.setId(50); user.setUsername("mybastis update user"); user.setAddress("mybastis update user"); user.setSex("男"); user.setBirthday(new Date()); usersDao.updateUsers(user); } /* * 测试删除案例 * */ @Test public void testdeleteUsers(){ int id=50; usersDao.deleteUsers(id); } /** * 测试模糊查询操作 */ @Test public void testFindByName(){ List<Users> users=usersDao.findByName("%王%"); for(Users user:users){ System.out.println(user); } } /** * 测试查询总记录条数 */ @Test public void testFindTotal(){ //5.执行查询一个方法 int count = usersDao.findTotal(); System.out.println(count); } }
模糊查询可以使用如上的方式进行
SqlSession对象中包含了很多方法,其常用方法如下所示。
<T> T selectOne(String statement);
查询方法。参数statement是在配置文件中定义的<select>元素的id。使用该方法后,会返回执行SQL语句查询结果的一条泛型对象。
· <T> T selectOne(String statement, Object parameter);
查询方法。参数statement是在配置文件中定义的<select>元素的id, parameter是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的一条泛型对象。
· <E> List<E> selectList(String statement);
查询方法。参数statement是在配置文件中定义的<select>元素的id。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合。·
<E> List<E> selectList(String statement, Object parameter);
查询方法。参数statement是在配置文件中定义的<select>元素的id, parameter是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合。
<E> List<E> selectList(String statement, Object parameter, RowBoundsrowBounds);
查询方法。参数statement是在配置文件中定义的<select>元素的id, parameter是查询所需的参数,rowBounds是用于分页的参数对象。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合。
· void select(String statement, Object parameter, ResultHandler handler);
查询方法。参数statement是在配置文件中定义的<select>元素的id, parameter是查询所需的参数,ResultHandler对象用于处理查询返回的复杂结果集,通常用于多表查询。
· int insert(String statement);
插入方法。参数statement是在配置文件中定义的<insert>元素的id。使用该方法后,会返回执行SQL语句所影响的行数。
· int insert(String statement, Object parameter);
插入方法。参数statement是在配置文件中定义的<insert>元素的id, parameter是插入所需的参数。使用该方法后,会返回执行SQL语句所影响的行数。
· int update(String statement);
更新方法。参数statement是在配置文件中定义的<update>元素的id。使用该方法后,会返回执行SQL语句所影响的行数。
· int update(String statement, Object parameter);
更新方法。参数statement是在配置文件中定义的<update>元素的id, parameter是更新所需的参数。使用该方法后,会返回执行SQL语句所影响的行数。
· int delete(String statement);
删除方法。参数statement是在配置文件中定义的<delete>元素的id。使用该方法后,会返回执行SQL语句所影响的行数。
· int delete(String statement, Object parameter);
删除方法。参数statement是在配置文件中定义的<delete>元素的id, parameter是删除所需的参数。使用该方法后,会返回执行SQL语句所影响的行数。
· void commit();
提交事务的方法。
· void rollback();
回滚事务的方法。
void close();
关闭SqlSession对象。
· <T> T getMapper(Class<T> type);
该方法会返回Mapper接口的代理对象,该对象关联了SqlSession对象,开发人员可以使用该对象直接调用方法操作数据库。参数type是Mapper的接口类型。MyBatis官方推荐通过Mapper对象访问MyBatis。
· Connection getConnection();
获取JDBC数据库连接对象的方法。
但是注意一下:sqlsession的对象在使用时一定注意:不同dao映射文件中的方法名不要相同,否则会报错的
OGNL表达式:
Object Graphic Navigation Language
对象 图 导航 语言
它是通过对象的取值方法来获取数据。在写法上把get给省略了。
比如:我们获取用户的名称
类中的写法:user.getUsername();
OGNL表达式写法:user.username
mybatis中为什么能直接写username,而不用user.呢:
因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名