MyBatis

可以通过索引的方式获取 索引从0开始 也可用param1 param2Mybatis安装

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可
官网 http://mybatis.github.io/
下载路径:https://github.com/mybatis/mybatis-3/releases
文档:http://mybatis.github.io/mybatis-3/zh/getting-started.html

pom.xml

<!-- 配置mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.2.8</version>
    </dependency>

MyBatis简介

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

Mybatis入门配置

从 XML 中构建 SqlSessionFactory:
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

public class Test {
    public static void main(String[] args) throws IOException {
        String resource = "com/et/lesson01/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        List list=session.selectList("selectFood");
        System.out.println(list);

mybatis的核心配置

mybatis.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>
    <!--1.数据库的连接信息 告诉properties文件位置 -->
    <properties resource="jdbc.properties">
    </properties>
<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson01/test/foodMapper.xml" />
</mappers>
</configuration> 

foodMapper.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">
<!--  namespace命名空间 多个文件中的相同id
   比如 a.xml (namespace=a)
   id="test"
    b.xml (namespace=b)
   id="test"
   a.test
   b.test
 -->
<mapper namespace="a">
  <select id="selectFood" resultType="java.util.Map">
    select * from food
  </select>
  <select id="selectFoodById" resultType="java.util.Map" >
    select * from food where foodid=1
  </select>
<!--FOOD_SEC.nextval 序列通过下一个值找到主键-->
  <insert id="saveFood">
    insert into food values(FOOD_SEC.nextval,#{foodname},#{price})
  </insert>
  <insert id="insertFood" parameterType="java.util.Map">
      insert into food(FOODID,FOODNAME,PRICE) values(#{foodid},#{foodname},#{price}) 
  </insert>

  <delete id="deleteFood" parameterType="java.util.Map">
  <!--
    delete from FOOD where FOODID=5 
  -->
  delete from FOOD where FOODID=#{foodid}
  </delete>

  <update id="updateFood"  parameterType="java.util.Map" >
    <!-- update FOOD set FOODNAME='酸辣土豆丝' where FOODID =4 -->
    update FOOD set FOODNAME=#{foodname},PRICE=#{price} where FOODID =#{foodid}
  </update>
</mapper>
public class Test {
    public static void main(String[] args) throws IOException {
        String resource = "com/et/lesson01/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        List list=session.selectList("selectFood");
        System.out.println(list);
        //通过id查找
        Map  map=(Map)session.selectOne("selectFoodById");
        System.out.println(map);


    /*  //添加
        Map map1=new HashMap();
        map1.put("foodid", "5");
        map1.put("foodname", "酸辣土豆丝");
        map1.put("price", "155");
        session.insert("insertFood", map1);
        System.out.println(map1);
        //删除
        session.delete("deleteFood");
        session.commit();

        //修改
        session.update("a.updateFood");
        session.commit();*/

        //删除
        /*Map map1=new HashMap();
        map1.put("foodid", "4");
        session.delete("deleteFood", map1);
        session.commit();
        System.out.println(map1);*/
        //修改
        Map map1=new HashMap();
        map1.put("foodid", "1");
        map1.put("foodname", "酸辣土豆丝");
        map1.put("price", "20");
        session.update("updateFood", map1);
        session.commit();
        System.out.println(map1);
    }
    @Test
    public void saveFood() throws IOException{
        SqlSession session=getSession();
        Food food=new Food();
        food.setPrice("100");
        food.setFoodname("回锅肉");
        session.insert("a.saveFood", food);
        session.commit();

    }
}

mybatis参数传递的方式有两种

第一种方式

<!--使用#{键}方式 实际上是使用占位符 问号(?) 来替代
    可以通过索引的方式获取 索引从0开始 也可用param1 param2
 -->
  <select id="selectFoodParam" resultType="java.util.Map">
    select * from food where price=#{price} and foodname=#{foodname}
  </select>
第二中方式

 <!--使用${键}方式 使用是直接替换对应的的键 注意如果是字符串说过添加'' -->
  <select id="selectFoodByParam" resultType="java.util.Map">
    select * from food where price=${price} and foodname='${foodname}'
  </select>

通过map和对象都可以传值

public class MyTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson01/test/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    @Test
    public void QueryFood() throws IOException{
        SqlSession session=getSession();
        Map map=new HashMap();
        map.put("price", 60);
        map.put("foodname", "大盘鸡");
        List  list = session.selectList("a.selectFoodByParam", map);
        System.out.println(list);
    }

    /**
     *通过对象传值(面向对象)
     * @throws IOException
     */
    //@Test
    public void FoodAll() throws IOException{
        SqlSession session=getSession();
        Food food=new Food();
        food.setPrice("60");
        food.setFoodname("大盘鸡");
        List  list = session.selectList("a.selectFoodByParam", food);
        System.out.println(list);
    }
}
实体类

public class Food {
    private String foodname;
    private String price;

    public Food(){

    }
    public Food(String foodname, String price) {
        super();
        this.foodname = foodname;
        this.price = price;
    }
    public String getFoodname() {
        return foodname;
    }
    public void setFoodname(String foodname) {
        this.foodname = foodname;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }

}

自定义log日志及日志的打印

### 全局控制机制 ###
log4j.rootLogger = debug ,  a 
# log4j日志分为 5种级别
#         debug 调试 (开发阶段)
#         info  运行信息 (测试或者运行阶段)
#         warn  警告消息 
#         error 程序错误消息
#         fatal 系统错误消息
 #       通过5种级别输出的日志 打印在文件中
#        int i=0;
#        my.debug("定义了变量i");
#        i=10
#        my.debug("变量i设置了值 10");
#        my.info("变量i设置了值 10")
#        my.warn("警告。。。。")
#           ....
#           
  # 全局控制机制
  #   root=info
   #
        #日志级别  fatal>error>warn>info>debug 所有全局控制中设置的级别 以下的所有日志都不打印 比如 设置  info 不打印debug   fatal 前面四个日志都不会打印
   #
log4j.appender.a = org.apache.log4j.ConsoleAppender
log4j.appender.a.Target = System.out
log4j.appender.a.layout = org.apache.log4j.PatternLayout
log4j.appender.a.layout.ConversionPattern =%-d{yyyy-MM-dd HH\:mm\:ss}  [ %t\:%r ] - [ %p ]  %m%n
    //自定义log日志
    Logger logger=Logger.getLogger(MyTest.class);
    //@Test
    public void QueryFood() throws IOException{
        SqlSession session=getSession();
        Map map=new HashMap();
        map.put("price", 60);
        map.put("foodname", "大盘鸡");
        List  list = session.selectList("a.selectFoodByParam", map);
        logger.info(list);
        System.out.println(list);
    }

通过接口直接映射Sql(XML)

接口定义:

/**
 * 接口
 * @author Administrator
 *
 */
public interface FoodMapper {
    /**
     * 根据名称查询所有的菜品信息
     * @param foodName
     * @return
     */
    public List queryFood(String foodName,String price);
    /**
     * 通过菜品id删除
     * @param foodId
     */
    public void deleteFood(String foodId);
    /**
     * 通过名字模糊查找
     * @param foodName
     * @return
     */
    public List queryFoodByName(@Param("foodName") String foodName);

    /**
     * 插入food
     * @param food
     */
    public void saveFood(Food food);
}

mybatis.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>
    <!-- 是mybatis的核心配置  数据库的连接信息告诉properties文件位置 -->
    <properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson02/xml/foodMapper.xml" />
</mappers>
</configuration> 

foodMapper.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">
<!-- 
    接口绑定 将接口中的方法和对应的sql声明进行绑定
    接口绑定的参数 可以通过索引的方式获取 索引从0开始 也可用param1 param2
    ('s','sex') 0='sex' 1='abc'
    param1='sex'  param2='abc'
    namespace="全路径.接口名"
 -->
<mapper namespace="com.et.lesson02.xml.FoodMapper">


  <select id="queryFood" resultType="java.util.Map">
  <!--
    select * from food where  foodname=#{0} and price=#{1} 
  -->
    select * from food where  foodname=#{param1} and price=#{param2} 
  </select>

  <delete id="deleteFood" >
  delete from FOOD where FOODID=#{0}

    <!-- 通过自定义类型 -->
  <select id="queryFoodByName" resultType="food">
    select * from food where  foodname like '%${foodName}%'
  </select>

<insert id="saveFood" >
    <!-- 在程序中获取主键    将获取到的主键塞入参数foodId中
    keyProperty="告诉塞入的属性名"
    order="BEFORE"在执行insert语句之前
    statementType="STATEMENT" 表示sql语句
    -->
    <selectKey keyProperty="foodId" order="BEFORE"  resultType="int" statementType="STATEMENT">
        select Food_SEC.Nextval from dual
    </selectKey>
        insert into food values(#{foodId},#{foodName},#{price})
    </insert>
</mapper>

通过接口直接映射Sql(注解)

接口定义:

/**
 * 接口
 * @author Administrator
 *
 */
public interface FoodMapper {
    /**
     * 根据名称查询所有的菜品信息
     * @Param("foodName")可以指定参数 例如foodname=#{foodName}
     * @param foodName
     * @return
     */
    @Select("select * from food where  foodname=#{foodName} and price=#{price}")
    public List<Map> queryFood(@Param("foodName")String foodName,@Param("price")String price);
    /**
     * 通过菜品id删除
     * @param foodId
     */
    @Delete(" delete from FOOD where FOODID=#{0}")
    public void deleteFood(String foodId);

    /**
     * 通过名字模糊查找
     * @param foodName
     * @return
     */
    @Select("select * from food where  foodname like '%${foodName}%'")
    public List<Food> queryFoodByName(@Param("foodName") String foodName);

    /**
     * 插入food
     * before=true 表示insert之前执行  false之后
     * @param food
     */
    @SelectKey(before=true,keyProperty="foodId", resultType=int.class, statement = "select Food_SEC.Nextval from dual" )
    @Insert("insert into food values(#{foodId},#{foodName},#{price})")
    public void saveFood(Food food);

mybatis.xml内容: 不需要foodMapper.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="jdbc.properties">
    </properties>
<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 
         class="全路径.接口名"
-->
<mappers>
<mapper class="com.et.lesson02.annotion.FoodMapper" />
</mappers>
</configuration> 
测试类

public class MyTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson02/xml/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }
    /**
     * 根据名称查询所有的菜品信息
     * @throws IOException
     */
    //@Test
    public void QueryFood() throws IOException{
        SqlSession session=getSession();
        //获取接口
        FoodMapper fm=session.getMapper(FoodMapper.class);
        List  list=fm.queryFood("大盘鸡", "60");
        System.out.println(list);
    }
    /**
     * 通过菜品id删除
     * @throws IOException
     */
    //@Test
    public void deleteFood() throws IOException{
        SqlSession session=getSession();
        //获取接口
        FoodMapper fm=session.getMapper(FoodMapper.class);
        fm.deleteFood("4");
        session.commit();
    }

    /**
     * 通菜品名模糊查找
     * @throws IOException
     */
    @Test
    public void QueryFoodByName() throws IOException{
        SqlSession session=getSession();
        //获取接口
        FoodMapper fm=session.getMapper(FoodMapper.class);
        List  list=fm.queryFoodByName("鸡");
        System.out.println(list);
    }

    /**
     * 插入food 在程序中获取主键
     * @throws IOException
     */
    @Test
    public void QueryFoodSelectKey() throws IOException{
        SqlSession session=getSession();
        //获取接口
        FoodMapper fm=session.getMapper(FoodMapper.class);
        Food food=new Food();
        food.setFoodName("牛肉面");
        food.setPrice("10");
        fm.saveFood(food);
        session.commit();
        System.out.println(food.getFoodId());
    }
}

typeAliases

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:

mybatis.xml

<!-- 自定义类型别名
            resultType="全包名路径.类名"=type
        resultType="food"
     -->
    <typeAliases>
        <typeAlias type="com.et.lesson02.Food" alias="自定义名字 food"/>
    </typeAliases>

  <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson03"/>
    </typeAliases>

SELECT调用存储过程

创建存储过程:

create or replace procedure prg_add(p1 in number,p2 in number,p3 out number)
as
begin
  p3:=p1+p2;
end;

创建函数:

create or replace function fun_add(p1 in number,p2 in number)
return number
as
begin
 return p1+p2;
end;

Mybatis映射文件中使用select调用存储过程

mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson02/procedure/ProcMapper.xml" />
</mappers>
</configuration> 
ProcMapper.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="com.et.lesson02.procedure.ProcMapper.xml">
 <!-- jdbc调用存储过程的语法 
    {call  存储过程名(?,?)}
    函数的语法
    {?=call  函数名 (?,?)}
  -->
  <select id="call_prg_add" resultType="java.util.Map" statementType="CALLABLE">
    {call prg_add(
      #{p1,mode=IN,jdbcType=NUMERIC},
      #{p2,mode=IN,jdbcType=NUMERIC},
      #{result,mode=OUT,jdbcType=NUMERIC})}
  </select>

 <!--函数 -->
  <select id="call_fun_add" resultType="java.util.Map" statementType="CALLABLE">
    {#{result,mode=OUT,jdbcType=NUMERIC}=call fun_add(
      #{p1,mode=IN,jdbcType=NUMERIC},
      #{p2,mode=IN,jdbcType=NUMERIC})
    }
  </select>
</mapper>
测试类

public class MyProcTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson02/procedure/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    /**
     * 存储过程
     * @throws IOException
     */
    //@Test
    public void testProcFood() throws IOException{
        SqlSession session=getSession();
        Map map=new HashMap();
        map.put("p1",100);
        map.put("p2",200);
        map.put("result",0);
        String result=session.selectOne("call_prg_add",map);
        System.out.println(map.get("result"));
    }
    /**
     * 函数
     * @throws IOException
     */
    @Test
    public void testFunFood() throws IOException{
        SqlSession session=getSession();
        Map map=new HashMap();
        map.put("p1",100);
        map.put("p2",200);
        map.put("result",0);
        String result=session.selectOne("call_fun_add",map);
        System.out.println(map.get("result"));
    }
}

sql 这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:

foodMapper.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">
<!-- 
  sql这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。
 -->
<mapper namespace="com.et.lesson03.sql.FoodMapper">
    <sql id="commonSql">
        select * from 
    </sql>

  <select id="queryFood" resultType="java.util.Map">
    <include refid="commonSql"></include>
    food where  foodname=#{param1} and price=#{param2} 
  </select>
</mapper>
mybatis.xml

<!-- 键和sql语句映射 -->
<mappers>
<mapper resource="com/et/lesson03/sql/foodMapper.xml" />
</mappers>

Result Maps

结果集映射:数据库的列名和实体类的属性名如果不一致 需要建立 列名和属性名的映射关系
结果集映射返回的结构是相同的,只是多了一层关系

<!--
    结果集映射:数据库的列名和实体类的属性名如果不一致 需要建立 列名和属性名的映射关系
    结果集映射返回的结构是相同的都是grade 只是多了一层关系
    <select id="queryAllGrade" resultType="间接将resultType映射到resultMap">
    select * from grade
  </select>
  -->
    <select id="queryAllGrade" resultMap="gradeMap">
    select * from grade
    </select>
    <!--  resultType="返回的班级" -->
    <select id="queryGradeById" resultMap="gradeMap">
        select * from grade where gid=#{gid}
    </select>

用xml实现一对多和多对一的结果集映射

/**
 * 一对多
 * 班级实体
 * @author Administrator
 *
 */
public class Grade {
    private int gid;
    private String gname;
    private List<Student>  studentList=new ArrayList<Student>();

    public List<Student> getStudentList() {
        return studentList;
    }
    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }
    public int getGid() {
        return gid;
    }
    public void setGid(int gid) {
        this.gid = gid;
    }
    public String getGname() {
        return gname;
    }
    public void setGname(String gname) {
        this.gname = gname;
    }
}

/**
 * 多对一
 * 实体类
 * @author Administrator
 *
 */
public class Student {
    private int sid;
    private String sname;
    private Grade grade;
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}

多对一和一对多的关系:

/**
 *多对一接口
 * @author Administrator
 *
 */
public interface StudentMapper {
    /**
     * 通过编号查询学生
     * @param 
     * @return
     */
    public Student queryStudentById(String sid);
}
/**
 * 接口
 * @author Administrator
 *
 */
public interface GradeMapper {
    /**
     * 查询所有的班级
     * @param 
     * @return
     */
    public List queryAllGrade();

    /**
     * 通过id查找所有的班级
     * 一对多
     * @param gid
     * @return
     */
    public Grade queryGrade(String gid);

}
studentMapper.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="com.et.lesson03.resultMap.xml.StudentMapper">
    <!-- 映射多对一的关系
    多对一使用的关联<association property="关联的属性名"></association>
   -->
        <resultMap type="student" id="studentMap" autoMapping="true">
    <!-- 列和属性的关系 主键使用id 非主键使用result -->
        <id column="sid" property="sid"/>
        <!-- select * from grade where gid=${学生信息中的gid} 
        select="queryGradeById"指定学生的班级
        -->
        <association property="grade" column="gid" select="com.et.lesson03.resultMap.xml.GradeMapper.queryGradeById">
        </association>
    </resultMap>
    <!-- 多对一 -->
    <select id="queryStudentById" resultMap="studentMap">
        select * from student where sid=#{0}
    </select>

  <!-- 一对多 -->
    <select id="queryStudentByGid" resultMap="studentMap">
        select * from student where gid=#{0}
    </select>
</mapper>
gradeMapper.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="com.et.lesson03.resultMap.xml.GradeMapper">
 <!--
  type="返回的都是grade类" id="名字"
  column="数据库列名" property="属性名"
  autoMapping="true"相同列自动映射 
   -->
    <resultMap type="grade" id="gradeMap" autoMapping="true">
    <!-- 列和属性的关系 主键使用id 非主键使用result -->
        <id column="gid" property="gid"/>
        <result column="gname" property="gname"/>
    </resultMap>
  <!-- 
      结果集映射:数据库的列名和实体类的属性名 如果不一致  需要建立 列名和属性名的映射关系 
               结果集映射返回的结果是相同 的 都是grade  只是多了一层关系
   -->
 <select id="queryAllGrade" resultMap="gradeMap">
    select * from grade
 </select>

    <!--  多对一resultType="返回的班级" -->
    <select id="queryGradeById" resultMap="gradeMap">
        select * from grade where gid=#{gid}
    </select>

  <!-- 用于一对多的映射 
    一对多使用的关联<collection property="关联的属性名" javaType="返回的类型"></collection>
 -->
    <resultMap type="grade" id="gradeOne" autoMapping="true">
    <!-- 列和属性的关系 主键使用id 非主键使用result -->
        <id column="gid" property="gid"/>
        <result column="gname" property="gname"/>
        <collection property="studentList" column="gid"  javaType="list" select="com.et.lesson03.resultMap.xml.StudentMapper.queryStudentByGid" autoMapping="true">
        </collection>
    </resultMap>

    <!-- 一对多的关系 查询某个班级下 多个学生 -->
    <select id="queryGrade" resultMap="gradeOne">
        select * from grade where gid=#{gid}
    </select>
</mapper>
测试类

public class MyTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson03/resultMap/xml/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    /**
     * 查询所有的班级
     * @throws IOException
     */

    @Test
    public void QueryAllGrade() throws IOException{
        SqlSession session=getSession();
        //获取接口
        GradeMapper gm=session.getMapper(GradeMapper.class);
        List<Grade> list=gm.queryAllGrade();
        for (Grade g : list) {
            System.out.println(g.getGid()+"-----"+g.getGname());
        }
        System.out.println(list.size());
    }

    /**
     * 多对一的查询
     * @throws IOException
     */

    @Test
    public void QueryManyToOne() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper gm=session.getMapper(StudentMapper.class);
        Student st=gm.queryStudentById("2");
        System.out.println(st.getSname()+"---"+st.getGrade().getGname());

    }
    /**
     * 一对多的查询
     * @throws IOException
     */

    @Test
    public void QueryOneToMany() throws IOException{
        SqlSession session=getSession();
        //获取接口
        GradeMapper gm=session.getMapper(GradeMapper.class);
        Grade ge=gm.queryGrade("1");
        for (Student s:ge.getStudentList()) {
            System.out.println(ge.getGname()+"==="+s.getSid()+"---"+s.getSname());
        }
        System.out.println(ge.getStudentList().size());
    }
}
mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="jdbc.properties"></properties>
    <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson03.resultMap.xml"/>
    </typeAliases>

<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
    <mapper resource="com/et/lesson03/resultMap/xml/GradeMapper.xml" />
    <mapper resource="com/et/lesson03/resultMap/xml/StudentMapper.xml" />
</mappers>
</configuration> 

用注解实现一对多和多对一的结果集映射 不需要xml映射文件

/**
 * 接口
 * @author Administrator
 *
 */
public interface GradeMapper {
    /**
     * 查询所有的班级
     * @param 
     * @return
     */
    public List queryAllGrade();

