持久层技术解决方案有几种?
1.JDBC技术–>Connection、PreparedStatement、ResultSet
2.Spring的JdbcTemplate–>Spring中对Jdbc的简单封装
3.Apache的DBUtils–>它和Spring的JdbcTemplate很像,也是对Jdbc的简单封装
以上这些都不是框架(JDBC是规范、Spring的JdbcTemplate和Apache的DBUtils都只是工具类)
mybatis持久层框架
mybatis是一个用Java编写的持久层框架,它使用ORM实现了结果集的封装。
跟hibernate一样,也是需要拥有两个配置文件,全局配置文件 和 映射文件,在编写这两个映射文件之前,必须创建mybatis环境(引入jar包或者maven工程导入坐标)
ORM是Object Relational Mapping 对象关系映射。简单来说,就是把数据库表和实体类及实体类的属性对应起来,让开发者操作实体类就实现操作数据库表。
它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等烦杂过程
测试用例搭建
搭建环境流程如下四点:
-
创建maven工程并导入坐标
<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.43</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>
-
创建实体类和Mapper的接口
public class User implements Serializable { private int id ; private String username; ...... }
public interface IUserMapper { /** * 查询所有操作 * @return */ List<User> findAll(); }
-
创建mybatis的主配置文件
<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/db1" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <mappers> <mapper resource="Mybatis/IuserMapper.xml" /> </mappers> </configuration>
-
创建映射配置文件
<mapper namespace="com.Mapper.IUserMapper" > <select id="findAll" resultType="com.Pojo.User" > select * from usr </select> </mapper>
测试方法
...... InputStream in = Resources.getResourceAsStream("mybatis/MapperConfig.xml"); //创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //使用工厂生产SqlSession对象 SqlSession session = factory.openSession(); //使用SqlSession创建Mapper接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); //使用代理对象执行方法 List<mybatis_user> users = userMapper.findAll(); for (mybatis_user muser : users){ System.out.println(muser); } session.close(); in.close(); ......
mybatis全局配置文件
mybatis的配置文件推荐为命名mybatis-config.xml,其内容包含了会深深影响mybatis行为的设置和属性信息。使用者掌握方面有properties、settings、typeAliases、enveronments、mappers;以下是全配置文件列表:
...
<!--配置-->
<configuration>
<!--属性-->
<properties></properties>
<!--全局参数设置-->
<settings></settings>
<!--类型别名-->
<typeAliases></typeAliases>
<!--类型处理器-->
<typeHandles></typeHandles>
<!--对象工厂-->
<objectFactory></objectFactory>
<!--插件-->
<plugins></plugins>
<!--环境信息集合:起步学习只需要关注一下此处配置-->
<environments>
<!--单个环境信息-->
<environment>
<!--事务-->
transactionManager
<!--数据源-->
dataSource
</environment>
</environments>
<!--数据库厂商标识-->
databaseIdProvider
<!--映射器-->
<mappers></mappers>
</configuration>
...
具体各个配置内容如下:
-
properties 标签
开发者可通过properties属性来实现引用配置文件。这些属性都是可外部配置且可动态替换的
[注]
1.如果两个配置文件有同一个字段,优先使用外部配置文件的
2.可以直接引入外部配置文件,properties子元素中可以增加一些属性配置 -
typeAliases 标签
typeAliases类型别名是为java类型设置一个短的名字,存在的意义仅在于用来减少类完全限定名的冗余。java内置内建类型别名它们都不区分大小写,注意对基本类型名称重复采用的特殊命名风格。
别名 映射的类型 _byte byte _long long _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer Integer Integer double Double float Float boolean Boolean date Date object Object map Map hashmap HashMap list List arraylist ArrayList [注]
方法二中,每一个在包中的Java bean,在没有注解的情况下,会使用bean的首字母小写的非限定类名来作为它的别名。若有注解,则别名为其注解值。(实体类上使用注解:@Alias(“user”)) -
setting 标签
setting设置标签,这是Mybatis中极为重要的调整设置,它们会改变Mybatis的运行时行为
-
environments标签
首先 看一段示例:
<!-- 配置mybatis的环境信息 --> <environments default="development"> <environment id="development"> <!-- 配置JDBC事务控制,由mybatis进行管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源,采用dbcp连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test_1?useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments>
dataSource子标签的type属性表达采用何种连接池方式, 在mybatis中连接池提供了3种方式的配置
我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间,①POOLED 方式:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。下图中观察出POOLED它是从池中获取一个连接来用
②UNPOOLED 方式:采用传统的获取连接的方式,虽然也实现javax.sql.DataSource接口,但是并没有使用连接池技术。下图中观察出UNPOOLED每次创建一个新的连接来用③JNDI 方式:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样的,如果不是web或者maven的war工程,是不能使用的。
-
mappers标签
mappers映射器属性,MapperRegistry:注册绑定我们的Mapper文件。有三种方式如下:
<mappers> <mapper resource="com/ferao/mapper/UserMapper.xml"/> </mappers>
<!--该方式绑定注册时,接口和它的Mapper配置文件必须同名,且它的Mapper配置文件必须在同一个包下--> <mappers> <mapper class="com.ferao.mapper.UserMapper" /> </mappers>
<!--该方式注入绑定时,接口和它的Mapper配置文件必须同名,且它的Mapper配置文件必须在同一个包下--> <mappers> <package name="com.ferao.mapper"></package> </mappers>
mybatis映射文件
传递参数的方式
在mapper中传递多个参数的方式有四种:顺序传递法、@Param注解传参法、Map传参法、Java Bean传参法;
方法1:顺序传参法
xxMapper.java
public User selectUser(String name, int deptId);
xxMapper.xml
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{0} and dept_id = #{1}
</select>
#{}里面的数字代表传入参数的顺序。这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。
方法2:@Param注解传参法
xxMapper.java
public User selectUser(@Param("userName") String name, int @Param("deptId") deptId);
xxMapper.xml
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是注解@Param括号里面修饰的名称。这种方法在参数不多的情况还是比较直观的,(推荐使用)。
方法3:Map传参法
xxMapper.java
public User selectUser(Map<String, Object> params);
xxMapper.xml
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是Map里面的key名称。这种方法适合传递多个参数,且参数易变能灵活传递的情况。
方法4:Java Bean传参法
xxMapper.java
public User selectUser(User user);
xxMapper.xml
<select id="selectUser" parameterType="com.jourwon.pojo.User" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是User类里面的成员属性。这种方法直观,需要建一个实体类,扩展不容易,需要加属性,但代码可读性强,业务逻辑处理方便,推荐使用。(推荐使用)。
parameterType(输入类型)
**Mapper.java 可向 **Mapper.xml中输入三种类型:
① 简单类型
② pojo对象类型
mybaits使用OGNL表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称
[注]OGNL表达式:object Graphic Navigation Language (对象图导航语言),它是通过对象的取值方法来获取数据。在写法上把gat给省略了。比如:我们获取用户的名称类中的写法:user.getUsername();
OGNL表达式写法:user.username
那么,mybatis中为什么能直接写username,而不用user呢?因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名
③ pojo包装对象
开发中通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他的查询条件(比如将用户购买商品消息也作为查询条件),这时可以使用包装对象传递输入pojo类参数中包含pojo
resultType(输出类型)
可输出的类型有四种:返回一般数据类型(单条)、JavaBean 类型(单条)、List类型(多条)、Map类型
① 一般数据类型(单条)
比如要根据Id属性获得数据库中的某个字段值,示例:
//**Mapper.java
String getStuNameById(Integer id);
<!--**Mapper.xml-->
<select id="getStuNameById" resultType="string">
select username from t_student where id = #{id}
</select>
② JavaBean 类型(单条)
比如根据某个字段获得数据库中的信息,把查询的结果信息封装成某个javaBean类型的数据,示例: