使用原始dao层进行开发

UserMapper层接口

public interface UserMapper {
/**
* 通过id查询用户
* @param id
* @return
*/
User queryUserById(Integer id);
}

UserMapper层的实现类

public class UserMapperImpl implements UserMapper{

    private SqlSessionFactory sqlSessionFactory;
//使用构造方法进行注入sqlSessionFactory
public UserMapperImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
} /**
* 通过id查询用户
*
* @param id
* @return
*/
@Override
public User queryUserById(Integer id) { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = (User)sqlSession.selectOne("test.queryUserById", 2); return user;
}
}

测试类

 */
public class DaoTest {
@Test()
public void daoTest() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
UserMapperImpl userMapper = new UserMapperImpl(sqlSessionFactory);
User user = userMapper.queryUserById(2);
System.out.println(user);
}
}

最后的结果为:

使用动态代理进行开发.

定义一个Mapper接口,这个接口其实和我们UserDao接口是一样的,从Mybatis框架中拿到一个代理对象(代理的是这个Mapper接口),通过代理对象调用接口当中的方法完成业务.

 传统dao开发方式中的实现类其实起了一个连接,承上启下的作用,连接了接口和xml映射文件,效果就是调用接口中方法时能够找到xml映射文件.

Mapper动态代理开发遵从的规范:

      1.sql映射文件的namespace必须和mapper接口的全限定类名保持一致

      2.mapper接口的接口方法名必须和xml中的sql语句id保持一致.

      3.mapper接口的接口方法形参类型必须和sql语句的输入参数类型保持一致

      4.mapper接口的接口方法返回类型必须和sql语句的resultType保持一致

UserMapper接口

public interface UserMapper {
User queryUserById(Integer id);
}

UserMapper.xml配置文件

<!-- namespace属性值=接口全限定名-->
<mapper namespace="com.itheima.mapper.UserMapper">
<!-- id属性值=方法名-->
<select id="queryUserById" parameterType="Integer" resultType="com.itheima.pojo.User">
select * from user where id=#{id}
</select>
</mapper>

测试类

@Test
public void userMapper() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(2);
System.out.println(user);
}

总结:关于使用动态代理,就是将不用通过

UserMapperImpl userMapper = new UserMapperImpl(sqlSessionFactory);这个方法获取到UserMapper对象,然后再操作里面的方法,
而是通过
UserMapper mapper = sqlSession.getMapper(UserMapper.class);这个方法获取到动态代理对象,间接的操作这个类里面的方法.
然后达到目的.

全局properties的配置

重新创建一个db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.user=root
jdbc.password=root

将这个文件引入到SqlMapperConfig.xml中

<properties resource="db.properties"></properties>

然后修改SqlMapperConfig.xml文件

       <dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>

<typeAliases>
<!-- 为pojo对象定义别名-->
<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>
</typeAliases>
<!-- 使用别名即可-->
<select id="queryUserById" parameterType="int" resultType="User">
select * from user where id=#{id}
</select>

扫描所有pojo包下的类。注意:不可以出现相同的类名

<typeAliases>
<!--<typeAlias type="com.itheima.pojo.User" alias="user"></typeAlias>-->
<!-- 自动扫描pojo包下的全部类-->
<package name="com.itheima.pojo" ></package>
</typeAliases>

全局配置文件mappers

mappers注册sql映射文件的

  • resource属性加载sql映射文件,万能型选手(crud、原始dao、mapper动态代理)

  • 针对Mapper动态代理进行一个增强(增强两种用法)

  • mapper class 单个注册

  • package 批量扫描注册

  • 以上两种方式有规范要求

<mappers>
<mapper resource="sqlmapper/UserMapper.xml" />
<mapper resource="mapper/UserMapper.xml" />
<mapper class="com.itheima.mapper.UserMapper"></mapper>
<package name="com.itheima.mapper"></package>
</mappers>

MyBatis输入参数类型

parameterType(输入参数类型)

1.传递简单类型

2.传递Pojo对象

3.传递Pojo包装对象

QueryVO类

public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

UserMapper接口

public interface UserMapper {
User queryUserById(Integer id);
List<User> queryUserByQueryVo(QueryVo queryVo);
}

UserMapper接口类  传入的参数为queryVO,然后查询时候,需要使用User类中的username通过#{user.username}获取

<select id="queryUserByQueryVo" resultType="user" parameterType="queryvo">
select * from user where username like #{user.username}
</select>

Test测试类