    /**
     * 通过id查找所有的班级
     * @param gid
     * @return
     * 一对多
     * many=@Many
     */
    @Results({
        @Result(column="gid",property="studentList",javaType=ArrayList.class,many=@Many(
                select="com.et.lesson03.resultMap.annotion.StudentMapper.queryStudentByGid"
                ))
    })
    @Select("select * from grade where gid=#{0}")
    public Grade queryGrade(String gid);

    /**
     * 多对一
     * @param gid
     * @return
     */
    @Select("select * from grade where gid=#{0}")
    public Grade queryGradeById(String gid);
}
/**
 *多对一
 * @author Administrator
 *
 */
public interface StudentMapper {
    /**
     * 通过编号查询学生
     * 列名不同时要映射@Result(column="ganme",property="ganme1")
     * 相同的时候自动映射
     *多对一
     * one=@One(select="全路径.接口名.方法名 ")
     * @param 
     * @return
     */
    @Results({
        @Result(column="gid",property="grade",one=@One(select="com.et.lesson03.resultMap.annotion.GradeMapper.queryGradeById"))
    })
    @Select("select * from student where sid=#{0}")
    public Student queryStudentById(String sid);

    /**
     * 一对多
     * @param gid
     * @return
     */
    @Select("select * from student where gid=#{0}")
    public List<Student> queryStudentByGid(String gid);
}
mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="jdbc.properties"></properties>
    <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson03.resultMap.annotion"/>
    </typeAliases>

<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
    <mapper class="com.et.lesson03.resultMap.annotion.GradeMapper" />
    <mapper class="com.et.lesson03.resultMap.annotion.StudentMapper" />
</mappers>
</configuration> 
测试类

public class MyTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson03/resultMap/annotion/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    /**
     * 查询所有的班级
     * @throws IOException
     */

