mybatis+struts2

本文介绍了如何使用mybatis3.2.7和struts2.1.8进行小型web项目的开发,通过配置文件、数据库设计、项目结构、引入的jar包以及代码分析,展示了mybatis的多对多查询和分页功能。在struts部分,讨论了Action层与service层的交互,以及struts.xml的配置。整个过程旨在简化开发流程,避免使用SSH框架的复杂性,适用于小型项目。
摘要由CSDN通过智能技术生成

前言:我们都知道Java开发web项目的框架有很多:struts,hibernate,spring,springMVC,mybatis,Ejb 。个人来说,一般的网站都会使用传统的ssh。这几天,准确是4天,要开发一个报名的系统。挺小的一个网站,只有3张表。这个时候总不能用ssh吧,杀鸡焉用宰牛刀,但是有不想使用原始的jdbc,servlet。想来想去,决定用mybatis3.2.7+struts2.1.8+bootstarp开发。


需求:用户报名。完整的界面如下:





mysql数据库:有3张表,如下



项目结构:


src的目录结构如下:



引进的jar包有:


下面具体分析src目录的代码,有mybatis的多对多查询,分页。单元测试

1.先再src目录下建立一个db.properties配置文件,存放链接数据库的参数:

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

2.mybatis的xml配置文件:config.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>  
   <!-- 加载属性文件 -->
   <properties resource="db.properties">
   </properties>
     
   <!-- 类别名定义 -->  
   <typeAliases>  
         <package name="com.yctime.pojo"/>
    </typeAliases>  
    <!-- 配置Mybatis的环境,事务及数据源等等 -->  
    <environments default="development">  
        <environment id="development">  
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
                <property name="driver" value="${jdbc.driver}" />  
                <property name="url" value="${jdbc.url}" />  
                <property name="username" value="${jdbc.username}" />  
                <property name="password" value="${jdbc.password}" />  
            </dataSource>  
        </environment>  
    </environments>  
      
    <!-- 指定映射文件或者映射类 -->  
    <mappers>
        <package name="com.yctime.persistence"/>
    </mappers>  
</configuration>  

3.写pojo类

Student.java:

package com.yctime.pojo;

import java.io.Serializable;
import java.util.List;

public class Student implements Serializable {
	
	private static final long serialVersionUID=1L;
	private int id;
	private String username;
	private String sex;
	private String classname;
	private String tel;
	private String power;
	private String myflags;
	private String introduce;
	private String isfile;
	private String filename;
        setter getter...

Flag.java:

package com.yctime.pojo;

import java.io.Serializable;

public class Flag implements Serializable {
	
	private static final long serialVersionUID=1L;
	private int id;
	private String name;
        setter getter...

Selection.java:

package com.yctime.pojo;

public class Selection {
	private static final long serialVersionUID=1L;
	private int id;
	private int studentid;
	private int flagid;
        setter getter...

Page.java(分页专用)

package com.yctime.pojo;

public class Page {
	
	private int pageBegin;
	private int pageGet;
	setter getter...

FlagCustom.java(Flag 的拓展类,处理多对多):

package com.yctime.pojo;

import java.util.List;

public class FlagCustom extends Flag{
	
	private List<Student> students;
        setter getter...

4.写persistence层:

StudentMapper.java:(这里的接口只需声明,不需要实现,方法名看不懂没关系,呆会就明白了)

package com.yctime.persistence;

import java.util.List;

import com.yctime.pojo.Flag;
import com.yctime.pojo.FlagCustom;
import com.yctime.pojo.Page;
import com.yctime.pojo.Selection;
import com.yctime.pojo.Student;

public interface StudentMapper {
	
	public void insertStudent(Student student);
    
	public int getstupageCount();
	
	public List<Student> getstudentBypage(Page page);
	
	public Student getstudentById(int id);
	
	public void insertSelection(Selection selection);
	
	public void updateStudent(Student student);
	
	public FlagCustom selectFlagStudent(int id);
	
	public Flag getflagById(int id);
	
	public void insertflag(Flag flag);
}

StudentMapper.xml:(id是跟上面的接口的的方法名一致,resultMap是针对多对多构建的,如果看不明白,复制里面的sql语句,放在mysql中去测试)

<?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.yctime.persistence.StudentMapper">
 <resultMap type="FlagCustom" id="flagCustomMap">  
        <id property="id" column="id" />  
        <result property="name" column="name" />  
    </resultMap>  
  
