MyBatis学习笔记

MyBatis框架简介

开发中要考虑代码的性能:

①避免多表查询;

②避免过多的复杂的逻辑循环控制;

③避免同一数据的重复查询处理,使用缓存机制进行处理。

MyBatis设计思想:(不考虑数据库移植,这也是最大缺点)

①代码更加简单

②不过多考虑复杂的数据库操作

最大优点:体积小,响应速度快(王道),避免了复杂的逻辑性的操作,提供映射支持

与Hibernate区别:

①面对数据库的移植操作,Hibernate一定是不二选择(但如果是不需要数据库移植的环境,Hibernate没有优势)

②Hibernate根据配置文件动态转换为SQL语句(缺点:复杂度高)

③Hibernate配置复杂,如果配置不当,直接带来严重的性能问题

开发第一个MyBatis

搭建MyBatis开发环境(实现数据增加操作):导入包,编写mybatis.cfg.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>
    <!--    数据库的连接配置-->
    <environments default="development">
        <environment id="development">
        <!--        使用JDBC来实现数据库的事务控制    -->
            <transactionManager type="jdbc"></transactionManager>
        <!--    连接类型        -->
        <!--    POOLED:表示所有的数据库连接都要在数据库连接池之中保存,性能最好        -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="mysqladmin"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

编写vo类,然后编写映射文件

