大纲摘要:

    1、mybatis的介绍

    2、Mybatis的入门

      a) 使用jdbc操作数据库存在的问题

      b) Mybatis的架构

      c) Mybatis的入门程序

    3、Dao的开发方法

      a) 原始dao的开发方法——由ibatis遗留下来的

      b) mapper动态代理方式

    4、SqlMapConfig.xml文件说明

一、mybatis概述 

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。

  2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身

  而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

    Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,

  并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    是一个不完全的orm框架

  根据经典的凡技术必登其官网的结论,官网文档很有必要参阅http://www.mybatis.org/mybatis-3/zh/index.html

二、mybatis入门

【更新】 问题总结

    1、 在创建连接时,存在硬编码

      配置文件(全局配置文件)

    2、 在执行statement时存在硬编码

      配置文件(映射文件)

    3、 频繁的开启和关闭数据库连接,会造成数据库性能下降。

      数据库连接池(全局配置文件)

  很多硬编码,把程序写死了!

  1.mybatis架构

  

  详细架构请参见:http://blog.csdn.net/luanlouis/article/details/40422941

//SqlSession本身只是一个接口,它依靠executor进行执行增删改查操作

三.入门程序

  导包:在github上下载mybatis,下载地址:

    https://github.com/mybatis/mybatis-3/releases

    包的结构如下:

  导入的包如下图所示:

  

  引入核心jar包以及lib目录的下的依赖包

  引入Mysql驱动包(持久层框架需要连接数据库都必须 必须导入驱动包!!!)

  引入junit包(eclipse引入方法见另外一篇随笔)

  创建核心配置文件——(全局配置文件)

  新建一个与src同级的 source folder( maven的目录结构) 新建  SqlMapConfig.xml (约定大于配置,尽量不要修改名称)

  (实际开发时会与spring进行整合,配置文件会有改动)

<?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>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>

//ps:每次新建xml文件,第一件事应该是引入约束

  引入log4j.properties——这是从官方文档中PDF中拿的(官方文档的查阅有待加强)

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  创建POJO类 User.java

package cn.pojo;

import java.util.Date;

public class User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址 public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
} }

  创建Sql映射文件 User.xml ——此命名方式是ibatis遗留下来的

<?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">
<!-- namespace命名空间,用来作SQL隔离 -->
<mapper namespace="test">
<!-- id为SQL:语句唯一标识
parameterType:指定入参类型,java的类型而不是数据库的类型
resultType:指定返回结果集类型(如 POJO类型)
#{}是占位符,起到占位作用(不使用之前的?)#{中的变量名称可以随意写(当然尽量遵循规范)}
-->
<select id="findById" parameterType="java.lang.Integer" resultType="cn.pojo.User">
select * from user where id = #{id}
</select>
<!-- 按姓名查询,
返回的是集合类型 ,resultType里写的是selectList返回的集合里的泛型
${}原样拼接字符 传参是基本数据类型(包括String)里面变量名必须是value
拼接符有SQL注入的风险,慎用 一般like的地方用拼接
-->
<select id="findByName" parameterType="java.lang.String" resultType="cn.pojo.User">
select * from user where username like '%${value}%';
</select>
</mapper>

 //一般而言不要直接在映射文件直接写SQL,在navicat等数据库管理工具写完做简单验证后再写回来

    无论返回值是单个或者集合,returnType表示的是返回集合时集合泛型里的泛型

   加载映射文件

<?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>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池(有其他性能更好的连接池,此处暂不展开)-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 引入映射文件 -->
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>

  查询:

  测试函数:

package mybatis01;

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 org.junit.Test; import cn.pojo.User; public class UserTest { @Test
public void findById() throws Exception{
//通过流将核心配置文件进行读取(注意resources的所在包)
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//通过核心配置文件输入流来创建工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通过工厂创建会话
SqlSession session = factory.openSession();
/*执行查询操作
* 第一个参数为SQL语句 namespace+sql语句id格式
* 第二个参数为SQL参数
*/
User user = session.selectOne("test.findById", 1);
System.out.println(user.toString());
session.close();
}
@Test
public void findByName() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
List<User> list = session.selectList("test.findByName", "王");
System.out.println(list); }
}

  //通过Resource获取核心配置文件到流里面

    SQL模糊匹配规则如下:

      % :表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。

      _ : 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:

      [ ]([^]同理) :表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。

  小结: 

    1 #{}和${}

    #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。

  #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

    ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,直接原样输出 ${}可以接收简单类型值或pojo属性值,常用于排序后面的动态列等。

    其中,#是表示预编译的SQL,其SQL会在解析时解析为 ?(SELECT * FROM user WHERE id = ?),然后在DBMS阶段进行替换。

       $是仅在动态解析SQL时便进行替换,也就是说SQL解析之后均为常量

      一般$用于传递表名、字段名、ORDER BY排序字段后等

  如果 parameterType传输单个简单类型值,${}括号中只能是value。(防SQL注入见文末今日小结)

    类似于一个是state,一个是pstate,占位符就相当于 ? 

    更多相关见今日小结

    2 parameterType和RessultType

  parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

  resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

    3 selectOne和selectList

  selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

    org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

  at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

  selectList可以查询一条或多条记录

  增加

  修改映射文件,增加相关的配置