@Test
public void userMapperQueryVo(){
// 获取到工厂建造者对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 通过本类加载器获取到一个流对象,这个流对象用来读取SqlMapperConfig.xml文件
InputStream inputStream = SqlMapperTest.class.getClassLoader().getResourceAsStream("sqlMapperConfig.xml");
// 创建工厂对象
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取到映射对象,getMapper("实现类",接口.class)
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
User user = new User();
//将要查询的东西,封装在user类中
user.setUsername("%王%");
queryVo.setUser(user);
List<User> list = mapper.queryUserByQueryVo(queryVo);
for(User u :list){
System.out.println(u);
}
sqlSession.close();
}

MyBatis的手动映射

当数据库中的列名和domain类中的属性名,不能对应上的时候,就会出现封装数据失败,mybatis无法将数据表中数据准确的封装到domain对象中,因此必须使用手动映射方式,

domain类

private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;

Mapper接口

public interface OrdersMapper {
List<Orders> queryOrders();
}

xml配置文件

<mapper namespace="com.itheima.mapper.OrdersMapper">
<select id="queryOrders" resultMap="order">
select * from orders
</select>
<!-- id属性值=resultMap属性值-->
<resultMap id="order" type="com.itheima.pojo.Orders">
<!-- 配置pojo对象红的属性名和数据表列名的对应关系 -->
<id property="id" column="id"></id>
<result property="userId" column="user_id"></result> //property 为domian中的属性名,column为数据库中的列名
<result property="number" column="number"></result>
<result property="createtime" column="createtime"></result>
<result property="note" column="note"></result> </resultMap>
</mapper>

Test测试类

@Test
public void ordersMapper(){
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> list = ordersMapper.queryOrders();
for(Orders orders : list){
System.out.println(orders);
}
sqlSession.close();
}

 MyBatis连接池

在Mybatis的配置文件中,这个位置配置了数据源,,也就是使用了连接池.

那么连接池是在什么时候建立的,什么时候从连接池中获取连接的.

连接池初始化的时机:

在SqlSessionFactoryBuilder构建SqlSessionFactory的时候初始化的连接池,初始化之后,放入Configuration对象中,分析框架的源代码:

org.apache.ibatis.builder.xml.XMLConfigBuilder类的方法environmentsElement()

什么时候从连接池中获取连接

在getMapper的时候是不会从数据库连接池中获取数据库连接的,在具体操作数据库调用mapper接口方法的时候才会从连接池拿连接.

UNPOOLED:不适用数据库连接池(一般情况下不使用)

JNDI:(前提是你的Mybatis环境必须是Web应用)

什么是JNDI?

JNDI:java naming directory interface(java命名目录接口,它是一种服务发布技术),数据源可以以服务的形式发布出去,那么哪个应用想用,就类似于客户端调用远程服务一样去调用即可.

为什么必须是wen应用?

往往只有tomcat./weblogic服务中间件才支持JNDI技术.

如果Mybatis当中用,怎么用?

第一步:在数据库驱动程序(jar包)放到tomcat安装目录下的lib文件夹下.

第二步:在Tomcat的conf/context.xml文件中进行jndi数据源服务配置

<Resource name="jndi/mybatis" auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mybatis?
characterEncoding=utf8"
  username="root" password="root"
maxActive="20"
maxIdle="10"
maxWait="10000">
</Resource>

name:在JNDI中叫做目录名,等同于服务名,此处的jndi/mybatis是自定义的,往往以/连接前后字符串即可。auth和type是固定的,其他都是数据库连接池的具体配置信息。

第三步 :在自己web项目的web.xml中引用Jndi数据源服务。

<resource-ref>
<res-ref-name>jndi/mybatis</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
 </resource-ref>

第四步:在自己web项目的Mybatis配置文件中使用

<property name="data_source"
value="java:comp/env/jndi/mybatis"/>

配置data_source属性,指向你的数据源引用,java:comp/env/jndi/mybatis中红色部分是固定的,绿色部分是你自己定义的目录名(服务名)。
MyBatis事务控制

通过sqlSession.openSession这种方法操作数据库时候,mybatis默认把事务自动提交给关闭了,注意:数据量非常小可以自动提交,数据量大就应该手动提交。自动提交在openSession
方法中传入参数true: SqlSession sqlSession = sqlSessionFactory.openSession(true)
动态SQL标签

where和if标签

需求:根据用户的性别和用户名多条件查询用户信息

<select id="queryUserByWhere" resultType="user" parameterType="user">
 select * from user where sex=#{sex} and username like #{username}
</select>
@Test
public void queryUserByWhere(){
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  User user = new User();
  user.setSex("2");
  user.setUsername("%王%");
  List<User> list = mapper.queryUserByWhere(user);
  if(list!=null && list.size()>0){
    for(User user1 : list){
      System.out.println(user1);
   }
 }
}