<?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="ycit.sth.vo.mapping.MemberNS">
<!--    定义数据增加所使用的SQL语句,id为调用名称,与命名空间结合使用,不能够重复-->
    <insert id="doCreate" parameterType="ycit.sth.vo.Member">
        INSERT INTO `member`(mid,name,age,birthday,salary) VALUES(#{mid},#{name},#{age},#{birthday},#{salary})
    </insert>
</mapper>  

所有的映射文件必须在mybatis.cfg.xml中进行映射

<!--    编写映射文件的路径-->
    <mappers>
        <mapper resource="ycit/sth/vo/mapping/Member.xml"></mapper>
    </mappers>

MyBatis使用的操作类:读取配置Reader    连接工厂SqlSessionFactory   连接对象SqlSession

对比Hibernate:读取配置Configuration   连接工厂SessionFactory  连接对象Session

配置测试类

public class TestMemberInsert {
    public static void main(String[] args) throws Exception{
        //1.读取myBatis的核心配置文件 mybatis.cfg.xml
        Reader reader= Resources.getResourceAsReader("mybatis.cfg.xml");
        //2.创建SqlSessionFactory工厂类
        SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(reader);
        //3.通过工厂类取得SqlSession对象
        SqlSession session=factory.openSession();
        //4.进行数据的保存
        Member vo=new Member();
        vo.setMid("小哥");
        vo.setName("张起灵");
        vo.setAge(100);
        vo.setBirthday(new Date());
        vo.setSalary(888888.88);
        int len=session.insert("ycit.sth.vo.mapping.MemberNS.doCreate",vo);//设置要执行的SQL语句
        session.commit();
        System.out.println("操作影响的行数:"+len);
        session.close();
        reader.close();
    }
}

问题1:如果id是自动增长列,要取得增长后的id 值,增加配置即可,无需再写一条SQL语句

<insert id="" parameterType="" keyProperty="自动增长列" useGeneratedKeys="true">SQL语句</insert>

问题2:配置文件内每次配置参数都要加上包.名称(j见上面蓝色),太长,不方便维护,在mybatis.cfg.xml可以进行别名设置

<!--    别名设置-->
    <typeAliases>
        <package name="ycit.sth.vo"/>
    </typeAliases>

 配置日志

拷贝log4j.properties文件及所需的jar包

让日志文件进行输出显示,必须手工修改log4j.properties文件

log4j.logger.ycit.sth.vo.mapping.MemberNS=TRACE   命名空间

写包名该包下的所有xml都可以日志输出

自定义MyBatisSessionFactory

/**
 * ClassName:MyBatisSessionFactory
 * Package:ycit.sth.util
 * Description: 本类主要负责SqlSessionFactory与SqlSession接口对象的取得
 * 以及负责重新连接以及关闭的处理操作
 * @Date:2021/2/1 12:20
 * Author:沙天慧
 */
public class MyBatisSessionFactory {
    private static final String CONFIG_FILE="mybatis.cfg.xml";
    //保存SqlSession接口对象,主要被不同的层做引用操作
    private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<SqlSession>();
    //用于通过它操作二级缓存以及重新取得SqlSession的配置
    private static SqlSessionFactory factory=null;
    //主要是读取mybatis.cfg.xml文件
    private static InputStream input=null;
    static {
        rebuildSessionFactory();  //静态代码块,在类加载的时候创建SqlSessionFactory接口对象
    }
    /**
     * 取得当前连接的SqlSession对象,如果没有,则通过SqlSessionFactory创建新的SqlSession,
     * 如果当前存在该对象,则通过ThreadLocal取得
     * @return  SqlSession对象
     */
    public static SqlSession getSession(){
        SqlSession session=threadLocal.get();//通过ThreadLocal取得
        if (session==null){  //没有SqlSession对象
            if (factory==null){   //没有工厂
                rebuildSessionFactory();;
            }
            session=factory.openSession();  //创建新的session对象
            threadLocal.set(session);
        }
        return session;
    }
    public static SqlSessionFactory getSessionFactory(){
        return factory;
    }

    /**
     * 重新建立新的SqlSessionFactory对象
     */
    public static void rebuildSessionFactory(){
        try {
            input= Resources.getResourceAsStream(CONFIG_FILE);
            factory= new SqlSessionFactoryBuilder().build(input);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void close(){
        SqlSession session=threadLocal.get();
        threadLocal.set(null);
        if (session!=null){
            session.close();
            if (input!=null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

更新删除操作

    <update id="doUpdate" parameterType="News">
        UPDATE news  SET title=#{title},pubdate=#{pubdate}   WHERE nid=#{nid}
    </update>
    <delete id="doRemove" parameterType="int">
        delete FROM news WHERE nid=#{id}       一个参数随便什么名字都可以
    </delete>

查询操作

当数据库的列名和属性名不一致时,除了在SQL语句写上别名,最好的方法是设置映射关系,在每个映射文件中配置。

<!--    结果转换映射-->
<resultMap id="NewsResultMap" type="News">
        <id property="nid" column="nid"></id>
        <result property="title" column="title"></result>
        <result property="pubdate" column="pubdate"></result>
</resultMap>
<select id="findById" parameterType="int" resultMap="NewsResultMap">        //查询单个数据
        select nid,title,pubdate FROM news WHERE nid=#{id}
</select>

数据的分页查询

MyBatis对于参数的传递分为两种形式:

  ①以内容替换的方式设置参数:${替换变量}

  ②传递的操作的数值:#{内容}

<!--    分页查询  -->
<!--    Map集合的特点是根据Key取得对应的value数据,MyBatis里发现有多个参数就传Map-->
    <select id="findAllSplit" resultMap="NewsResultMap" parameterType="java.util.Map">
        SELECT nid,title,pubdate FROM news WHERE ${column} LIKE #{keyword}  LIMIT #{start},#{lineSize}</select>
<!--    统计数据行数-->
    <select id="getAllCountSplit" resultType="int" parameterType="java.util.Map">
        SELECT COUNT(*) FROM news WHERE ${column} LIKE #{keyword}
    </select>

缓存机制

缓存可以减少数据库的访问操作,以达到性能的提升。

MyBatis提供两类缓存,一级缓存(SqlSession级,永远存在)、二级缓存(SqlSessionFactory,需要进行配置)

一级缓存

更改缓存数据会影响后续数据的查询,但不会修改数据库的数据

如果之前的数据发生事务提交处理,会将缓存的数据清除掉,如果有需要,可以利用SqlSession接口的方法clearCache()手工进行缓存的清除

二级缓存

二级缓存的配置:

修改mybatis.cfg.xml:

<settings>
    <!--    启用二级缓存配置    -->
    <setting name="cacheEnabled" value="true"/>
</settings>

在你需要缓存的对象上(*.xml)进行缓存的配置  加上<cache/>

【注】

①第一个Session关闭后才能将内容写入缓存

②要进行缓存的对象所在的类必须实现Serializable接口,负责出错

对于不需要使用二级缓存的单独配置  useCache=false

默认缓存所使用的缓存处理算法:LRU(最近最少使用算法)

动态SQL

利用配置文件来实现判断与循环的效果

if 语句

<select id="findAllByTitle" parameterType="News" resultMap="NewsResultMap">
        SELECT nid ,title,pubdate FROM news
        <if test="title!=null">
            WHERE title=#{title}
        </if>
</select>

不传参数就查询全部,此时的SQL语句可以动态的进行处理

choose语句

当我们不想使用所有的查询条件,只想选择其中的一个,此时使用choose标签可以解决问题

实现当nid不空时根据nid查,当nid为空title不空时根据title查,当nid,title均为空时,根据pubdate查,都为空,查询全部

<select id="" parameterType="News" resultMap="NewsResultMap">
        SELECT nid ,title,pubdate FROM news
        <where>
            <choose>
                <when test="nid!=''and  nid!=null">nid=#{nid}</when>
                <when test="title!=''and  title!=null">title=#{title}</when>
                <when test="pubdate!=''and  pubdate!=null">pubdate=#{pubdate}</when>
            </choose>
        </where>
</select>

foreach语句

其标签的属性:

collection:collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合。
item :表示在迭代过程中每一个元素的别名
index :表示在迭代过程中每次迭代到的位置(下标)
open :前缀
close :后缀
separator :分隔符,表示迭代时每个元素之间以什么分隔

查询 id为1,2,3的信息

<select id="" parameterType="java.util.List" resultMap="NewsResultMap">
        SELECT nid ,title,pubdate FROM news WHERE nid IN 
        <foreach collection="list" index="index" item="nid" open="(" separator="," close=")">#{nid}</foreach>
</select>

set语句

当在update中使用if标签,如果有if没有执行,会因为多余的逗号导致错误。使用 set 标签可以将动态的配置 set关键字,和剔除追加到条件末尾的任何不相关的逗号。使用 set+if 标签修改后,如果某项为 null 则不进行更新,而是保持数据库原值。

<update id="findAllByTitle" parameterType="News" >
        UPDATE news
        <set>
            <if test="title !='' and title !=null">title=#{title},</if>
            <if test="pubdate !=null">pubdate=#{pubdate}</if>
        </set>
        WHERE nid=#{nid}
</update>

Annotation配置

写完DAO接口,一般要实现其子类,也可以使用注解配置

public interface INewsDAO {
    @Insert("INSERT INTO news(title,pubdate) VALUES(#{title},#{pubdate})")
    @SelectKey(before = false,keyProperty = "nid",resultType = java.lang.Integer.class,statement = "SELECT LAST_INSERT_ID()")
    public boolean doCreate(News vo) throws Exception;  //返回主键,before = false表示在执行之后
   @Update("UPDATE news  SET title=#{title},pubdate=#{pubdate}   WHERE nid=#{nid}")
    public boolean doUpdate(News vo) throws Exception;
   @Delete("DELETE FROM news WHERE nid=#{id}")
    public boolean doRemove(Integer id) throws Exception;
   @Select("SELECT nid,title,pubdate FROM news WHERE nid=#{id}")
    public News findById(Integer id) throws Exception;
    @Select("SELECT nid,title,pubdate FROM news ")
    public List<News> findAll() throws Exception;
    @Select("SELECT nid,title,pubdate FROM news WHERE #{column} LIKE #{keyword}  LIMIT #{start},#{lineSize}")
    public List<News> findAllSplit(
            @Param("column") String column,
            @Param("keyword") String keyword,
            @Param("currentPage") Integer currentPage,
            @Param("lineSize")Integer lineSize) throws  Exception;
    @Select("SELECT COUNT(*) FROM news WHERE ${column} LIKE #{keyword}")
    public Integer getAllCount(
            @Param("column") String column,
            @Param("keyword") String keyword) throws Exception;
}

如果要使用这个接口进行数据操作,要修改MyBatisSessionFactory.java

 public static void rebuildSessionFactory(){
        try {
            input= Resources.getResourceAsStream(CONFIG_FILE);
            factory= new SqlSessionFactoryBuilder().build(input);
            factory.getConfiguration().addMappers("ycit.sth.dao");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Annotation不能够实现实现动态SQL,所以在项目中不会使用。

识别器

识别器指的是在一张数据表中可以描述多种实体的关系

Member有两个子类Student,Worker,  根据id查询返回结果是student还是worker根据flag标记

<mapper namespace="ycit.sth.vo.mapping.MemberNS">
<!--    resultMap是在查询返回结果的时候才会起作用,那么就意味着数据的更新跟此配置无关-->
    <resultMap id="MemberResultMap" type="Member">
        <id property="mid" column="mid"></id>
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
        <discriminator javaType="String" column="flag">
            <case value="学生" resultType="Student">
                <result property="score" column="score"></result>
                <result property="school" column="school"></result>
            </case>
            <case value="工人" resultType="Worker">
                <result property="company" column="company"></result>
                <result property="salary" column="salary"></result>
            </case>
        </discriminator>
    </resultMap>
    <insert id="doCreateStudent" parameterType="Student">
        INSERT INTO `member` (mid,name,age,flag,school,score) VALUES(#{mid},#{name},#{age},'学生',#{school},#{score})
    </insert>
    <insert id="doCreateWorker" parameterType="Worker">
        INSERT INTO `member` (mid,name,age,flag,company,salary) VALUES(#{mid},#{name},#{age},'工人',#{company},#{salary})
    </insert>
    <select id="findByStudentId" parameterType="String" resultMap="MemberResultMap">
        SELECT mid,name,age,flag,school,score FROM `member` WHERE mid=#{mid} AND flag='学生'
    </select>
    <select id="findByWorkerId" parameterType="String" resultMap="MemberResultMap">
        SELECT mid,name,age,flag,company,salary FROM `member` WHERE mid=#{mid} AND flag='工人'
    </select>
</mapper>  

一对一数据关联

两张表memebr_login, member_details,一对一关系

MemberLogin.xml

<mapper namespace="ycit.sth.vo.mapping.MemberLoginNS">
    <resultMap id="MemberLoginResultMap" type="MemberLogin">
        <id property="mid" column="mid"></id>
        <result property="password" column="password"></result>
<!--    该级联操作发生在数据查询的时候进行,表示查询返回的是MemberLoginResultMap时,执行级联    -->
        <association property="details" javaType="MemberDetails" column="mid" select="ycit.sth.vo.mapping.MemberDetailsNS.findById"></association>
    </resultMap>
    <select id="findById" parameterType="java.lang.String" resultMap="MemberLoginResultMap">
        SELECT mid,password FROM member_login WHERE mid=#{mid}
    </select>
    <insert id="doCreate" parameterType="MemberLogin">
        INSERT INTO member_login(mid,password) VALUES(#{mid},#{password})
    </insert>
</mapper>  

MemberDetails.xml

<mapper namespace="ycit.sth.vo.mapping.MemberDetailsNS">
    <resultMap id="MemberDetailsResultMap" type="MemberDetails">
        <id property="mid" column="mid"></id>
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
    </resultMap>
    <select id="findById" parameterType="java.lang.String" resultMap="MemberDetailsResultMap">
        SELECT mid,name,age FROM member_details WHERE mid=#{mid}
    </select>
    <insert id="doCreate" parameterType="MemberDetails">
        INSERT INTO member_details(mid,name,age) VALUES(#{mid},#{name},#{age})
    </insert>
</mapper>  

一对多数据关联(重难点)

两张表 type 和subtype

【注】如果使用级联操作,select="ycit.sth.vo.mapping.SubTypeNS.findByType"  ,会出现1+N次查询,不合适,千万不能使用

Type.xml

<mapper namespace="ycit.sth.vo.mapping.TypeNS">
    <resultMap id="TypeResultMap" type="Type">
        <id property="tid" column="tid"></id>
        <result property="title" column="title"></result>
        <collection property="subTypes"  column="tid" javaType="java.util.List" ofType="SubType"></collection>  这个地方注意上面的注
    </resultMap> 
    <insert id="doCreate" parameterType="Type">
        INSERT INTO type(title) VALUES(#{title})
    </insert>
    <select id="findById" parameterType="Integer" resultMap="TypeResultMap">
        SELECT tid,title FROM type WHERE tid=#{tid}
    </select>
</mapper>  

SubType.xml

<mapper namespace="ycit.sth.vo.mapping.SubTypeNS">
    <resultMap id="SubTypeResultMap" type="SubType">
        <id property="stid" column="stid"></id>
        <result property="title" column="title"></result>
        <association property="type" javaType="Type" column="tid" resultMap="ycit.sth.vo.mapping.TypeNS.TypeResultMap"></association>
    </resultMap>
    <insert id="doCreate" parameterType="SubType">
        INSERT INTO subtype(title,tid) VALUES(#{title},#{type.tid})
    </insert>
    <select id="findById" parameterType="Integer" resultMap="SubTypeResultMap">   注意一下
        SELECT stid,title,tid FROM subtype WHERE stid=#{stid}
    </select>
    <select id="findByType" parameterType="Integer" resultMap="SubTypeResultMap">
        SELECT stid,title,tid FROM subtype WHERE tid=#{tid}
    </select>
</mapper>  

多对多数据映射(重难点)

MyBatis没有所谓的多对多的映射支持,使用的是一对多的概念来实现多对多的应用。

使用角色和权限的例子

创建  Role.java  Groups.java  RoleGroupsLink.java

public class RoleGroupsLink implements Serializable {
    private Role role;
    private Groups groups;
}

Role.xml

<mapper namespace="ycit.sth.vo.mapping.RoleNS">
    <resultMap id="RoleResultMap" type="Role">
        <id property="rid" column="rid"></id>
        <result property="title" column="title"></result>
        <collection property="allGroups"  javaType="java.util.List" ofType="Groups"
        resultMap="ycit.sth.vo.mapping.GroupsNS.GroupsResultMap"></collection>  灰色可不写
    </resultMap>
<!--    角色增加要有生成的id取得,用于关系表的维护-->
    <insert id="doCreate" parameterType="Role" keyProperty="rid" useGeneratedKeys="true">
        INSERT INTO role(title) VALUES(#{title})
    </insert>
    <insert id="doCreateRoleGroups" parameterType="RoleGroupsLink">
        INSERT INTO role_groups(rid,gid) VALUES(#{role.rid},#{groups.gid})
    </insert>
    <update id="doUpdate" parameterType="Role">
        UPDATE role SET title=#{title} WHERE rid=#{rid}
    </update>
    <delete id="doRemoveRoleGroups" parameterType="int">
        DELETE  FROM role_groups WHERE rid=#{rid}
    </delete>
</mapper>  

Groups.xml

<mapper namespace="ycit.sth.vo.mapping.GroupsNS">
    <resultMap id="GroupsResultMap" type="Groups">
        <id property="gid" column="gid"></id>
        <result property="title" column="title"></result>
        <collection property="allRoles"  javaType="java.util.List" ofType="Role"></collection>
    </resultMap>
    <select id="findAllByRole" parameterType="int" resultMap="GroupsResultMap">
        SELECT gid,title FROM `groups` WHERE gid IN ( SELECT gid FROM role_groups WHERE rid=#{rid})
    </select>
</mapper>  

【注】

①role数据增加时,必须设置好role_groups表的数据

public class TestRoleAdd {
    public static void main(String[] args) {
        int gids[]=new int[]{1,2,4};
        Role role=new Role();
        role.setTitle("sth");
        //先保存角色数据,保存之后取得角色编号,才可以向role_groups表中添加数据
        if (MyBatisSessionFactory.getSession().insert("ycit.sth.vo.mapping.RoleNS.doCreate",role)>0){
            int rid=role.getRid();
            for (int i=0;i<gids.length;i++){
                RoleGroupsLink vo=new RoleGroupsLink();
                Groups groups=new Groups();
                groups.setGid(gids[i]);
                vo.setRole(role);
                vo.setGroups(groups);
                System.out.println(MyBatisSessionFactory.getSession().insert("ycit.sth.vo.mapping.RoleNS.doCreateRoleGroups",vo));
            }
        }
        MyBatisSessionFactory.getSession().commit();
        MyBatisSessionFactory.getSession().close();
    }
}

②role数据修改的时候,需要先删除role_groups表后对应数据,然后重新添加

public class TestRoleEdit {
    public static void main(String[] args) {
        int gids[]=new int[]{3,4};
        Role role=new Role();
        role.setRid(3);
        role.setTitle("沙天慧");
        if (MyBatisSessionFactory.getSession().update("ycit.sth.vo.mapping.RoleNS.doUpdate",role)>0){
            if (MyBatisSessionFactory.getSession().delete("ycit.sth.vo.mapping.RoleNS.doRemoveRoleGroups",role.getRid())>0){
                for (int i=0;i<gids.length;i++){
                    RoleGroupsLink vo=new RoleGroupsLink();
                    Groups groups=new Groups();
                    groups.setGid(gids[i]);
                    vo.setRole(role);
                    vo.setGroups(groups);
                    System.out.println(MyBatisSessionFactory.getSession().insert("ycit.sth.vo.mapping.RoleNS.doCreateRoleGroups",vo));
                }
            }
        }
        MyBatisSessionFactory.getSession().commit();
        MyBatisSessionFactory.getSession().close();
    }
}

③role数据查询的时候可以查询出所有的权限组数据

public class TestRoleSelect {
    public static void main(String[] args) {
        List<Groups> all= MyBatisSessionFactory.getSession().selectList("ycit.sth.vo.mapping.GroupsNS.findAllByRole",3);
          System.out.println(all);
        MyBatisSessionFactory.getSession().commit();
        MyBatisSessionFactory.getSession().close();
    }
}

SSM基础整合

①创建数据库,创建message表

②创建项目,配置好开发包,配置文件(web.xml,applicationContext.xml,mybatis.cfg.xml,database.properties,日志)

web.xml  添加监听器启动Spring容器,通过contextConfigLocation加载配置文件

③编写vo类,编写映射文件Message.xml

<mapper namespace="ycit.sth.vo.mapping.MessageNS">
    <resultMap id="MessageResultMap" type="Message">
        <id property="mid" column="mid"></id>
        <result property="title" column="title"></result>
        <result property="pubdate" column="pubdate"></result>
        <result property="content" column="content"></result>
    </resultMap>
    <insert id="doCreate" parameterType="Message">
        INSERT INTO message(title,pubdate,content) VALUES (#{title},#{pubdate},#{content})
    </insert>
    <select id="findAllSplit" parameterType="java.util.Map" resultMap="MessageResultMap">
        SELECT mid,title,pubdate,content FROM message
        <where>
            <if test="keyword != null">
                ${column} LIKE #{keyword}
            </if>
        </where>
        ORDER BY pubdate DESC LIMIT #{start},#{lineSize}
    </select>
</mapper>  

④数据层DAO编写及实现子类

public interface IMessageDAO {
    public boolean doCreate(Message vo) throws Exception;
    public List<Message> findAllSplit(String column,String keyword,Integer currentPage,Integer lineSize) throws Exception;
}
@Component
public class MessageDAOImpl implements IMessageDAO {
    @Resource
    private SqlSessionFactory sessionFactory;
    @Override
    public boolean doCreate(Message vo) throws Exception {
        return this.sessionFactory.openSession().insert("ycit.sth.vo.mapping.MessageNS.doCreate",vo)>0;
    }

    @Override
    public List<Message> findAllSplit(String column, String keyword, Integer currentPage, Integer lineSize) throws Exception {
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("column",column);if(keyword!=null){
            map.put("keyword","%"+keyword+"%");
        }
        map.put("start",(currentPage-1)*lineSize);
        map.put("lineSize",lineSize);
        return this.sessionFactory.openSession().selectList("ycit.sth.vo.mapping.MessageNS.findAllSplit",map);
    }
}

【注】由于数据层比较简单,也可以去数据层,直接放在业务层

⑤编写业务层Service及其实现子类

public interface IMessageService {
    public boolean insert(Message vo)  throws Exception;
    public List<Message> list(String column,String keyword,int currentPage,int lineSize) throws Exception;
}
@Service
public class MessageServiceImpl implements IMessageService {
    @Resource
    private IMessageDAO messageDAO;

    @Override
    public boolean insert(Message vo) throws Exception {
        return messageDAO.doCreate(vo);
    }

    @Override
    public List<Message> list(String column, String keyword, int currentPage, int lineSize) throws Exception {
        return messageDAO.findAllSplit(column,keyword,currentPage,lineSize);
    }
}

⑥编写控制层action

@Controller
@RequestMapping("/pages/message/*")
public class MessageAction {
    @Resource
    private IMessageService messageService;
    @RequestMapping("insert")
    public ModelAndView insert(Message vo){
        try {
            System.out.println(this.messageService.insert(vo));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @RequestMapping("list")
    public ModelAndView list(String col,String kw,int cp,int ls){
        try {
            System.out.println(this.messageService.list(col,kw,cp,ls));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    @InitBinder
    public void initBinder(WebDataBinder binder){//进行web数据的转换绑定
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //注册一个专门的日期转换器的操作类,并且允许输入的数据为空
        binder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,true));
    }
}

【注】对于日期必须添加转换器

⑦编写显示层,我们通过地址来进行测试

http://localhost:8080/SSMProject_war_exploded/pages/message/insert.action?title=hello&pubdate=1999-07-21&content=未来可期

http://localhost:8080/SSMProject_war_exploded/pages/message/list.action?col=title&kw=hello&cp=1&ls=5

posted @ 2021-02-05 15:33  我的愿望是如你所愿  阅读(104)  评论(0)    收藏  举报