    <resultMap type="FlagCustom" id="flagCustomStudentMap" extends="flagCustomMap">  
        <collection property="students" ofType="Student">  
            <id property="id" column="studentid" />  
            <result property="username" column="username" />  
            <result property="sex" column="sex"/> 
            <result property="classname" column="classname"/>
            <result property="tel" column="tel"/>
            <result property="power" column="power"/>
            <result property="introduce" column="introduce"/>
            <result property="myflags" column="myflags"/>
            <result property="isfile" column="isfile"/>
            <result property="filename" column="filename"/>
        </collection>  
    </resultMap>  
<insert id="insertStudent" useGeneratedKeys="true" keyProperty="id" parameterType="Student">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
insert into student(username,sex,classname,tel,power,introduce,myflags,isfile,filename) 
values(#{username},#{sex},#{classname},#{tel},#{power},#{introduce},#{myflags},#{isfile},#{filename})
</insert>
<select id="getstupageCount" resultType="java.lang.Integer">
select count(*) from student
</select> 
<select id="getstudentBypage" parameterType="Page" resultType="Student">
select * from student where id limit #{pageBegin},#{pageGet}
</select>
<select id="getstudentById" parameterType="int" resultType="Student">
select * from student where id=#{id}
</select>
<insert id="insertSelection" parameterType="Selection">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
insert into selection(studentid,flagid) values(#{studentid},#{flagid})
</insert>
<update id="updateStudent" parameterType="Student">
update student set myflags=#{myflags},isfile=#{isfile},filename=#{filename} where id=#{id}
</update>
<select id="selectFlagStudent" parameterType="int"  
        resultMap="flagCustomStudentMap">  
        select s.id as studentid,s.username as username,s.sex as sex,
        s.classname as classname,s.tel as tel,s.power as power,s.introduce as introduce,
        s.myflags as myflags, s.isfile as isfile,s.filename as filename,
        f.id,f.name from flag f left join selection on f.id=selection.flagid left join student
        s on selection.studentid=s.id where f.id=#{id}
</select>
<select id="getflagById" parameterType="int" resultType="Flag">
select * from flag where id=#{id}
</select>
<insert id="insertflag" parameterType="Flag">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
insert into flag(name) values(#{name})
</insert>
</mapper>

5.写service层,其实service有没有都可以,看个人:

MybatisUtil.java是一些重量级的配置,studentService.java是针对具体的业务需求写的,主要是对persistence层的接口再次封装

MybatisUtil.java:定义一些共用的方法

package com.yctime.service;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtil {

     private static final String resource = "config.xml";
     private static Reader reader;
     private static SqlSessionFactory sqlSessionFactory;

     static{
         try {
                   reader = Resources.getResourceAsReader(resource);
                   sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                   } catch (IOException e) {
                         e.printStackTrace();
                   }
     }
 
     private static final ThreadLocal<SqlSession> THREAD_LOCAL = new ThreadLocal<SqlSession>();

     public static SqlSession getcurrentSession(){
          SqlSession session = THREAD_LOCAL.get();
          if(session==null){
            session = sqlSessionFactory.openSession();
            THREAD_LOCAL.set(session);
           }
         return session;
     }

     public static void closeSession(){
          SqlSession session = THREAD_LOCAL.get();
          THREAD_LOCAL.set(null);
          if(session!=null){
                session.close();
          }
     }
}


studentService.java:方法是上面的persistence层的StudentMapper.java的方法的封装,方法名也很像,每个方法名多个S

package com.yctime.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.yctime.persistence.StudentMapper;
import com.yctime.pojo.Flag;
import com.yctime.pojo.FlagCustom;
import com.yctime.pojo.Page;
import com.yctime.pojo.Selection;
import com.yctime.pojo.Student;

public class studentService {
	
	//存储student
	public void insertSStudent(Student student){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		mapper.insertStudent(student);
		session.commit();
		MybatisUtil.closeSession();
	}

	//获取student的页数
	public int getSstupageCount(int pageSize){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		int pageCount=mapper.getstupageCount();
		MybatisUtil.closeSession();
		return ((pageCount-1)/pageSize)+1;
	}
	
	//对student分页获取数据
	public List<Student> getSstudentByPage(int pageSize,int pageNow){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		Page page=new Page();
		page.setPageBegin((pageNow-1)*pageSize);
		page.setPageGet(pageSize);
		List<Student> studentlist=mapper.getstudentBypage(page);
		MybatisUtil.closeSession();
		return studentlist;
	}
	
	//通过id获取student
	public Student getSstudentById(int id){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		Student student=mapper.getstudentById(id);
		MybatisUtil.closeSession();
		return student;
	}
	
	//插入selection记录
	public void insertSSelection(Selection selection){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		mapper.insertSelection(selection);
		session.commit();
		MybatisUtil.closeSession();
	}
	
	//更新student
	public void updateSStudent(Student student){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		mapper.updateStudent(student);
		session.commit();
		MybatisUtil.closeSession();
	}
	
	//根据方向查找到所有选择的学生
	public FlagCustom selectSFlagStudent(int id){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		FlagCustom falgcustom=mapper.selectFlagStudent(id);
		MybatisUtil.closeSession();
		return falgcustom;
	}
	
	//通过id获取flag
	public Flag getSflagById(int id){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		Flag flag=mapper.getflagById(id);
		MybatisUtil.closeSession();
		return flag;
	}
	
	//存储flag
	public void insertSflag(Flag flag){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		mapper.insertflag(flag);
		session.commit();
		MybatisUtil.closeSession();
	}

}

6.写测试类

再测试的方法上加个@Test即可

package com.yctime.test;

import java.util.List;

import org.junit.Test;

import com.yctime.pojo.Flag;
import com.yctime.pojo.FlagCustom;
import com.yctime.pojo.Selection;
import com.yctime.pojo.Student;
import com.yctime.service.MybatisUtil;
import com.yctime.service.studentService;

public class textMapper {
	
	public void teststudentMapper(){
		Student student=new Student();
		student.setClassname("XXXX");
		student.setIntroduce("XXXX");
		student.setPower("Hello world.");
		student.setSex("XXXX");
		student.setTel("XXXX");
		student.setUsername("XXXX");
		student.setMyflags("XX");
		student.setIsfile("XX");
		student.setFilename("XX");
		studentService studentser=new studentService();
		studentser.insertSStudent(student);
	}

	
	public void testgetpagecount(){
		studentService studentser=new studentService();
		int pagecount=studentser.getSstupageCount(2);
		System.out.println("pagecount-->"+pagecount);
	}
	
	
	public void teststudentByPage(){
		studentService studentser=new studentService();
		List<Student> studentlist=studentser.getSstudentByPage(3, 2);
		System.out.println("studentlist.size()-->"+studentlist.size());
		for(int i=0;i<studentlist.size();i++)
		{
			System.out.println(studentlist.get(i).getId()+"-->"+studentlist.get(i).getMyflags());
		}
	}
	

	public void testgetstuById(){
		studentService studentser=new studentService();
		Student student=new Student();
		student=studentser.getSstudentById(13);
		System.out.println(student.getId()+"-->"+student.getMyflags());
	}
	
	public void testinsertSSelection(){
		studentService studentser=new studentService();
		Selection selection=new Selection();
		selection.setFlagid(1);
		selection.setStudentid(23);
		studentser.insertSSelection(selection);
	}
	
	public void testselectSFlagStudent(){
		studentService studentser=new studentService();
		FlagCustom flagcustom=studentser.selectSFlagStudent(8);
		System.out.println(flagcustom.getName());
		System.out.println("*******************");
		for(Student student:flagcustom.getStudents())
		{
			System.out.println(student.getUsername());
		}
	}
	@Test
	public void testgetSflagById(){
		studentService studentser=new studentService();
		Flag flag=studentser.getSflagById(6);
		System.out.println(flag.getName());
	}

}

至此,mybatis的工作完成了

下面看看struts的

7.web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

8.在src目录下建一个struts.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
      <constant name="struts.action.extension" value="do,action"/>
      <constant name="struts.multipart.maxSize" value="104857600"/>
      <package name="register" namespace="/" extends="json-default">
           <action name="student_*" class="com.yctime.web.Action.registerAction" method="{1}">
                <result name="registered">/WEB-INF/signup.jsp</result>
                <result name="addedflag">/addflag.jsp</result>
           </action>
           <action name="admin_*" class="com.yctime.web.Action.adminAction" method="{1}">
                <result name="loginsuccess">/WEB-INF/adminmanager.jsp</result>
                <result name="loginfail">adminlogin.jsp</result>
                <result name="gostudent">/WEB-INF/student.jsp</result>
                <result name="otherStudent">/WEB-INF/adminmanager.jsp</result>
                <result name="flagFilter">/WEB-INF/filter.jsp</result>
                <result name="studentFlagfilter">/WEB-INF/student_flagfilter.jsp</result>
           </action>
      </package>
</struts>

至此,struts也好了,具体的使用看具体需求了,mybatis和struts的交叉就是Action层,需要什么数据就在service中调,需要带数据跳到哪个界面就根据struts.xml去跳转

下面具体分析多对多和分页:

分页先来:

在StudentMapper.xml有一分页:

<select id="getstudentBypage" parameterType="Page" resultType="Student">
select * from student where id limit #{pageBegin},#{pageGet}
</select>

它对应的方法是StudentMapper.java的public List<Student> getstudentBypage(Page page);这里传入的参数是一个Page对象,看看Page对象先,他有两个成员变量:pageBegin 和 pageGet,分别代表从第几行记录和要取多少记录。再看看public int getstupageCount();,看看它对用应的sql语句:

<select id="getstupageCount" resultType="java.lang.Integer">
select count(*) from student
</select>
很明显,他是取得该分页表的记录行,public int getstupageCount();在service层中被下面的方法调用:

//获取student的页数
	public int getSstupageCount(int pageSize){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		int pageCount=mapper.getstupageCount();
		MybatisUtil.closeSession();
		return ((pageCount-1)/pageSize)+1;
	}
传入的参数代表一页要显示几条数据,根据得到记录的总数,用
((pageCount-1)/pageSize)+1
计算出页数。
再看看service层的另一个方法:

//对student分页获取数据
	public List<Student> getSstudentByPage(int pageSize,int pageNow){
		SqlSession session=MybatisUtil.getcurrentSession();
		StudentMapper mapper=session.getMapper(StudentMapper.class);
		Page page=new Page();
		page.setPageBegin((pageNow-1)*pageSize);
		page.setPageGet(pageSize);
		List<Student> studentlist=mapper.getstudentBypage(page);
		MybatisUtil.closeSession();
		return studentlist;
	}

传入的参数代表一页显示的页数和当前页是第几页,根据mysql limit分页的要求,构建Page对象,于是取得想要的当前页的一页的数据,那么service层中得到的页数和取得的当前页数据有什么用呢?具体怎么用

我们看看Action层的一个方法:

	String pageNow=request.getParameter("pageNow");
			int s_pageNow=1;
			if(pageNow!=null)
			{
				s_pageNow=Integer.parseInt(pageNow);
			}
			studentService stuService=new studentService();
			int pageCount=stuService.getSstupageCount(20);
			List<Student> studentlist=stuService.getSstudentByPage(20,s_pageNow);
			request.setAttribute("pageCount", pageCount);
			request.setAttribute("studentlist", studentlist);
			return "otherStudent";

这个方法中,getSstupageCount(20);代表传入每页20条数据,返回有几页,好把页数传给前端界面显示,.getSstudentByPage(20,s_pageNow);传入20,当前页数,当前页数是变量。可以根据前端界面返回的数值切换,20告诉service层要20条数据:看看具体在jsp页面的用法:

<ul class="pagination">
  <li><a href="${pageContext.request.contextPath }/admin_otherStudent.action?pageNow=1">首页</a></li>
  <c:forEach begin="1" end="${pageCount}" var="i">
  <li><a href="${pageContext.request.contextPath }/admin_otherStudent.action?pageNow=${i}">${i}</a></li>
  </c:forEach>
  <li><a href="${pageContext.request.contextPath }/admin_otherStudent.action?pageNow=${pageCount}">尾页</a></li>
</ul>
当前页数是可以返回给后台切换的。


先面说说多对多,这个比较简单,从hiberbate的角度分析:

student可以选多个flag,flag可以有多个student,selection只是用来记录两个表之间的每一个联系,回想一下hibernate的对应关系,记不记得Set,如果是hibernate,那么student中一定有Set<Selection>,flag也有。

现在一取出某个flag对应的所有学生:只需在falg的基础上加一个List<Student>,于是,flagCustom应运而生,根据mybatis3.0以后出的collection,再使用resultMap构建即可。





  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值