框架简介?
mybatis是一个持久层框架,mybatis是一个不完全的ORM框架,通过mybatis提供的映射方式自由灵活的生成sql语句。
与其他一些mybatis的文章不同,本文是mybatis学习笔记,主要讲解mybatis的使用方法,针对入门的人或是太久没用mybatis框架的人想复习一下 也可以看看本文章。
如果想要更深层次的理解mybatis,可以去这看看《深入理解mybatis原理》,一个大佬写的文章。
开发环境
本人是通过idea创建的maven项目,这样很方便的导入所需要的jar包,(但是有个坑,后面将会讲到)。
实例讲解
mybatis框架执行过程
开发步骤
0、创建数据库,新建两张表(family_member表有一个字段user_id是为了与user表关联查询)
1、导入jar包;
2、配置mybatis的运行环境SqlMapConfig.xml
3、使用mapper代理的方法开发dao接口
4、测试(用户的增删改查)
项目结构图
开发过程
1、导入jar包
在pom.xml中添加mybatis的依赖以及日志、单元测试依赖。
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<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.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2、配置mybatis的运行环境SqlMapConfig.xml
log4j.properties日志文件配置如下:
### set log levels ### log4j.rootLogger = DEBUG,stdout ### stdout ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n
主要是配置数据源、事务等。数据库信息在db.properties中:
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/mybatis_learned?characterEncoding=utf-8
jdbc.username = root
jdbc.password = root
SqlMapConfig.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> <!--加载属性文件--> <properties resource="db.properties"></properties> <!--别名定义--> <typeAliases> <!--批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名--> <package name="com.zone.mybatis.entity"/> </typeAliases> <!--环境配置,连接的数据库,这里使用的是MySQL--> <environments default="mysql"> <environment id="mysql"> <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置--> <transactionManager type="JDBC"></transactionManager> <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments> <mappers> <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名, 如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml--> <!--<mapper resource="User.xml"></mapper>--> <!--批量加载mapper,指定mapper接口的包名,mybatis自动扫描mapper接口进行加载--> <package name="com.zone.mybatis.mapper"/> </mappers> </configuration>
3、使用mapper代理的方法开发dao接口
mapper代理开发规范:
1、mapper.xml中namespace就是mapper.java的类全路径。
2、mapper.xml中statement的id和mapper.java中方法名一致。
3、mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入参数类型一致
4、同3,resultType返回类型也要一致
这个小实例主要就是讲解mybatis基本的增删改查。有两种dao的开发方法,原始的dao开发方法即创建dao接口,创建实现类实现dao接口,现在基本上已经不用第一种方法了,因此这里直接使用第二种mapper代理的方法。
//User实体类,此处省略了get、set方法 public class User { private int id; private String name; private String sex; private Date birthday; private int iss;//这个属性只是为了测试所加上,和此对象没什么关系
UserMapper.java接口
public interface UserMapper { //插入用户,返回值不建议void,因为要得到“结果” public int insertUser(User user)throws Exception; //删除用户,返回值不建议void public int deleteUser(int id)throws Exception; //更新用户 public int updateUser(User user)throws Exception; //根据id查询用户 public User findUserById(int id) throws Exception; //多表查询,查询用户列表 public List<UserVo> findUserVo(int id)throws Exception; }
到这一步的时候是不是以为下一步就是编写.xml映射文件然后测试了?错了,要是不加以下代码,程序仍然要报错
<build> <!--使用maven遇到的坑!--> <!--如果不添加此节点,src/main/java目录下的UserMapper.xml会被漏掉,从而报错:invalid bound statement (not found)--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
新增用户:
UserMapper.xml
<!--获得刚才插入数据返回的主键id,以下两种方式--> <!-- 第一种方式:在insert标签中直接加上 keyProperty="id" useGeneratedKeys="true"--> <insert id="insertUser" parameterType="user" keyProperty="iss" useGeneratedKeys="true"> <!-- 第二种方式: 得到刚insert进去记录的主键值,只适用于自增主键 keyProperty:将查询到主键值设置到parameterType指定的对象的某个属性 order:执行顺序,相对于insert来说 resultType:SELECT LAST_INSERT_ID()结果类型 --> <!--<selectKey keyProperty="id" order="AFTER" resultType="int">--> <!--SELECT LAST_INSERT_ID()--> <!--</selectKey>--> INSERT INTO USER(NAME,SEX,birthday) VALUES(#{name},#{sex},#{birthday}) </insert>
test.java
先定义全局的SqlSessionFactory对象,并加上Junit的注解@Before,执行所有测试方法之前都执行一遍
private SqlSessionFactory sqlSessionFactory; //此方法在执行test方法之前执行 @Before public void setUp() throws Exception{ //创建sqlSessionFactory //mybatis配置文件 String resource="SqlMapConfig.xml"; //得到配置文件流 InputStream inputStream= Resources.getResourceAsStream(resource); //创建会话工厂 sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); }
@Test public void testInsertUser() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setName("Jam"); user.setSex("女"); user.setBirthday(new Date()); //int i=userMapper.insertUser(user);//若插入成功i=1,表示受影响的行数,若插入失败,返回exception,所以这里进行如下处理 int i=0; try { i=userMapper.insertUser(user); }catch (Exception e){ i=-1;//插入失败返回-1 } sqlSession.commit();//除了查询操作,其他都要commit(),提交 System.out.println("======="+i); System.out.println(user.getId()+"*******"+user.getIss());//获取刚才insert进去的数据返回的主键值 //这里之所以getId()=0,是因为userMapper.xml中将keyProperty设置="iss"了,所以getIss()=13; sqlSession.close(); }
运行截图:
删除用户:
UserMapper.xml
<delete id="deleteUser" parameterType="int"> DELETE FROM USER WHERE id=#{id} </delete>
test.java
@Test public void testDeleteUser() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); int i = userMapper.deleteUser(13);//删除成功返回1,删除失败返回0,而不是抛异常 sqlSession.commit(); System.out.println("--------"+i); sqlSession.close(); }
运行截图:
更新用户:
UserMapper.xml
<update id="updateUser" parameterType="user"> UPDATE USER <set> <if test="name!=null">name =#{name},</if> <if test="sex!=null">sex=#{sex},</if> <if test="birthday!=null">birthday=#{birthday}</if> </set> WHERE id=#{id} </update>
test.java
@Test public void testUpdateUser() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user=new User(); user.setId(10); user.setSex("女"); String time="2000-01-01"; SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd"); Date date=simpleDateFormat.parse(time);//字符串转日期 user.setBirthday(date); int i=userMapper.updateUser(user);//更新成功返回1,更新失败返回0 sqlSession.commit(); System.out.println("---------"+i); sqlSession.close(); }
运行截图:
查询用户:(根据ID查询某个用户,多表关联查询用户列表)
UserMapper.xml(除了前面的内容,剩下全部内容如下)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-mybatis.org/DTD config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址 --> <mapper namespace="com.zone.mybatis.mapper.UserMapper"> <select id="findUserById" parameterType="int" resultType="user"> SELECT * FROM USER WHERE id=#{value} </select> <!-- 这里遇到了一个问题,返回的 family_member_name 始终为空 原因在于UserVo字段名为familyMemberName,不对应! --> <resultMap id="UserVoMap" type="com.zone.mybatis.entity.UserVo"> <id column="id" property="id"/> <result column="family_member_name" property="familyMemberName"/> </resultMap> <select id="findUserVo" parameterType="int" resultMap="UserVoMap"> SELECT user.id,name,birthday,fm.family_member_name FROM user JOIN family_member fm WHERE user.id=fm.user_id AND user.id=#{id} </select> </mapper>
test.java
@Test public void testFindUserById() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1); System.out.println(user); sqlSession.close(); }
运行截图:
多表关联查询:
定义User的增强类,关联属性familyMemberName
public class UserVo extends User { private String familyMemberName; public String getFamilyMemberName() { return familyMemberName; } public void setFamilyMemberName(String familyMemberName) { this.familyMemberName = familyMemberName; } }
test.java
@Test
public void testFindUserVoById() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<UserVo> list=userMapper.findUserVo(1);
System.out.println(list.get(0).getFamilyMemberName());
sqlSession.close();
}
运行截图:
说明:部分借鉴传智播客的文档,感谢。
原创:https://blog.youkuaiyun.com/qq_37094660/article/details/96097537