    //@Test
    public void QueryAllGrade() throws IOException{
        SqlSession session=getSession();
        //获取接口
        GradeMapper gm=session.getMapper(GradeMapper.class);
        List<Grade> list=gm.queryAllGrade();
        for (Grade g : list) {
            System.out.println(g.getGid()+"-----"+g.getGname());
        }
        System.out.println(list.size());
    }
    /**
     * 多对一的查询
     * @throws IOException
     */
    //@Test
    public void QueryManyToOne() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper gm=session.getMapper(StudentMapper.class);
        Student st=gm.queryStudentById("2");
        System.out.println(st.getSname()+"---"+st.getGrade().getGname());

    }
    /**
     * 一对多的查询
     * @throws IOException
     */
    @Test
    public void QueryOneToMany() throws IOException{
        SqlSession session=getSession();
        //获取接口
        GradeMapper gm=session.getMapper(GradeMapper.class);
        Grade ge=gm.queryGrade("1");
        for (Student s:ge.getStudentList()) {
            System.out.println(ge.getGname()+"==="+s.getSid()+"---"+s.getSname());
        }
        System.out.println(ge.getStudentList().size());
    }
}

动态sql(xml)

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

IF
if用来判断条件是否满足 满足就将if中的sql 自动拼接到主sql
where 1=1相当于标签
相当于
where 自动判断第一个条件是否存在where 如果没有就追加
同时去掉一个and
trim 永远 灵活度更高
prefix=”前缀” 配置的参数会被添加在sql语句的开始的地方
prefixOverrides=”” sql语句首次出现的参数会被覆盖
prefix覆盖prefixOverrides

