什么是Mybatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
首先新建一个Maven工程项目,在pom.xml文件中加入依赖
<?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.junko</groupId> <artifactId>eesy_mybatis</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</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.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project> 复制代码
在实际使用中,只要导入mybatis和mysql坐标就能够正常使用了,log4j与junit分别是日志与单元测试。
Java程序操作是基于实体类的,而在操作数据库的时候,是基于Dao的,于是我们需要新建
main/java/cn/junko/domain
注意:这里的属性名与我之前建好的User表的名字是一致的
package cn.junko.domain; import java.util.Date; public class User implements Serializable{ private Integer id; private String username; private String sex; private String address; private Date birthday; /* 这里生成各种setter和getter方法,以及toString */ } 复制代码
main/java/cn/junko/dao
package cn.junko.Dao; import cn.junko.domain.User; import java.util.List; public interface UserDao { /** * 查询所有User表所有 * @return */ List<User> findAll(); } 复制代码
在项目resources目录下新建一个xml文件,命名没有规范,自己能辨识出来就行 resources/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> <!--配置环境--> <environments default="mysql"> <!--配置mysql环境--> <environment id="mysql"> <!--配置事务类型--> <transactionManager type="JDBC"></transactionManager> <!--配置连接池--> <dataSource type="POOLED"> <!--连接数据库的四个基本信息--> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/eesy"/> <property name="username" value="root"/> <property name="password" value="12345678"/> </dataSource> </environment> </environments> <!--指定映射配置文件的位置,每个dao独立的配置文件--> <mappers> <mapper resource="cn.junko.dao.UserDao.xml"></mapper> </mappers> </configuration> 复制代码
因为我们目前只需要操作User表,因此在resources再新建一个针对UserDao的xml配置文件
需要注意的是,这个xml文件的路径需要对应主配置文件mappers下的路径 resources/cn/junko/dao/UserDao
<?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.junko.dao.UserDao"> <select id="findAll"> select * from user; </select> </mapper> 复制代码
id对应的是Dao接口的方法名 findAll
,mapper标签的namespace则为Dao接口的全限定类名
环境配置完成,接下来可以去test里面测试一下是否可以实现
public class MyBatisTest { public static void main(String[] args) throws Exception { //1.读取配置文件 InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in); //3.使用工厂生产SqlSession对象 SqlSession session=factory.openSession(); //4.使用SqlSession创建Dao接口的代理对象(动态代理) UserDao userDao=session.getMapper(UserDao.class); //5.使用代理对象执行方法 List<User> users = userDao.findAll(); for (User user : users) { System.out.println(user); } //6.释放资源 session.close(); in.close(); } 复制代码
结果正常查询出来,控制台显示表中数据
为了测试方便,我们进行单元测试的方法,把一些重复的操作抽离出来
private InputStream in; private SqlSession sqlSession; private UserDao userDao; @Before public void init() throws Exception{ in=Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in); sqlSession=factory.openSession(); userDao =sqlSession.getMapper(UserDao.class); } @After public void destroy() throws Exception{ sqlSession.close(); in.close(); } 复制代码
同样,先从UserDao里面添加方法,在UserDao.xml里面加入对应的标签,最后在测试类里面运行
Mybatis的事务默认是开启的,需要我们手动去提交事务 sqlSession.commit();
或者 sqlSession=factory.openSession(true);
parameterType:参数的类型。
<insert id="saveUser" parameterType="cn.junko.domain.User"> insert into user(username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday}); </insert> <update id="updateUser" parameterType="cn.junko.domain.User"> update user set username=#{username},address=#{address},sex=#{sex} where id=#{id}; </update> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id = #{id}; </delete> 复制代码
测试类
@Test public void testSave(){ User user=new User(); user.setUsername("junko"); user.setSex("男"); user.setAddress("深圳"); user.setBirthday(new Date()); userDao.saveUser(user); //提交事务 sqlSession.commit(); } @Test public void testUpdate(){ User user=new User(); user.setId(52); user.setUsername("fuwafuwa"); user.setSex("女"); user.setAddress("云南"); user.setBirthday(new Date()); userDao.updateUser(user); //提交事务 sqlSession.commit(); } @Test public void testDelete(){ userDao.deleteUser(52); sqlSession.commit(); } 复制代码
一个小细节,在执行完插入操作后,由于表中数据的ID是自增长,我们能否获取到插入数据的ID值?这就需要在insert标签中添加一个操作,这样在执行完插入语句之后,在控制台打印对象,会显示ID值
<insert id="saveUser" parameterType="cn.junko.domain.User"> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id(); </selectKey> insert into user(username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday}); </insert> 复制代码
1.修改xml中的sql语句,使用起别名的方式与实体类的名字对应 select id as uid ······
2.使用resultMap
<resultMap id="userMap" type="cn.junko.domain.User"> <!--主键字段对应--> <id property="userId" column="id"></id> <!--非主键字段对应--> <result property="userName" column="username"></result> <result property="userSex" column="sex"></result> </resultMap> 复制代码
标签引用的地方需要作出修改,不再使用resultType
resulMap="userMap"