初次使用Mybatis
目录
mybatis简介
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。——摘抄自mybatis官网
导入jar包
需要导入两个最基本的jar包,分别是mybatis的jar包,以及数据库驱动包。
mysql-connector-java-5.1.39-bin.jar mybatis-3.2.7.jar
如果要记录日志,还需要导入日志包,比如log4j..
创建数据库以及数据库表
创建测试专用库mybatis,并创建一个Person表:
CREATE DATABASE mybatis; USE mybatis; CREATE TABLE `person` ( `id` int(11) primary key auto_increment, `name` varchar(30) DEFAULT NULL, `age` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO person VALUES (1, 'aaaa', 88);
创建实体类
为了演示方便,这里创建一个Person类,类名和数据库中的person表名对应,并且Person类中的属性名和person表中的字段名相同(一一对应)。
实体类都在cn.ganlixin.pojo包下面:
package cn.ganlixin.pojo; import java.io.Serializable; public class Person implements Serializable{ private int id; private String name; private int age; public Person() { } public Person(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } }
创建mapper.xml文件
前面的介绍中已经说了:MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
所以此时我们需要创建一个mapper文件,文件名规范:实体类名+Mapper.xml,当然也可以命名为其他规范。
上面的Person类,对应的mapper文件是PersonMapper.xml,位于cn.ganlixin.mapper包下面。
<?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.ganlixin.mapper.PersonMapper"> <select id="selectPersonById" parameterType="int" resultType="cn.ganlixin.pojo.Person"> select * from person where id=#{id} </select> </mapper>
介绍一下上面的xml内容:
1、第一部分是dtd声明,不加的话,写xml标签的时候没有提示。
2、每个mapper映射文件,顶级标签都是mapper,namespace的规范是packageName.ClassName。
3、select标签表示这是一个查询操作,另外还有insert、update、delete标签。
id属性,可以理解为方法名,通过namespace.id可以调用这个id的方法,执行标签定义的sql。
parameterType属性,表示传入的参数类型,关于参数类型设置,可以参考:
resultType属性,表示结果集中每一行记录的类型,注意,如果没有配置别名<alias>,需要使用全路径。
sql中的#{id}表示接受参数名为id的值。
配置mybatis
实体类和映射文件已经写好之后,当我们运行测试代码的时候,mybatis会运用反射,扫描映射文件,并解析映射文件,让映射文件和实体类之间产生联系,所以现在应该配置mybatis了。
创建一个xml文件,文件名随意,文件可以放在项目的根目录下,也可以放专门存放配置文件的目录下,这里将配置文件命名为mybatis.xml,并且放在projectRoot/src/conf目录下。
配置mybatis无非就两点:
1、配置数据库连接信息
2、配置mybatis要扫描哪些映射文件。
<?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> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </dataSource> </environment> </environments> <mappers> <mapper resource="cn/ganlixin/mapper/PersonMapper.xml"></mapper> </mappers> </configuration>
解释一下上面的mybatis的配置文件:
1、首先是dtd,注意配置文件的dtd和映射文件的dtd不同。
2、configuration标签内容就是配置mybatis。
3、environments标签下面可以有多个environment,每一个environment就是一套数据库配置,并且每一个environment都用一个id来标识自己。environments标签使用default来配置哪一个environment配置有效。
4、transactionManager的type属性配置事务管理的类型,有两种:
i、一种是JDBC,使用JDBC原生的事务控制管理,JDBC默认没有开启事务(会自动提交),但是mybatis会将JDBC的事务自动开启,即不会自动提交。
ii、另一种是MANAGED,使用Spring的时候就是设置为MANAGED。
5、dataSource标签内容就是配置数据库连接信息。其中dataSource的type可以设置为POOLED、UNPOOLED、JNDI。
6、mappers标签就是针对上面写的映射文件,只有在这里面使用mapper标签指定的映射文件才会被扫描。
测试mybatis
package cn.ganlixin.test; import java.io.IOException; import java.io.InputStream; 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 cn.ganlixin.pojo.Person; public class TestMybatis { public static void main(String[] args) { try { // 加載mybatis配置文件 String resource = "conf/mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // 利用配置文件,创建sqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 利用sqlSessionFactory来获取数据库连接 SqlSession session = sqlSessionFactory.openSession(); // 指定要调用的方法(映射文件中的namespace加上包含SQl语句的标签的id。 String method = "cn.ganlixin.mapper.PersonMapper.selectPersonById"; // 调用方法 Person p = (Person) session.selectOne(method, 1); System.out.println(p); // 断开数据库连接 session.close(); } catch (IOException e) { e.printStackTrace(); } } }
三种查询方式
mybatis提供了三种方式来获取结果集的格式:
1、selectOne用来获取sql语句执行完毕后得到单一的值;
2、selectList用来获取sql语句执行完毕后的到一个List结果集,多条记录。
3、selectMap用来获取sql执行之后,某一个字段为key,每一条记录为value,put到一个map中。
在测试selectList和selectMap之前,先修改一下PersonMapper.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="cn.ganlixin.mapper.PersonMapper"> <select id="selectPersonById" parameterType="int" resultType="cn.ganlixin.pojo.Person"> select * from person where id=#{id} </select> <select id="selectAllPerson" parameterType="int" resultType="cn.ganlixin.pojo.Person"> select * from person </select> </mapper>
selectOne
selectOne的用法上面已经展示了,就不在重复说了。
selectList
package cn.ganlixin.test; import java.io.IOException; import java.io.InputStream; import java.util.List; 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 cn.ganlixin.pojo.Person; public class TestMybatis { public static void main(String[] args) { try { String resource = "conf/mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); // 注意selectList要使用List来接收,可以直接指定泛型 String method = "cn.ganlixin.mapper.PersonMapper.selectAllPerson"; List<Person> list = session.selectList(method); for (Person p : list) { System.out.println(p); } session.close(); } catch (IOException e) { e.printStackTrace(); } } }
selectMap
package cn.ganlixin.test; import java.io.IOException; import java.io.InputStream; import java.util.Map; 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 cn.ganlixin.pojo.Person; import jdk.management.resource.internal.inst.SocketOutputStreamRMHooks; public class TestMybatis { public static void main(String[] args) { try { String resource = "conf/mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); // 注意selectMap需要指定第二个参数,表示使用每一条记录中的那个属性(字段)作为map的key String method = "cn.ganlixin.mapper.PersonMapper.selectAllPerson"; Map<String, Person> map = session.selectMap(method, "name"); for (String name : map.keySet()) { System.out.println(name + " ==> " + map.get(name)); } //aaaa ==> Person [id=1, name=aaaa, age=88] //bbbb ==> Person [id=2, name=bbbb, age=99] session.close(); } catch (IOException e) { e.printStackTrace(); } } }