学生实体类

/**
 * 查询学生时将班级也查出
 * @author Administrator
 *
 */
public class Student {
    private String sid;
    private String sname;
    private Integer sex;
    private Integer age;
    private String address;
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }

    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}
/**
 * @author Administrator
 *接口类
 */
public interface StudentMapper {
    /**
     * 通过编号查询学生
     * @param 
     * @return
     */
    public List<Student> queryStudentById(Student student);
    /**
     * 通过学生的性别查询
     * 参数中传入sex  就根据条件查  没有传值就查所有的女生
     * @param sex
     * @return
     */
    public List<Student> queryBySex(@Param("sex")Integer sex);
    /**
     * 修改学生信息
     * @param 
     * @return
     */
    public void updateStudent(Student student);

    /**
     * 通过传入的班级查询所有的学生
     * @Param("取别名")
     */
    public List<Student> queryStudentAndGrade(@Param("gradeList")List<String> gradeList);

}

mybatis的核心文件配置:

mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="com/et/lesson04/jdbc.properties"></properties>
    <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson04.xml"/>
    </typeAliases>
<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
    <mapper resource="com/et/lesson04/xml/StudentMapper.xml" />
</mappers>
</configuration> 
StudentMapper.xml

    <select id="queryStudentById" resultType="student">
        select * from student
        <where>
            <if test="sname!=null">
                and sname like '%${sname}%'
            </if>
            <if test="address!=null">
                and address like '%${address}%'
            </if>
        </where>
    </select>

    <select id="queryStudentById" resultType="student">
        select * from student
        <trim  prefix="where" prefixOverrides="and">
            <if test="sname!=null">
                and sname like '%${sname}%'
            </if>
            <if test="address!=null">
                and address like '%${address}%'
            </if>
        </trim>
    </select>

choose, when, otherwise
你们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

StudentMapper.xml

    <select id="queryBySex" resultType="student">
        select * from student where 1=1
        <choose>
            <when test="sex!=null">
            and sex=#{sex}
            </when>
            <otherwise>
            and sex=1
            </otherwise>
        </choose>
    </select>

trim, where, set

    <!-- set标签 动态去掉最后一个逗号(,) 
        用trim实现set  例如:<trim prefix="set" prefixOverrides=""></trim>
    -->
    <update id="updateStudent">
        update student
        <set>
            <if test="sname!=null">
            sname=#{sname},
            </if>
            <if test="sex!=null">
            sex=#{sex},
            </if>
            <if test="age!=null">
            age=#{age}
            </if>
        </set>
         where sid=#{sid}
    </update>

foreach
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:

<!-- 
    foreach
        open="循环条件开始之前追加的条件" 
        close="循环条件结束之后追加的sql"
        separator="非最后一次的循环值上添加逗号分隔符"
        where gid in()等于 open="where gid in(" close=")"
        collection="指定传入值的集合"
        item="每循环一次就用临时变量存"
        ${gid}获取gid
     -->
    <select id="queryStudentAndGrade" resultType="student">
        select * from student
        <foreach  item="gid" collection="gradeList" open="where gid in(" close=")" separator="," >
            ${gid}
        </foreach>
    </select>

动态sql(注解)

mybatis的核心文件配置:

mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="com/et/lesson04/jdbc.properties"></properties>
    <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson04.annotation"/>
    </typeAliases>

<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
    <mapper class="com.et.lesson04.annotation.StudentMapper" />
</mappers>
</configuration> 
/**
 * @author Administrator
 *接口类
 */
public interface StudentMapper {
    /**
     * 通过编号查询学生
     * @SelectProvider提供sql语句有一个类中的方法提供类的方法于接口中的方法名相同
     * type=类名.class
     * method="类中的方法名"
     * @param 
     * @return
     */
    @SelectProvider(type=StudentProvier.class,method="queryStudentBySql")
    public List<Student> queryStudentById(@Param("stu")Student student);
    /**
     * 通过学生的性别查询
     * 参数中传入sex  就根据条件查  没有传值就查所有的女生
     * ${}在注解中会失效
     * @param sex
     * @return
     */
    @Select("<script>select * from student where 1=1" +
            "<choose>"+
            " <when test=\"sex!=null\">"+
            " and sex=#{sex}"+
            " </when>"+
            " <otherwise>"+
            " and sex=1"+
            " </otherwise>"+
            " </choose></script>")
    public List<Student> queryBySex(@Param("sex")Integer sex);
    /**
     * 修改学生信息
     * @param 
     * @return
     */

    @UpdateProvider(type=StudentProvier.class,method="updateStudentSql")
    public void updateStudent(@Param("stud")Student student);

    /**
     * 通过传入的班级查询所有的学生
     * foreach
     * @Param("取别名")
     */
    @SelectProvider(type=StudentProvier.class,method="queryStudentAndGradeBySql")
    public List<Student> queryStudentAndGrade(@Param("gradeList")List<String> gradeList);
}
 提供方法的类