以上查询是可以查询到相关的数据的,假定不传递sex的值,那么就会出现什么也差不到的结果?

通过日志可以看出,MyBatis在执行SQL语句的时候,参数sex的值是null,因此没有查询到结果。在以往的做法是判断参数是否为空,并进行字符串的拼接。在MyBatis框架中,提供了where标签和if标签来实现动态SQL语句。
where标签:处理SQL语句,自动添加where关键字,并去掉紧跟他后面的一个and或者or

if标签:test属性,判断表达式真假

<select id="queryUserByWhere" resultType="user"
parameterType="user">
 select * from user
 <where>
   <if test="sex!=''and sex!=null">
    and sex=#{sex}
   </if>
   <if test="username!=''and username!=null">
    and username like #{username}
   </if>
 </where>
</select>

SQL标签

将SQL语句抽取,其他SQL语句中引入

<!--
 SQL片段抽取
 使用include标签引入
-->
<sql id="commonsSql">
 id,username,sex,birthday,address
</sql>

引入外部xml配置文件中的共享SQL片段时,使用namespace属性值+“.”+sql标签的id属性值。

foreach标签传入集合

删除多条数据的SQL语句,delete from user where id in(1,2,3)

String sql = "delete from user where id in("
for(int i=0; i<list.size();i++) {
if(i != list.size()-1)
sql += list.get(i) + ","
else
 sql += list.get(i)+")"
}

foreach标签遍历拼接SQL语句

  collection属性:遍历传入的集合,当参数是集合时collection属性值固定为list

  open属性:遍历拼接前
  close属性:遍历拼接后
  separator属性:拼接的符号
  item属性:遍历到的元素

<select id="queryUserByIdsList" parameterType="list"
resultType="user">
  select * from user
   <foreach collection="list" open="where id in(" close=")"
separator="," item="item">
    #{item}
   </foreach>
 </select>
@Test
public void queryUserByIdsList(){
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  List<Integer> idsList = new ArrayList<Integer>();
  idsList.add(1);
  idsList.add(2);
  idsList.add(3);
  List<User> list = mapper.queryUserByIdsList(idsList);
  if(list!=null && list.size()>0){
    for (User user : list){
      System.out.println(user);
   }
 }
  sqlSession.close();
}

foreach标签传入数组

foreach标签遍历拼接SQL语句
  collection属性:遍历传入的集合,当参数是数组时collection属性值固定为array
  open属性:遍历拼接前
  close属性:遍历拼接后
  separator属性:拼接的符号
  item属性:遍历到的元素

<select id="queryUserByIdsArray" parameterType="int[]"
resultType="user">
 select * from user
 <foreach collection="array" open="where id in(" close=")"
separator="," item="item">
  #{item}
 </foreach>
@Test
public void queryUserByIdsArray(){
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  int[] idsArray= {1,2,3};
  List<User> list = mapper.queryUserByIdsArray(idsArray);
  if(list!=null && list.size()>0){
    for (User user : list){
      System.out.println(user);
   }
 }
  sqlSession.close();
}

foreach标签传入pojo对象

foreach标签遍历拼接SQL语句
  collection属性:遍历传入的pojo对象中的集合,collection属性配置pojo中成员变量名
  open属性:遍历拼接前
  close属性:遍历拼接后
  separator属性:拼接的符号
  item属性:遍历到的元素

public class QueryVo {
  private List<Integer> idsList;
  public List<Integer> getIdsList() {
    return idsList;
 }
  public void setIdsList(List<Integer> idsList) {
    this.idsList = idsList;
 }
}
<select id="queryUserByQueryVo" parameterType="queryVo"
resultType="user">
 select * from user
 <foreach collection="idsList" open="where id in(" close=")"
separator="," item="item">
  #{item}
 </foreach>
</select>
@Test
public void queryUserByQueryVo(){
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
  QueryVo queryVo = new QueryVo();
  List<Integer> idsList = new ArrayList<Integer>();
  idsList.add(1);
  idsList.add(2);
  idsList.add(3);
  queryVo.setIdsList(idsList);
  List<User> list = mapper.queryUserByQueryVo(queryVo);
  if(list!=null && list.size()>0){
    for (User user : list){
      System.out.println(user);
   }
 }
  sqlSession.close();
}