<!-- insert无返回值类型,入参是整个实体类
入参是POJO类型,#{}中的变量名必须属性,属性,...
-->
<!-- 如果要返回数据库自增主键,可以使用数据库的函数进行查询SELECT LAST_INSERT_ID() -->
<insert id="insertUser" parameterType="cn.pojo.User">
<!-- 执行数据库函数,返回自增主键
keyProperty:将返回的主键保存在入参的user的id里
order:在insert前执行是ibefore 在insert后执行是after
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
</insert>

//原理是使用的OGNL对象图导航语言

  测试函数:

@Test
public void insert() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
User user = new User();
user.setUsername("老李");
//util下的Date
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京");
session.insert("test.insertUser", user);
//提交事务(会自动开启事务),必须提交,否则运行成功后数据也无法插入到数据库
session.commit();
     //传的是对象的引用,此时get到的是最新的插入的ID,因为通过配置进行了保存
System.out.println(user.getId());
}

 //注意事务的部分,增删改需要手动的提交事务!(openSession()的时候默认开启了事务,此方法有重载方法,参数为bool值,可以设置为true以设置不开启事务),不提交是不会更新到数据库的

 小结:

  添加selectKey实现将主键返回:必须和insert语句一起使用

    keyProperty:返回的主键存储在pojo中的哪个属性

    order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,

            所以这里selectKey的执行顺序为after

    resultType:返回的主键是什么类型

    LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值

  当使用 UUID 作为主键时:需要增加通过select uuid() (函数)得到uuid值

<insert  id="insertUser" parameterType="cn.itcast.mybatis.po.User">

<selectKey resultType="java.lang.String" order="BEFORE"

keyProperty="id">

select uuid()

</selectKey>

insert into user(id,username,birthday,sex,address)

 values(#{id},#{username},#{birthday},#{sex},#{address})

</insert>

//注意这里使用的order是“BEFORE”

 //此时使用的ID是通过我们生成进行插入的,所以首先需要在插入时显式的指定给ID赋值,因为该ID不是通过自增生成的 (VALUES(#{id}) )

 //此时的SELECT UUID()函数会自动将生成的UUID赋值给指定的ID值

 //由于接收的是POJO类型,所以#{}里面必须是属性值(注意${}必须是value)

  删除

  修改映射文件,增加相关的配置

<!-- 删除无返回值,占位符变量可自定义 -->
<delete id="deleteById" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>

  测试函数:

@Test
public void delete() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
session.delete("test.deleteById", 29);
session.commit();
}

  //注意事务的提交

  修改

   修改映射文件,增加相关的配置

<!-- 更新时注意入参是pojo类型,此时占位符变量必须是属性名! -->
<update id="updateById" parameterType="cn.pojo.User">
UPDATE user SET username=#{username} WHERE id=#{id}
</update>

  测试函数:

@Test
public void update() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
User user = new User();
user.setId(28);
user.setUsername("县长");
//util下的Date
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京");
session.delete("test.updateById", user);
session.commit();
}

  //注意入参

 四、DAO的开发方法

  1.原生的开发方式——接口+实现类模式

  //也就是将test中的代码进行一些改动,加到Dao

  定义接口:

package cn.dao;

import java.util.List;

import cn.pojo.User;

public interface UserDao {

    User findById(Integer id);
List<User> findByUsername(String username);
}

  定义实现类:

package cn.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import cn.pojo.User; public class UserDaoImpl implements UserDao { //构造方法注入factory
private SqlSessionFactory factory; public UserDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
} @Override
public User findById(Integer id) {
//session是线程不安全的,最佳使用是在方法体内
SqlSession session = factory.openSession();
return session.selectOne("test.findById", id);
} @Override
public List<User> findByUsername(String username) {
//session是线程不安全的,最佳使用是在方法体内
SqlSession session = factory.openSession();
return session.selectList("test.findByName", username);
} }

  //使用构造方法注入factory的形式,因为不应该频繁地创建工厂,SqlSessionFactory生命周期应该是全局的单例的

  //与spring整合后,交给spring来进行管理,所以这里用spring的非常熟悉的依赖注入(这里暂时使用构造注入) (而SqlSession有线程安全问题,无法进行单例的控制)

  测试类:

