工具类
MyBatis进行数据库查询一定会用到SqlSessionFactory和SqlSession这两个类的对象,为了以后每次查询方便,就先构造有一个工具类,用来管理这两个对象:
【SqlSessionFactory的对象是重量级的,而SqlSession是轻量级的】
以下是工具类:
package com.hgd; 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 java.io.IOException; import java.io.InputStream; /* * Mybatis工具类 * 创建SqlSessionFactory对象以及获取SqlSession对象 * */ public class MyBatisUtils { private static SqlSessionFactory factory = null; static{ InputStream is = null; String config = "mybatis-config.xml"; try{ is = Resources.getResourceAsStream(config); SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(is); factory = sessionFactory; }catch (IOException e){ e.printStackTrace(); }finally{ if(is!=null) try{ is.close(); }catch (IOException e){ e.printStackTrace(); } } } /* * @param autoCommit 设置是否为自动提交 * */ public static SqlSession getSession(boolean autoCommit){ return factory.openSession(autoCommit); } }
mybatis-config.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> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="123"/> </properties> <!--设置--> <settings> <!--显示SQL语句,以便于调试--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--映射文件--> <mappers> <mapper resource="com/hgd/userMapper.xml"/> <mapper resource="com/hgd/employeeMapper.xml"/> <mapper resource="com/hgd/mapper.xml"/> </mappers> </configuration>
需要查询的数据库中的user表结构:
实体类User【普通JavaBean】
package com.hgd; public class User { private Integer id; private String username; private String password; private String email; public User(){} public User(Integer id,String username,String password,String email){ setId(id); setUsername(username); setPassword(password); setEmail(email); System.out.println("UserCreated"); } public Integer getId() { return id; } public String getUsername() { return username; } public String getPassword() { return password; } public String getEmail() { return email; } public void setId(Integer id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + '}'; } }
1.利用默认SqlSession中的方法,进行查询
(1)根据id,查询某个User的全部字段:
①新建一个映射配置文件【userMapper.xml】
<mapper namespace="${NAMESPACE}" > <!--resultMap 结果映射--> <select id="selectByID" parameterType="int" resultType="com.hgd.User"> select id,username,password,email from user where id = #{id}; </select> </mapper>
【注:实体类User里面的字段和数据库里面的列名是一样的,所以就不用再去配置resultMap了;
如果不一样的话可以
Ⅰ使用别名,比如select e_id as id 这种,别名和实体类属性一致
Ⅱ再配置一个resultMap,里面配置清楚property和column的联系。
这里估计是MyBatis反射调用User类中的setter方法设置属性值的】
②然后在Mybatis主配置文件中引用这个文件,像这样:
③然后就可以在Java代码中进行查询操作了:
这里用到了SqlSession的一个方法,selectOne(String id,Object o);
这里的id就是你在userMapper.xml中配置的select节点的id,Object就是你传入的参数
运行结果:
【其余的输出均为设置的<setting name="logImpl" value="STDOUT_LOGGING"/>输出的内容】:
(2)查询一组User,返回List<User>这样的返回值:
这个时候就需要用到select子节点中的resultMap属性了【这个属性的意思是,结果映射,与Java中的Map关系不是很大】
①在映射文件中[userMapper.xml]配置一个结果集映射,这里MyBatis是反射调用User的构造方法来创建的对象(猜测
<resultMap id="constructedUser" type="com.hgd.User"> <!--利用构造方法构造对象,参数顺序为构造方法中的顺序[3.4.3+可任意顺序]--> <constructor> <idArg column="id" javaType="int"/> <arg column="username" javaType="String" /> <arg column="password" javaType="String"/> <arg column="email" javaType="String"/> </constructor> </resultMap>
②配置一个select,注意这里是resultMap,然后这个属性要引用上面配置的resultMap的id
<select id="Users" resultMap="constructedUser"> select * from user </select>
③写个测试
@Test public void testMyBatis(){ SqlSession s = MyBatisUtils.getSession(true); List<User> u = s.selectList("Users"); System.out.println(u); s.close(); }
输出结果:
2.自定义接口,由Mybatis代理查询(抱歉,不是很懂
(1)先新建一个接口[UserMapper],这里会有一系列查询操作的模板方法:
第一个方法查询所有的User,第二个方法根据传入的ID查找指定的一个User
public interface UserMapper { ArrayList<User> getUsers(); User getUserById(Integer id); }
(2)为这个接口配置查询语句,新建一个配置文件mapper.xml,注意这个时候的namespace应该为这个接口的全类名(好像又看到了反射的影子)
【这里的select的id应该与接口中的函数名一致】
可以理解为 为接口中的每一个函数配置一个对应的<select></select>
<?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="com.hgd.UserMapper"> <select id="getUsers" resultMap="userList"> select * from user; </select> <resultMap id="userList" type="com.hgd.User"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="password" column="password"/> <result property="email" column="email"/> </resultMap> <select id="getUserById" parameterType="int" resultType="com.hgd.User"> select id,username,password,email from user where id=#{id} </select> </mapper>
(3)在MyBatis全局配置文件中将这个配置文件mapper.xml包含进去
(4)写个测试:
@Test public void testMyBatis(){ SqlSession s = MyBatisUtils.getSession(true); UserMapper mapper = s.getMapper(UserMapper.class); User u = mapper.getUserById(5); List<User> list = mapper.getUsers(); System.out.println("id为5的用户:"+u); System.out.println("所有的用户列表:"+list); }
SqlSession.getMapper(Class clazz);这里可能用了代理
输出结果:
【SELECT】
在select子节点中,可以有下面的一些属性:
<select
id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10000" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。 |
parameterType | 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。 |
resultType | 从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。 |
resultMap | 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。 |
flushCache | 将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false。 |
useCache | 将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。 |
fetchSize | 这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。 |
databaseId | 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。 |
resultOrdered | 这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。 |
resultSets | 这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。 |
--------表格来自MyBatis官方中文网站:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html
常用的几个属性一般有resultType,resultMap,parameterType等