public class StudentProvier {
    /**
     * 通过键值对方式传参
     * ${}在注解中会失效
     * 提供sql语句方法的参数是Map  键值对
     * 对象的属性取值用别名.属性名
     * @return
     */
    public  String queryStudentByIdSql(Map map){
        Student st=(Student)map.get("stu");
        String sql=" select * from student where 1=1 ";
        if(st.getSname()!=null &&!"".equals(st.getSname())){
            st.setSname("%"+st.getSname()+"%");
            sql+=" and sname like #{stu.sname}";
        }
        if(st.getAddress()!=null && !"".equals(st.getAddress())){
            st.setAddress("%"+st.getAddress()+"%");
            sql+=" and address like #{stu.address}";
        }
        return sql;
    }

    public  String queryStudentBySql(Map map){
        Student st=(Student)map.get("stu");
        SQL sql=new SQL();
        sql.SELECT("*").FROM("student");
        if(st.getSname()!=null &&!"".equals(st.getSname())){
            st.setSname("%"+st.getSname()+"%");
            sql.WHERE(" sname like #{stu.sname}");
        }
        if(st.getAddress()!=null && !"".equals(st.getAddress())){
            st.setAddress("%"+st.getAddress()+"%");
            sql.AND();
            sql.WHERE(" address like #{stu.address}");
        }
        return sql.toString();
    }

    public String updateStudentSql(Map map){
        Student st=(Student)map.get("stud");
        SQL sql=new SQL();
        sql.UPDATE("student");
            if(st.getSname()!=null || !"".equals(st.getSname())){

                sql.SET("sname=#{stud.sname}");
            }
            if(st.getSex()!=null || !"".equals(st.getSex()) ){
                sql.SET("sex=#{stud.sex}");
            }

            if(st.getAge()!=null || !"".equals(st.getAge())){
                sql.SET("age=#{stud.age}");
            }
            sql.WHERE("sid=#{stud.sid}");
            return sql.toString();
    }   

    public String queryStudentAndGradeBySql(Map map){
        List<String> list=(List<String>)map.get("gradeList");
        SQL sql=new SQL();
        sql.SELECT("*").FROM("student");
        String str="";
        for (String stu : list) {
            str+=stu+",";
        }
        String st=str.substring(0, str.length()-1);
        sql.WHERE(" gid in ("+st+")");
        return sql.toString();
    }   
}
测试类

public class MyTest {
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson04/xml/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    /**
     * 通过学生id查询
     * @throws IOException
     */
    @Test
    public void queryStudentById() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        Student st=new Student();
        st.setSname("张");
        st.setAddress("深圳");
        List<Student>  list=sm.queryStudentById(st);
        for (Student stu : list) {
            System.out.println(stu.getSname());
        }
    }
    /**
     * 通过学生性别查询
     * @throws IOException
     */
    @Test
    public void queryBySexChoose() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        Integer sex=null;
        List<Student>  list=sm.queryBySex(sex);
        for (Student stu : list) {
            System.out.println(stu.getSname());
        }
    }

    /**
     * 修改学生信息
     */
    @Test
    public void updateStudent() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        Student st=new Student();
        st.setSid("1");
        st.setSname("张三三");
        sm.updateStudent(st);
        session.commit();
    }

    /**
     * 通过传入的班级查询所有的学生
     */
    @Test
    public void queryStudentAndGradeForEach() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        List list=new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        List<Student> lt=sm.queryStudentAndGrade(list);
        for (Student student : lt) {
            System.out.println(student.getSname());
        }
    }
}

Mybatis一级和二级缓存

Mybatis一级缓存为sqlSession级别的缓存 默认开启 相同的sqlsession对象 查询相同条件的结果时 存在一级缓存只会查询一次,sqlSession关闭后缓存失效 调用cleanCache后 缓存被清除,执行过增删改后缓存会被清除
二级缓存为sqlSessionFactory级别的缓存

/**
 * @author Administrator
 *
 */
public interface StudentMapper {
    /**
     * 通过编号查询学生
     * @param 
     * @return
     */
    public Student queryStudentById(String sid);
}
映射配置文件

<?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.et.lesson05.xml.StudentMapper">

  <!-- 二级缓存开启
  mybatis 默认缓存类FifoCache
  内存数据不足时需要一种机制 保证内存不出现溢出 需要将旧的数据清除 最先加入的数据最先清除
  LRU:最近在使用次数最少的被优先清除
  LFU:最近一段时间内使用次数最少 
  eviction="FIFO"默认是FIFO
  -->
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" type="com.et.lesson05.xml.RedisCache">
    </cache>
    <select id="queryStudentById" resultType="student">
        select * from student where sid=#{sid}
    </select>
</mapper>
mybatis.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>
    <!-- 是mybatis的核心配置
        1.数据库的连接信息
    告诉properties文件位置 -->
    <properties resource="com/et/lesson05/jdbc.properties"></properties>

    <!-- 二级缓存开启方式  也用不了要在映射文件中加<cache></cache>-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <!-- 给所有的类取别名 别名为类的首字母小写-->
    <typeAliases>
        <package name="com.et.lesson05.xml"/>
    </typeAliases>

<environments default="development">
<environment id="development">
    <!-- 事务管理器 默认使用jdbc的事务(自动提交) -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${url}" />
<property name="username" value="${username1}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
<!-- 键和sql语句映射 -->
<mappers>
    <mapper resource="com/et/lesson05/xml/StudentMapper.xml" />
</mappers>
</configuration> 
测试类

public class MyTest {

    /**
     * 用于二级缓存
     * @return
     * @throws IOException
     */
    public SqlSessionFactory getSessionFactory() throws IOException{
        String resource = "com/et/lesson05/xml/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        return  sqlSessionFactory;
    }

    /**
     * 用于一级缓存
     * @return
     * @throws IOException
     */
    public static SqlSession getSession() throws IOException{
        String resource = "com/et/lesson05/xml/mybatis.xml";
        //获取文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //工厂类
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //session 操作的是执行sql语句的一个唯一标识符
        SqlSession session=sqlSessionFactory.openSession();
        return  session;
    }

    /**
     * 通过学生id查询
     * 一级缓存 :同一个session对象针对同一份数据的查询产生的缓存
     * 第一次查询是调用数据 获取数据后
     * 通过session设置到一级缓存中
     * 第二次查询时 通过session一级缓存判断是否存在 相同的主键数据值 如果存在直接返回引用否则就查数据库
     * @throws IOException
     */
    //@Test
    public void queryStudentByIdToSqlSession() throws IOException{
        SqlSession session=getSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        Student st=sm.queryStudentById("1");
        //从缓存中查询
        Student st1=sm.queryStudentById("1");
        System.out.println(st==st1);
    }

    /***
     * 二级缓存:同一个sessionFactory下的不同session可以共享数据(二级缓存默认是没有开启)
     * @throws IOException
     */
    @Test
    public void queryStudentByIdToSessionFactory() throws IOException{
        SqlSessionFactory sessionFactory=getSessionFactory();
        SqlSession session=sessionFactory.openSession();
        SqlSession session1=sessionFactory.openSession();
        //获取接口
        StudentMapper sm=session.getMapper(StudentMapper.class);
        Student st=sm.queryStudentById("1");
        session.close();
        //获取接口
        StudentMapper sm1=session1.getMapper(StudentMapper.class);
        //从缓存中查询
        Student st1=sm1.queryStudentById("1");
        System.out.println(st==st1);
    }
}

自定义缓存

/**
 * 分布式环境
 */
import java.io.IOException;
import java.util.concurrent.locks.ReadWriteLock;

import org.apache.ibatis.cache.Cache;

import redis.clients.jedis.Jedis;