package mybatis01;

import java.io.InputStream;
import java.util.List; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test; import cn.dao.UserDao;
import cn.dao.UserDaoImpl;
import cn.pojo.User; public class UserDaoTest { private SqlSessionFactory factory;
//在测试方法前会执行此初始化方法,构造工厂
@Before
public void setUp() throws Exception{
//通过流将核心配置文件进行读取(注意resources的所在包)
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//通过核心配置文件输入流来创建工厂
factory = new SqlSessionFactoryBuilder().build(in);
}
@Test
public void test1() throws Exception{
UserDao dao = new UserDaoImpl(factory);
User user = dao.findById(1);
System.out.println(user.toString());
}
@Test
public void test2() throws Exception{
UserDao dao = new UserDaoImpl(factory);
List<User> list = dao.findByUsername("王");
System.out.println(list);
}
}

  //注意before注解的使用

  【更新】:问题引入:     

    1、 有大量的重复的模板代码——例如获得sqlSession的过程,session的关闭

    2、 存在硬编码

      硬编码就是一种不够灵活的代码方案。
      比如说,一个服务期端的程序,在执行时需要创建服务器进行侦听,你可以简单的将它需要侦听的端口号放在代码里面,

      也可以通过程序参数传入,也可以通过配置文件放置。
      上述的放在代码里面的就叫做硬编码

  所以我们前面说的mapper里的命名空间不能随便写,后面它需要根据这个动态生成编码。前面一些模板代码都是重复的,里面的.selectOnde() .delete()等方法,里面需要传入的参数,第二个SQL参数由方法传入,所以就剩SQL的id,如果我们可以确定这个,那么就能实现了!

  2.动态代理Dao的方式——只写接口,不写实现,由mybatis生成

    mapper代理使用的是JDK的动态代理

【更新】:

    1、 mapper接口的全限定名要和mapper映射文件的namespace值一致。

    2、 mapper接口的方法名称要和mapper映射文件的statement的id一致。

    3、 mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个。

    4、 mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。

  1. Mapper.xml(映射文件) (内容类同User.xml)——配置文件与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接口代理实现编写规则:
1.映射文件中namespace要等于接口的全路径
2.映射文件中sql语句的id要等于接口的方法名
3.映射文件中传入参数类型要等于接口方法的入参
4.映射文件返回值类型要等于接方法的返回值类型
-->
<mapper namespace="cn.mapper.UserMapper">
<!-- 不再赘述配置文件,详见User.xml -->
<select id="findById" parameterType="java.lang.Integer" resultType="cn.pojo.User">
select * from user where id = #{id}
</select>
<select id="findByName" parameterType="java.lang.String" resultType="cn.pojo.User">
select * from user where username like '%${value}%';
</select>
<insert id="insertUser" parameterType="cn.pojo.User">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
</insert>
</mapper>

  //注意编写规则

  2.mapper.java接口文件

package cn.mapper;

import java.util.List;

import cn.pojo.User;

public interface UserMapper {

    User findById(Integer id);
//返回值是list集合时,mybatis会自动调用selectList()方法
List<User> findByName(String username);
void insertUser(User user);
}

  //注意接口文件的编写规则(见配置文件注释)

  看到not found的异常时应该想到:没把配置文件引入进核心配置文件!

<!-- 引入映射文件 -->
<mappers>
<mapper resource="User.xml"/>
<!-- 使用class映入接口的全路径
class的使用规则:
1.接口名称和映射名称除拓展名外需要一致
2.映射文件和接口在同一目录下
-->
<mapper class="cn.mapper.UserMapper"/>
</mappers>

  测试类:

package mybatis01;

