发表于: 2016-09-20 02:58:30
2 2142
任务
1. 回顾
Task02的applicationContext.xml中除了:
连接数据库
配置SqlSession(加载SqlMapConfig.xml)
为需要代理的对象配置<bean>
以外,还对MVC框架配置了以下:
Controller(如果有必要)
处理器映射器和处理器适配器
视图解析器
注意区分以下二者的区别,前者是扫描生成代理过程(执行sql语句时)对应的映射,后者是扫描url请求对应的映射,因此前者的base-package路径是dao,后者是controller:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jnshu.Task02.DAO" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 注解开发所用控制器Controller 扫描器可以扫描指定包下所有有注解的Controller -->
<context:component-scan base-package="com.jnshu.Task02.Controller" />
关于<context:component-scan>标签
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean。
如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用在xml中配置了,因为前者包含了后者。另外<context:annotation-config/>还提供了两个子标签:
1. <context:include-filter>
2. <context:exclude-filter>
<context:component-scan>有一个use-default-filters属性,改属性默认为true。
Use-dafault-filters="false"的情况下:<context:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描。
之前的配置结构如下:
web.xml
(上下文初始化参数和springmvc配置都指向applicationContext.xml)
↓
applicationContext.xml
↓
SqlMapConfig.xml
↓
mapper.xml
2. 流程
本任务配置结构如下:
web.xml
(上下文初始化参数指向applicationContext.xml
springmvc配置都默认指向springmvc-servlet.xml)
↙ ↘
springmvc-servlet.xml applicationContext.xml
(配置tiles视图解析器和tiles.xml) (上下文初始化参数)
↓
tiles.xml
3. 具体实现
web.xml:
<!-- spring容器加载文件路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc/applicationContext.xml</param-value>
</context-param>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 前端控制器 dispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
(springmvc如果不配置contextConfigLocation,默认查找的配置文件名称classpath下的:servlet名称+"-serlvet.xml"即:springmvc-serlvet.xml)
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
applicationContext.xml主要初始化:
<!-- 配置数据库连接池 -->
<!-- 配置sqlSessionFactory -->
<!-- 自动扫描带注解的DAO,生成代理注入到Spring,bean的id就是接口的类名(首字母小写) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jnshu.Task04.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 必要的代理bean -->
<bean id="studentService" class="com.jnshu.Task04.dao.StudentServiceImpl" />
<!-- 配置必要处理器映射器和处理器适配器以及视图解析器 -->
springmvc-servlet.xml主要配置:
<!-- 注解开发所用控制器Controller的扫描器,可以扫描指定包下所有有注解的Controller -->
<context:component-scan base-package="com.jnshu.Task04.controller" />
<!-- tiles视图解析器 -->
<bean id="tilesViewResolver" class=
"org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.tiles2.TilesView</value>
</property>
</bean>
<!-- 配置TilesConfigurer所用tiles.xml -->
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
tiles.xml(节选)
/dao/ StudentDao_Annotation.java
public interface StudentDao_Annotation {
@Select("select * from Students_YQ")
public List<Student> queryStudents();
@Select("select * from Students_YQ where id = #{id}")
public Student getStudentById(Long id);
@Insert("insert into Students_YQ (name,profession,age,sex,create_at) values
(#{name},#{profession},#{age},#{sex},#{create_at})")
public void addStudent(Student student);
@Update("update Students_YQ set name=#{name},profession=#{profession},
age=#{age},sex=#{sex},update_at=#{update_at} where id=#{id}")
public void updateStudent(Student student);
@Delete("delete from Students_YQ where id=#{id}")
public void deleteStudentById(Long id);
@Select("select count(${column}) from ${table}")
public int getCount(TableAndColumn tableAndColumn);
@Select("select count(id) from Students_YQ where profession = #{profession}")
public int getCountByTag(String profession);
}
/dao/ StudentServiceImpl.java
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
StudentDao_Annotation studentDao_Annotation;
public List<Student> queryStudents() {
return studentDao_Annotation.queryStudents();
}
public Student getStudentById(Long id) {
return studentDao_Annotation.getStudentById(id);
}
public void addStudent(Student student) {
studentDao_Annotation.addStudent(student);
}
public void updateStudent(Student student) {
studentDao_Annotation.updateStudent(student);
}
public void deleteStudentById(Long id) {
studentDao_Annotation.deleteStudentById(id);
}
public int getCount(TableAndColumn tableAndColumn) {
return studentDao_Annotation.getCount(tableAndColumn);
}
public String getTime(Date date) {
DateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String time = (String)dateFormat.format(date);
return time;
}
}
/controller/ HomeController.java
@Controller
public class HomeController {
@Autowired
StudentService studentService;
@RequestMapping("/home")
public ModelAndView home(HttpServletRequest request, HttpServletResponse response){
ModelAndView modelAndView=new ModelAndView();
TableAndColumn tableOfStudents = new TableAndColumn("id","Students_YQ");
TableAndColumn tableOfClasses = new TableAndColumn("id","ITClasses_YQ");
int count_stu = studentService.getCount(tableOfStudents);
int count_cla = studentService.getCount(tableOfClasses);
String time = studentService.getTime(new Date());
//ModelAndview
modelAndView.addObject("classCount", count_cla);
modelAndView.addObject("studentCount", count_stu);
modelAndView.addObject("time", time);
//definitation name
modelAndView.setViewName("home");
return modelAndView;
}
}
/WEB-INF/views/contents/ home.jsp(节选)
4. 效果
(localhost:8080/home)
将项目部署服务器进行访问效果相同。
引申——更新数据库
1. 已建学生数据表 Students_YQ 包含以下字段:
id
name
profession
age
sex
create_at
update_at
并以插入数条数据记录。
2. 如何根据学生表自动更新班级数据表
(抽取学生profession作为班级profession,统计人数count_students,根据最近添加的学生及时更新相应的班级数据)
建好班级表 ITClasses_YQ 包含以下字段:
id
name
profession
count_students
create_at
update_at
其中profession为学生表中所包含的profession值,count_students默认为0,如何根据学生表自动更新班级表?
这个问题逻辑上很简单,无非就是应用一步COUNT函数,看起来一步就解决。用INSERT语句插入COUNT函数的值完全没问题,但是在实际中,班级表已存在,每次更新时都要插入全部的重复数据再手动删除,或是先全部删除再插入?要更新数据你用INSERT语句不是找麻烦吗。要更新数据当然用UPDATE语句,但问题就出在UPDATE语句无法将字段SET为COUNT函数的值(空口无凭,可以自行试一下,即使用上很复杂繁琐的多表连接也不行)。
我只能借助JAVA解决,代码不贴了,思路简单说就是:获取班级数据表中所有profession字段的值,通过学生数据表取得每一个profession对应的学生人数count_students,再利用这些count_students更新班级数据表。需注意耐心实现接口,并灵活调用方法即可。
访问学生数据表中所有记录(url=localhost:8080/queryStudents/All)
通过id访问学生数据表中记录(url=localhost:8080/queryStudents/id)
访问班级数据表中所有记录(url=localhost:8080/queryClasses/All)
通过id访问班级数据表中记录(url=localhost:8080/queryClasses/id)
而原来基本为空的班级数据表也得到自动更新(Java中实现,在访问请求的过程中自动更新数据表,当然实际中不可能这样来做,这里做了简化):
实现数据表及时更新。
评论