public class RedisCache implements Cache {
    /**
     * 操作redis对象
     */
    Jedis jedis=new Jedis("localhost",6379);
    private String cacheId;
    public RedisCache(String cacheId){
        this.cacheId=cacheId;

    }
    @Override
    public void clear() {
        //清空缓存
        //jedis.flushDB();
    }

    @Override
    public String getId() {
        return cacheId;
    }

    /**
     * mybatis自动调用getObject检测是否在缓存中存在
     */
    @Override
    public Object getObject(Object key) {
        try {
            byte[] bt=jedis.get(JavaReadis.objectToByteArrat(key));
            if(bt==null){
                return null;
            }
            return JavaReadis.byteArrayToObject(bt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return null;
    }

    @Override
    public int getSize() {
        return 0;
    }

    /**
     * mybatis读取数据是将数据库中读取的数据通过putObject设置到缓存中
     */
    @Override
    public void putObject(Object key, Object value) {
        //写入redis
        try {
            jedis.set(JavaReadis.objectToByteArrat(key), JavaReadis.objectToByteArrat(value));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * mybatis缓存策略 自动判断内存的大小 决定是否删除某些过期 久远的数据
     */
    @Override
    public Object removeObject(Object key) {
        Object obj=getObject(key);
        try {
            jedis.del(JavaReadis.objectToByteArrat(key));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return obj;
    }
}
学生实体类

/**
 * 查询学生时将班级也查出
 * @author Administrator
 *
 */
public class Student implements Serializable{
    private String sid;
    private String sname;
    private Integer sex;
    private Integer age;
    private String address;
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }

    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}
public class JavaReadis {

    /**
     * 将对象转成byte数组
     * 序列化
     * 写入数据到redis时调用
     * jedis.set("myname", "张三");
     * 默认mybatis是没有继承redis需要自己实现
     * @param obj
     * @return
     * @throws IOException 
     */

    public static byte[] objectToByteArrat(Object obj) throws IOException{
        //内存流
        ByteOutputStream bos=new ByteOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(obj);
        return bos.getBytes();
    }

    /**
     * 将byte数组转成对象
     * 反序列化
     * @param bt
     * @return
     * @throws IOException 
     * @throws ClassNotFoundException 
     */
    public static Object byteArrayToObject(byte[] bt) throws IOException, ClassNotFoundException{
        //内存流
        ByteInputStream bis=new ByteInputStream(bt,bt.length);
        // 反序列化
        ObjectInputStream ois=new ObjectInputStream(bis);
        return ois.readObject();
    }

    public static void main(String[] args) {
        Jedis jedis=new Jedis("localhost",6379);
        //键值对
        jedis.set("myname", "张三");
        System.out.println(jedis.get("myname"));
    }
}   

Mybatis集成Spring

步骤1.下载 mybatis-spring插件或者添加maven依赖

     <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>

步骤2.配置druid数据源
步骤3.配置SqlSessionFactoryBean设置数据源以及mybatis配置文件的位置
步骤四.配置SqlSessionTemplate 通过构造器注入SqlSessionFactoryBean
步骤五.配置DataSourceTransactionManager注入数据源配置事物
步骤六.配置MapperScannerConfigurer扫描注解对应的mapper文件对应的包
步骤七 配置spring事物的切面以及通知

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
    ">
    <!--spring是bean的容器(service+dao处理) 扫描 -->
    <context:component-scan base-package="com.et">
    <!-- 排除注解 -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <context:property-placeholder location="classpath:/jdbc.properties" />
    <!-- 所有数据库操作的源头实现子接口DataSource
        DriverManagerDataSource (请求产生一个连接 用完关闭 连接要重用 这样的机制叫连接池)
    -->
    <!-- 数据源只是为了获取连接池-->
    <bean id="dataSource"
        class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${url}"></property>
        <property name="username" value="${username1}"></property>
        <property name="password" value="${password2}"></property>
        <property name="driverClassName" value="${driverClass}"></property>
        <!-- 默认初始化的连接个数 -->
        <property name="initialSize" value="1"></property>
        <!--最大允许的连接个数 -->
        <property name="maxActive" value="200"></property>
        <!-- 最大的等待人数 -->
        <property name="maxIdle" value="100"></property>
        <!-- 监控sql 开启sql统计功能 -->
        <property name="filters" value="stat"></property>
    </bean>
    <!-- 通过spring集成mybatis  -->
    <!-- 配置session工厂 --> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接的数据源 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 构造器注入工厂 -->
        <constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg>
    </bean>
    <!-- 扫描mybatis的接口映射 (*..* 任意多层次的包两个以上的包) -->
    <bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.*.mapper"></property>
    </bean>
    <!-- 事务管理器 -->
    <bean id="tm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 提交连接事务 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 通知   并将事务管理器关联 -->
    <tx:advice id="txAdvice" transaction-manager="tm">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <!-- 只读 -->
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!-- 事务(*(返回值) com.*.service.*(类或接口).*(方法)(..)任意参数) -->
    <aop:config>
        <!--定义切点 -->
        <aop:pointcut expression="execution(* com.*.service.*.*(..))" id="myPointCut"/>
        <!--关联切点和事务的管理器 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/>
    </aop:config>
</beans>
springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
    ">
    <!--springmvc控制层处理+视图层 扫描 -->
    <context:component-scan base-package="com.et">
    <!-- 排除注解 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
    <context:property-placeholder location="classpath:/jdbc.properties" />
    <!-- 引用返回对象 响应json -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <!-- 配置返回字节数组解析成json的消息转换器 -->
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                    <!-- 设置响应支持的类型 -->
                        <value>text/html;charset="UTF-8"</value>
                        <!-- 设置请求body支持的类型 -->
                        <value>application/x-www-form-urlencoded</value>
                    </list>
                </property>
            </bean>
            <!-- 配置返回对象解析成json的消息转换器 -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                    <!-- 设置响应支持的类型 -->
                        <value>text/html;charset="UTF-8"</value>
                        <!-- 设置请求body支持的类型 -->
                        <value>application/x-www-form-urlencoded</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
   <!-- 
    ================================================
        spring配置
    ================================================
   -->
    <!-- spring配置文件位置 -->
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
     </context-param>  
     <!-- 配置监听 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>  


  <!-- 
    ================================================
        springmvc配置
    ================================================
   -->
  <!-- 请求method支持put和delete必须添加过滤器 支持rest风格-->
    <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  <!-- springmvc的核心配置 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定springmvc的配置文件名称 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mymvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
        <filter>
        <filter-name>Filter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 启用druid的监控功能 -->
    <servlet>
        <servlet-name>mydruid</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
        <init-param>
            <param-name>loginUsername</param-name>
            <param-value>admin</param-value>
        </init-param>
        <init-param>
            <param-name>loginPassword</param-name>
            <param-value>admin</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mydruid</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>
</web-app>
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>SSMA</groupId>
  <artifactId>SSMA</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name/>
  <description/>
  <dependencies>

  <!-- springmvc的配置-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.0.RELEASE</version>
    </dependency>
    <!-- 事务的配置 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.2.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.0.RELEASE</version>
    </dependency>
    <!-- 事务的配置 -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.12</version>
        </dependency>
    <!-- (druid)连接池的配置 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.5</version>
    </dependency>
    <!-- mybatis集成spring -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>
      <!-- 配置mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.2.8</version>
    </dependency>
        <!-- 添加jacson的json解析库  -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-core-asl</artifactId>
      <version>1.9.12</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.6.0</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.12</version>
    </dependency>
    <!-- mysql的配置 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.26</version>
    </dependency>

    <dependency>
      <groupId>org.apache.openejb</groupId>
      <artifactId>javaee-api</artifactId>
      <version>5.0-1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>1.2_04</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>1.2_04</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>
  <build>
    <sourceDirectory>${basedir}/src</sourceDirectory>
    <outputDirectory>${basedir}/WebRoot/WEB-INF/classes</outputDirectory>
    <resources>
      <resource>
        <directory>${basedir}/src</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <webappDirectory>${basedir}/WebRoot</webappDirectory>
          <warSourceDirectory>${basedir}/WebRoot</warSourceDirectory>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

目录结构:

这里写图片描述

@Controller
public class MyFoodController {
    @Autowired
    MyFoodService ms;

    /**
     *第三种直接返回对象  springmvc自动转成json(默认是不可以 需要消息转换器(MappingJackson2HttpMessageConverter)
     *会覆盖字节数组的消息转换器所有同时加字节数组的消息转换器ByteArrayHttpMessageConverter)
     *添加注解@ResponseBody
     */
    @ResponseBody
    @RequestMapping(value="/queryAllList",method={RequestMethod.GET})
    public List<Map<String, Object>> foodMap(String foodname) throws UnsupportedEncodingException, IOException{
        List<Map<String, Object>> queryFood=ms.queryAllFood(foodname);
        return queryFood;

    }
    /**
     * 删除方法
     */
    @RequestMapping(value="/food/{foodid}",method=RequestMethod.DELETE)
    public String deleteFood(@PathVariable String foodid,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
        try {
            ms.deleteFood(foodid);
            os.write("1".getBytes("UTF-8"));

        } catch (Exception e) {
            os.write("0".getBytes("UTF-8"));
        }
        return null;
    }
    /**
     * 添加方法
     */
    @RequestMapping(value="/food",method={RequestMethod.POST})
    public String saveFood(String foodName,String price,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
        try {
            ms.saveFood( foodName, price);
            os.write("1".getBytes("UTF-8"));
        } catch (Exception e) {
            os.write("0".getBytes("UTF-8"));
        }
        return null;
    }
    /**
     * 修改方法
     */
    @RequestMapping(value="/food/{foodid}",method={RequestMethod.PUT})
    public String updateFood(@PathVariable String foodid,String foodName,String price,OutputStream os,HttpServletResponse response) throws UnsupportedEncodingException, IOException{
        try {
            ms.updateFood(foodid, foodName, price);
            os.write("1".getBytes("UTF-8"));
        } catch (Exception e) {
            os.write("0".getBytes("UTF-8"));
        }
        return null;
    }
}
public interface MyFoodDao {
    /**
     * 查询
     * @param foodname
     * @return
     */
    public abstract List<Map<String, Object>> queryAllFood(String foodname);
    /**
     * 删除
     * @param foodId
     */
    public abstract void deleteFood(String foodId);
    /**
     * 添加
     * @param foodName
     * @param price
     */
    public abstract void saveFood(String foodName, String price);
    /**
     * 修改
     * @param foodId
     * @param foodName
     * @param price
     */
    public abstract void updateFood(String foodId, String foodName, String price);
}

@Repository
public class MyFoodDaoImpl implements MyFoodDao {
    @Autowired
    FoodMapper mapper;

    public List<Map<String, Object>> queryAllFood(String foodname){
        return mapper.queryAllFood(foodname);

    }
    public void deleteFood(String foodId){
        mapper.deleteFood(foodId);
    }
    public void saveFood(String foodName,String price){
        mapper.saveFood(foodName, price);
    }
    public void updateFood(String foodId,String foodName,String price){
        mapper.updateFood(foodId, foodName, price);
    }
}
public interface MyFoodService {
    /**
     * 查询
     * @param foodname
     * @return
     */
    public abstract List<Map<String, Object>> queryAllFood(String foodname);
    /**
     * 删除
     * @param foodId
     */
    public abstract void deleteFood(String foodId);
    /**
     * 添加
     * @param foodName
     * @param price
     */
    public abstract void saveFood(String foodName, String price);
    /**
     * 修改
     * @param foodId
     * @param foodName
     * @param price
     */
    public abstract void updateFood(String foodId, String foodName, String price);
}


@Service
public class MyFoodServiceImpl implements MyFoodDao, MyFoodService {

    @Autowired
    MyFoodDao dao;
    public List<Map<String, Object>> queryAllFood(String foodname){

        return dao.queryAllFood(foodname);
    }
    public void deleteFood(String foodId){
        dao.deleteFood(foodId);
    }
    public void saveFood(String foodName,String price){
        dao.saveFood(foodName, price);
    }
    public void updateFood(String foodId,String foodName,String price){
        dao.updateFood(foodId, foodName, price);
    }
}
public interface FoodMapper {
    /**
     * 查询
     */
    @Select("select * from food where foodname like '%${foodname}%'")
    public List<Map<String, Object>> queryAllFood(@Param("foodname")String foodname);
    /**
     * 删除
     */
    @Delete("delete from food where foodid=#{0}")
    public void deleteFood(String foodId);
    /**
     * 添加
     */
    @Insert("insert into food(foodid,foodname,price) values((select IFNULL(max(foodid),0)+1 from food f),#{0},#{1})")
    public void saveFood(String foodName,String price);
    /**
     * 修改
     */
    @Update("update food set foodname=#{1},price=#{2} where foodid=#{0}")
    public void updateFood(String foodId,String foodName,String price);
}

通过ajax实现

WEB-INF/food.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>My JSP 'food.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <script type="text/javascript">
        function sendAjax(url,methodType,param,retnFunction){
            //调用http://localhost:8080/SpringMvcDay/queryAll 获取数据通过dom方法添加到table中
                //ajax(异步)+json

                var xmlhttp = null;
                //兼容所有的浏览器创建这个对象(简称XHR对象)
                if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
                    xmlhttp = new XMLHttpRequest();
                } else {// code for IE6, IE5
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }

                    //匿名函数  不需要调的函数叫回调函数  当请求发送后回自动调用该方法
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        retnFunction(xmlhttp.responseText);
                    }
                }
                if(methodType=="get" || methodType=="GET"){
                    //open方法表示产生一个请求的关联(get 提交)
                    xmlhttp.open("GET",url+"?"+param, true);
                    xmlhttp.send();
                }else{
                //open方法表示产生一个请求的关联(POST 提交)
                xmlhttp.open("POST",url, true);
                xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=UTF-8");
                xmlhttp.send(param);
                }
        }
            function query() {
                var foodname=document.getElementsByName("foodName")[0].value;
                sendAjax("${pageContext.request.contextPath}/queryAllList","GET","foodname="+foodname,function(responseText){
                    //返回字符串的json
                var resultJson = responseText;
                //转换为js对象
                var resultObj = JSON.parse(resultJson);
                //获取table对象
                var table = document.getElementById("myTable");
                //将所有名字为dataTr的tr全部删除
                var allDataTr = document.getElementsByName("dataTr");
                var length = allDataTr.length;
                for ( var i = 0; i < length; i++) {
                    table.removeChild(allDataTr[0]);
                }

                //根据json的行数追加多个tr
                for ( var i = 0; i < resultObj.length; i++) {
                    var obj = resultObj[i];
                    //创建<td>
                    var tid = document.createElement("td");
                    //将内容添加到td中
                    tid.innerText = obj.foodid;
                    var tname = document.createElement("td");
                    tname.innerText = obj.foodname;
                    var tprice = document.createElement("td");
                    tprice.innerText = obj.price;
                    var td2=document.createElement("td");
                    //删除按钮
                    var ib=document.createElement("button");
                    ib.innerText="删除";
                    td2.appendChild(ib);
                    //修改按钮
                    var ib1=document.createElement("button");
                    ib1.innerText="修改";
                    td2.appendChild(ib1);
                    //创建<tr>
                    var tr = document.createElement("tr");
                    //将当前对象绑定到当前按钮
                    ib.foodObj=obj;
                    //将当前行的tr绑定当按钮上
                    ib.myLineTr=tr;
                    //删除按钮事件
                    ib.addEventListener("click",function(){
                        //获取按钮
                        var eventStr=event.srcElement;
                        //删除当前行+发送ajax请求到后台删除数据库
                        table.removeChild(eventStr.myLineTr);
                        sendAjax("${pageContext.request.contextPath}/food/"+ib.foodObj.foodid,"POST","_method=delete",function(responseText){
                         if(responseText==1)
                            alert("删除成功");
                         else{
                            alert("删除失败");
                         }
                      });
               });
               //将当前对象绑定到当前按钮
                ib1.foodObj=obj;
               //修改按钮事件
                ib1.addEventListener("click",function(){
                    //获取按钮
                    var eventStr=event.srcElement;
                    document.getElementById('updateDiv').style.display='block';
                    document.getElementsByName("updateFoodName")[0].value=eventStr.foodObj.foodname;
                    document.getElementsByName("updateFoodPrice")[0].value=eventStr.foodObj.price;
                    document.getElementsByName("updateFoodId")[0].value=eventStr.foodObj.foodid;
                });

                    tr.setAttribute("name", "dataTr");
                    tr.appendChild(tid);
                    tr.appendChild(tname);
                    tr.appendChild(tprice);
                    tr.appendChild(td2);
                    table.appendChild(tr);
                }
            });
        }
/**
  新增的方法
*/
function saveFood(){
   var myFoodName=document.getElementsByName("myFoodName")[0].value;
   var myFoodPrice=document.getElementsByName("myFoodPrice")[0].value;
   sendAjax("${pageContext.request.contextPath}/food","POST","foodName="+myFoodName+"&price="+myFoodPrice,function(responseText){
         if(responseText==1){
            document.getElementById('addDiv').style.display='none';
            query();
            alert("新增成功");

         }else{
            alert("新增失败");
         }
    });
}

/**
  修改的方法
*/
function updateFood(){
   var myFoodName=document.getElementsByName("updateFoodName")[0].value;
   var myFoodPrice=document.getElementsByName("updateFoodPrice")[0].value;
   var myFoodId=document.getElementsByName("updateFoodId")[0].value;
   sendAjax("${pageContext.request.contextPath}/food/"+myFoodId,"POST","_method=put&foodName="+myFoodName+"&price="+myFoodPrice,function(responseText){
                     if(responseText==1){
                        document.getElementById('updateDiv').style.display='none';
                        query();
                        alert("修改成功");

                     }else{
                        alert("修改失败");
                     }
    });
}
    </script>
    </head>
    <body>
        <input type="text" name="foodName" id="foodName">
        <input type="button" value="查询" onclick="query()">
        <input type="button" value="添加" onclick="document.getElementById('addDiv').style.display='block';">
        <table id="myTable" border="1">
            <tr>
                <th>菜品编号</th>
                <th>菜品名</th>
                <th>菜品价格</th>
                <th>操作</th>
            </tr>
        </table>
    </body>
    <div id="addDiv" style="display:none;position: absolute;left:45%;z-index: 100;border:1px solid black;width: 240px;height: 65px">
        菜品名&nbsp;:<input type="text" name="myFoodName"><br/>
        菜品价格:<input type="text" name="myFoodPrice"><br/>
            <input type="button" value="保存" onclick="saveFood()">&nbsp;<input type="button" value="关闭" onclick="document.getElementById('addDiv').style.display='none';">
    </div>