import java.io.InputStream;
import java.util.Date;
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 org.junit.Before;
import org.junit.Test; import cn.mapper.UserMapper;
import cn.pojo.User; public class UserMapperTest { private SqlSessionFactory factory;
//在测试方法前会执行此初始化方法,构造工厂
@Before
public void setUp() throws Exception{
//通过流将核心配置文件进行读取(注意resources的所在包)
String resource = "SqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//通过核心配置文件输入流来创建工厂
factory = new SqlSessionFactoryBuilder().build(in);
}
@Test
public void testFindById() throws Exception{
SqlSession session = factory.openSession();
//通过getMapper()方法实例化实现类
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.findById(1);
System.out.println(user.toString());
}
@Test
public void testFindByName() throws Exception{
SqlSession session = factory.openSession();
//通过getMapper()方法实例化实现类
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findByName("王");
System.out.println(list);
}
@Test
public void insert() throws Exception{
SqlSession session = factory.openSession();
//通过getMapper()方法实例化实现类
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("宋江");
user.setSex("2");
user.setBirthday(new Date());
user.setAddress("北京");
mapper.insertUser(user);
session.commit();
}
}

//一定得注意提交!增加修改删除等是先改到缓存区的,所以必须提交!

五、SqlMapConfig.xml文件说明 

  【更新】:详细配置讲解请参见:http://ju.outofmemory.cn/entry/94633

    mybatis的配置文件主要分为

      全局配置文件

         配置数据源、事务等全局信息

      映射文件

        执行statement相关的信息,SQL语句、输入输出映射等

  SqlMapConfig.xml中配置的内容和顺序如下:

    properties(属性)

    settings(全局配置参数)

    typeAliases(类型别名:给POJO类起别名)

    typeHandlers(类型处理器)

    objectFactory(对象工厂)

    plugins(插件)——使用插件可以方便的进行分页等的操作

    environments(环境集合属性对象)

      environment(环境子属性对象)

        transactionManager(事务管理)

        dataSource(数据源)

    mappers(映射器)

  1 properties(属性)

  SqlMapConfig.xml可以引用java属性文件(.properties)中的配置信息如下:

  在classpath下定义db.properties文件(回忆key多加一层的原因:同在mybatis这个大容器中,容易发生命名冲突)

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

  //如果jdbc.url多个参数需要使用&,请使用转义:&amp;

  SqlMapConfig.xml引用如下:(使用EL取值)

<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>

  2.支持别名

别名    映射的类型
_byte byte
_long long
_short short
_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
decimal BigDecimal
bigdecimal BigDecimal
map Map

  3.自定义别名:

  在SqlMapConfig.xml中配置:

<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="cn.itcast.mybatis.po"/>
<package name="其它包"/>
</typeAliases>

  //建议遵循驼峰式命名规则,批量别名时默认别名是类名(请使用规范首字母小写)

  4.mappers(映射器)

  1 <mapper resource=" " />

  使用相对于类路径的资源

  如:<mapper resource="sqlmap/User.xml" />

  2. <mapper class=" " />

  使用mapper接口类路径

  如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

  注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

  3.<package name=""/> 包扫描的方式

    使用的最多最简便,但是注意遵循相关的规则,与上述接口文件编写规则配置文件一致(映射文件与接口同名并且同一目录)

  注册指定包下的所有mapper接口

  如:<package name="cn.itcast.mybatis.mapper"/>

最后,贴出目录结构(夹带了一点day02的QueryVo等)

  

//三个source folder,为的是实现maven的目录结构

  今日小结:

  1. mybatis是一个持久层框架, 作用是跟数据库交互完成增删改查
  2.原生Dao实现(需要接口和实现类)
  4.动态代理方式(只需要接口)
  mapper接口代理实现编写规则:
    1) 映射文件中namespace要等于接口的全路径名称
    2) 映射文件中sql语句id要等于接口的方法名称
    3) 映射文件中传入参数类型要等于接口方法的传入参数类型
    4) 映射文件中返回结果集类型要等于接口方法的返回值类型

  5. #{}占位符:占位
    如果传入的是基本类型,那么#{}中的变量名称可以随意写
    如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性.属性...

  6. ${}拼接符:字符串原样拼接
    如果传入的是基本类型,那么${}中的变量名必须是value
    如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性.属性...
    注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格
  7. 映射文件:
    1)传入参数类型通过parameterType属性指定
    2)返回结果集类型通过resultType属性指定
  8. hibernate和mybatis区别:
    hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
  优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.数据库无关性!
  缺点:sql语句无法优化
  应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
  总的来说,在用于量不大,并发量小的时候使用.
    mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
  优点:学习成本低, sql语句可以优化, 执行效率高,速度快.【提高了SQL控制权!
  缺点:编码量较大,会拖慢开发周期
  应用场景: 互联网项目,比如电商,P2p等
  总的来说是用户量较大,并发高的项目.

  【补充注意事项】:当出现无法完成绑定异常时,是由于只有.java文件被编译而xml文件未被编译,方法之一可以在pom.xml中加入resource标签:   