MyBatis框架之入门(三)的更多相关文章

  1. Mybatis框架基础入门(三)--Mapper动态代理方式开发

    使用MyBatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper动态代理开发方法. 原始Dao开发方法需要程序员编写Dao接口和Dao实现类,此方式开发Dao,存在以下问题: Dao方 ...

  2. (转)MyBatis框架的学习(三)——Dao层开发方法

    http://blog.csdn.net/yerenyuan_pku/article/details/71700957 使用MyBatis开发Dao层,通常有两个方法,即原始Dao开发方法和Mappe ...

  3. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试

    这一部分的主要目的是 配置spring-service.xml  也就是配置spring  并测试service层 是否配置成功 用IntelliJ IDEA 开发Spring+SpringMVC+M ...

  4. myBatis框架之入门(一)

    什么是框架 框架就是一个架子,表演节目,舞台已经搭建好,表演什么节目,看自己的需求了. 框架是一个半成品,对于Java语言来说,框架就是封装了别人的代码.在框架的基础上我们在进一步开发,拿来主义. 框 ...

  5. MyBatis框架——快速入门

    主流的ORM框架(帮助开发者实现数据持久化工作的框架): 1.MyBatis: 半自动化ORM框架,半自动:指框架只完成一部分功能,剩下的工作仍需开发者手动完成. MyBatis 框架没有实现 POJ ...

  6. myBatis框架之入门(四)

    Mybatis多表管理查询 多表关联关系分析: 多表关联:至少两个表关联.分析多表关系的经验技巧:从一条记录出发,不要从表整体去分析,比如分析A表和B表关系,A表中的一条记录对应B表中的几条记录,如果 ...

  7. MyBatis框架之第三篇

    8.Spring与Mybatis整合 框架的整合就是软件之间的集成,它很抽象,因此在做整合之前先想好思路.规划好思路然后按照思路一步一步的做就可以实现框架的整合. 8.1.SM整合思路 8.1.1.思 ...

  8. mybatis框架快速入门

    通过快速入门示例,我们发现使用mybatis 是非常容易的一件事情,因为只需要编写 Dao 接口并且按照 mybatis要求编写两个配置文件,就可以实现功能.远比我们之前的jdbc方便多了.(我们使用 ...

  9. Mybatis框架七:三种方式整合Spring

    需要的jar包: 新建lib文件夹放入jar包,Build Path-->Add To Build Path之后: 原始Dao开发示例: src下:新建核心配置文件sqlMapConfig.xm ...

随机推荐

  1. 基于32位Windows2003的数据库服务器优化,启用AWE,优化SQL Server

    最近几天,笔者所在的单位中的一台WEB服务器由于负载过大出现了问题,当同时在线的用户达到一定规模(2000-3000)时,频繁出现页面响应迟缓.超时等问题.服务器采用的操作系统是Windows Ser ...

  2. A Philosophy of Software Design

    关于复杂性,尚无统一的定义,从不同的角度可以给出不同的答案.可以用数量来度量,比如芯片集成的电子器件越多越复杂(不一定对):按层次性[2]度量,复杂度在于层次的递归性和不可分解性.在信息论中,使用熵来 ...

  3. struts2.xml 中result type属性说明

    chain           用来处理Action链,被跳转的action中仍能获取上个页面的值,如request信息.           com.opensymphony.xwork2.Acti ...

  4. HDFS命令行及JAVA API操作

    查看进程 jps 访问hdfs: hadoop-root:50070 hdfs bash命令: hdfs dfs <1>   -help:  显示命令的帮助的信息 <2>  - ...

  5. python抓取每期双色球中奖号码,用于分析

    获取每期双色球中奖号码,便于观察,话不多说,代码如下 # -*- coding:utf-8 -*- # __author__ :kusy # __content__:获取每期双色球中奖号码 # __d ...

  6. element-ui时间选择器--设置禁止选择的时间

    场景需求:开始日期不能小于今天,在今天之前的日期禁止选择,结束日期不能小于开始日期,开始日期之前的日期禁止选择. 效果图: element-ui的时间选择器中,有一个picker-options的属性 ...

  7. Linux crond任务调度(定时任务),Linux磁盘分区/挂载

    一.crond任务调度 1.基本语法 crontab [选项] -e : 编辑 crontab定时任务 -l : 查询crontab -r : 删除当前用户所有的crontab任务 例子: 每分钟执行 ...

  8. async与await总结

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/11533174.html,多谢,=.=~ 抛出3个疑问: 1.async是干哈的? 2.await ...

  9. JavaScript由来

    在互联网时代,网速还很差劲的时候,表单输入数据的合法性验证需要与服务器交换数据,从而加重了使用者的负担. 网景公司为了解决这种简单问题开发了JavaScript.在1995年2月网景公司在发布自己的浏 ...

  10. (原创)如何搭建PLC+上位机监控系统达到成本的最小化?

    以西门子PLC举例; 西门子PLC有几个型号:S7-200SMART,S7-1200,S7-300,S7-400,S7-1500,价格从低到高. 1个项目中要求的IO数量:600点的DI+DO,若干个 ...