    <div id="updateDiv" style="display:none;position: absolute;left:45%;z-index: 100;border:1px solid black;width: 240px;height: 90px">
        <input type="hidden" name="updateFoodId"><br/>
        菜品名&nbsp;:<input type="text" name="updateFoodName"><br/>
        菜品价格:<input type="text" name="updateFoodPrice"><br/>
            <input type="button" value="修改" onclick="updateFood()">&nbsp;<input type="button" value="关闭" onclick="document.getElementById('updateDiv').style.display='none';">
    </div>
</html>

MyBatis使用Generator自动生成代码

一、在pom.xml中添加plugin

<!-- 代码生成工具的配置 -->
  <build>
    <plugins>
        <plugin>
          <groupId>org.mybatis.generator</groupId>
          <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.5</version>
          <configuration>
            <configurationFile>src/main/java/mbg.xml</configurationFile>
          </configuration>
        </plugin>
    </plugins>
  </build>

二、generatorConfig.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 生成代码需要的步骤
        1.连接数据库(驱动包 四要素)
     -->
  <classPathEntry location="E:\mysql-connector-java-5.1.26-bin.jar" />
    <!-- 设置生成代码的规则
        targetRuntime="MyBatis3"开发环境使用mybatis的版本 
     -->
  <context id="DB2Tables" targetRuntime="MyBatis3">
  <!-- 配置mysql的四要素 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/food"
        userId="root"
        password="123456">
    </jdbcConnection>
    <!--  -->
    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    <!--实体类bean 带有get set  -->
    <javaModelGenerator targetPackage="com.et.entity" targetProject="src/main/java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    <!--sql语句相关的xml或注解的生成包路径  -->
    <sqlMapGenerator targetPackage="com.et.resources"  targetProject="src/main/java">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    <!-- 生成接口的位置 
        type="XMLMAPPER" 生成xml
        type="ANNOTATEDMAPPER" 生成注解
    -->
    <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.et.dao"  targetProject="src/main/java">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>
    <!--告诉mbg需要生成代码的表
    schema="DB2ADMIN"用于oracle中
      -->
    <table tableName="food" >