<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8083</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>

mybatis第一天——入门与概述的更多相关文章

  1. mybatis第一个入门demo

    学习框架技术,一般先写个demo,先知道是什么,然后在知道为什么,这也是进步的一种. 源码链接:http://pan.baidu.com/s/1eQJ2wLG

  2. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  3. Mybatis第一天(其他)

    Mybatis第一天 框架课程 课程计划 第一天: Mybatis的介绍 Mybatis的入门 使用jdbc操作数据库存在的问题 Mybatis的架构 Mybatis的入门程序 Dao的开发方法 原始 ...

  4. MyBatis(1)——快速入门

    MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...

  5. Mybatis第一天

    Mybatis第一天   框架课程 1.   课程计划 第一天: 1.Mybatis的介绍 2.Mybatis的入门 a)       使用jdbc操作数据库存在的问题 b)      Mybatis ...

  6. [编程笔记]第一章 C语言概述

    //C语言学习笔记 第一讲 C语言概述 第二讲 基本编程知识 第三讲 运算符和表达式 第四讲 流程控制 第五讲 函数 第六讲 数组 第七讲 指针 第八讲 变量的作用域和存储方式 第九讲 拓展类型 第十 ...

  7. (转) MyBatis(1)——快速入门

    MyBatis 简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...

  8. Redis(一):NoSQL入门和概述

    NoSQL入门和概述目录导航: NoSQL入门概述 3V+3高 当下的NoSQL经典应用 NoSQL数据模型简介 NoSQL数据库的四大分类 在分布式数据库中CAP原理CAP+BASE NoSQL 入 ...

  9. 《驾驭Core Data》 第一章 Core Data概述

    <驾驭Core Data>系列教程综合了<Core Data for iOS>,<Learning Core Data for iOS>,<Core Data ...

随机推荐

  1. 记录下使用iis7代理node.js写的网站程序

    昨天晚上一个学弟的紧急求救,说了自己接的单子做了一个网站,使用了自己熟悉的技术——node.js+mongdb,但当看到部署环境惊呆了,是 windows+sqlserver.这些都不是关键,关键是服 ...

  2. <![CDATA[文本内容]]>

    DTD中的属性类型 全名:character data 在标记CDATA下,所有的标记.实体引用都被忽略,而被XML处理程序一视同仁地当做字符数据看待, CDATA的形式如下: <[CDATA[ ...

  3. is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

    出现此日志的原因: https://blog.csdn.net/m0_37962779/article/details/78605478 上面的博客中可能解决了他的问题,可我的项目是spring bo ...

  4. LeetCode题解之Peak Index in a MountainArray

    1 题目描述 2.问题分析 直接从后向前遍历,找到 A[i] > A[i-1] 即可. 3.代码 int peakIndexInMountainArray(vector<int>&a ...

  5. RedHat 安装YUM软件

    最近在虚拟机里搭建RedHat Enterprise Linux 6.0 X86_64位系统,在此机器上安装了Oracle11g数据库.其中在安装软件的时候,一般都是用的是RPM命令,但是有些软件包有 ...

  6. 网站源IP暴露使用高防之后还行不行如何解决?

    如题:使用高防后源站IP暴露的解决办法 在购买高防IP后,如果还存在攻击绕过高防直接打到源站IP的情况,就需要更换下源站IP了.但在这之前,请务必排查确认没有其他可能暴露源站IP的因素后,再去更换源站 ...

  7. Sqlserver2014 迁移数据库

    由于当初安装sqlserver 的时候选择默认安装的路径,导致现在c盘爆满,安装不了其它软件.因此想到了迁移数据库,网上搜索了一些简介,但是缺少一些步骤,导致数据库附加的时候失败.现总结如下: 1.将 ...

  8. Shell: extract more from listener.log (分析oracle监听日志)

    最近遇到了两起数据库连接数不足的问题, 通常都会预留一些会话增加的情况, 但在一些特殊情况下如连接风暴(logon storm), 如果在监听中没有做rate限流,对数据库来说巨大的冲击可能会导致数据 ...

  9. uml各类图

    原文:http://www.cnblogs.com/way-peng/archive/2012/06/11/2544932.html 一.UML是什么?UML有什么用? 二.UML的历史 三.UML的 ...

  10. REST framework 视图层

    我们之前写的  get  post  请求 要写很多 我们现在可以使用rest——framework给我们封装好的类 GenericAPIView 给我们提供了自动匹配验证的信息内部封装 from r ...