    </table>

  </context>
</generatorConfiguration>

完整版

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

  <!-- 配置mysql 驱动jar包路径.用了绝对路径 -->
  <classPathEntry location="D:\Work\Java\eclipse\workspace\myBatisGenerator\WebContent\WEB-INF\lib\mysql-connector-java-5.1.22-bin.jar" />

  <context id="yihaomen_mysql_tables" targetRuntime="MyBatis3">

    <!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制 -->
    <commentGenerator>
      <property name="suppressAllComments" value="true" />
      <property name="suppressDate" value="true" />
    </commentGenerator>
    <!-- 注释控制完毕 -->

    <!-- 数据库连接 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8"
        userId="root"
        password="password">
    </jdbcConnection>

    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>

    <!-- 数据表对应的model 层  -->
    <javaModelGenerator targetPackage="com.yihaomen.model" targetProject="src">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

    <!-- sql mapper 隐射配置文件 -->
    <sqlMapGenerator targetPackage="com.yihaomen.mapper"  targetProject="src">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

    <!-- 在ibatis2 中是dao层,但在mybatis3中,其实就是mapper接口 -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.yihaomen.inter"  targetProject="src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

    <!-- 要对那些数据表进行生成操作,必须要有一个. -->
    <table schema="mybatis" tableName="category" domainObjectName="Category" 
        enableCountByExample="false" enableUpdateByExample="false"
        enableDeleteByExample="false" enableSelectByExample="false"
        selectByExampleQueryId="false">     
    </table>

  </context>
</generatorConfiguration>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值