发表于: 2017-07-31 23:28:07
2 1058
今天做的事:
在师兄的帮助下,解决了一个bug,最后完成了mybatis和Spring的整合
这里学到一个新的概念,动态自动扫描装配,和之前学到的Spring的自动装配不同。
项目结构:
resource里的各种配置文件
测试代码
然后先数据库建表
CREATE TABLE `book` (
`book_id` bigint(
20
) NOT NULL AUTO_INCREMENT COMMENT
'图书ID'
,
`name` varchar(
100
) NOT NULL COMMENT
'图书名称'
,
`number`
int
(
11
) NOT NULL COMMENT
'馆藏数量'
,
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=
1000
DEFAULT CHARSET=utf8 COMMENT=
'图书表'
-- 初始化图书数据
INSERT INTO `book` (`book_id`, `name`, `number`)
VALUES
(
1000
,
'Java程序设计'
,
10
),
(
1001
,
'数据结构'
,
10
),
(
1002
,
'设计模式'
,
10
),
(
1003
,
'编译原理'
,
10
)
-- 创建预约图书表
CREATE TABLE `appointment` (
`book_id` bigint(
20
) NOT NULL COMMENT
'图书ID'
,
`student_id` bigint(
20
) NOT NULL COMMENT
'学号'
,
`appoint_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT
'预约时间'
,
PRIMARY KEY (`book_id`, `student_id`),
INDEX `idx_appoint_time` (`appoint_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=
'预约图书表'
直接贴过来的,根据这个格式,建出相应表格
然后贴一下具体代码
Book.java
package com.ts.entities;
/**
* Created by Administrator on 2017/07/31.
*/
public class Book {
private long bookId;
private String name;
private int number;
public void setBookId(long bookId){
this.bookId = bookId;
}
public long getBookId(){
return bookId;
}
public void setName(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
@Override
public String toString() {
return "Book{" +
"bookId=" + bookId +
", name='" + name + '\'' +
", number=" + number +
'}';
}
}
Appointment.java
package com.ts.entities;
import java.util.Date;
/**
* Created by Administrator on 2017/07/31.
*/
public class Appointment {
private long bookId;
private long studentId;
private Date appoinment;
private Book book;
public long getBookId() {
return bookId;
}
public void setBookId(long bookId) {
this.bookId = bookId;
}
public long getStudentId() {
return studentId;
}
public void setStudentId(long studentId) {
this.studentId = studentId;
}
public Date getAppoinment() {
return appoinment;
}
public void setAppoinment(Date appoinment) {
this.appoinment = appoinment;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
public String toString() {
return "Appointment{" +
"bookId=" + bookId +
", studentId=" + studentId +
", appoinment=" + appoinment +
'}';
}
}
BookDao.java
package com.ts.dao;
import com.ts.entities.Book;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Created by Administrator on 2017/07/31.
*/
public interface BookDao {
// 通过ID查找图书
// @param id
// @return
Book queryById(long id);
// 查询所有图书
// @param offset 查询起始位置
// @param limit 查询条数
// @return
List<Book> queryAll(@Param("offset") int offset,@Param("limit") int limit);
// 减少馆藏数量
// @param bookId
// @return 如果影响行数>=1 ,表示更新记录行数
int reduceNumber(long bookId);
}
对应的mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ts.dao.BookDao">
<select id="queryById" parameterType="long" resultType="Book">
SELECT book_id,name,number FROM book WHERE book_id = #{bookId}
</select>
<select id="queryAll" resultType="Book">
SELECT book_id,name,number FROM book ORDER BY book_id LIMIT #{offset},#{limit}
</select>
<update id="reduceNumber">
UPDATE book SET number = number - 1 WHERE book_id = #{bookId} AND number > 0
</update>
</mapper>
AppointmentDao.java
package com.ts.dao;
import com.ts.entities.Appointment;
import org.apache.ibatis.annotations.Param;
/**
* Created by Administrator on 2017/07/31.
*/
public interface AppointmentDao {
// 插入预约图书记录
// @param bookId
// @param studentId
// @return 插入行数
int insertAppointment(@Param("bookId") long bookId,@Param("studentId") long studentId);
// 通过主键查询预约图书记录,并且携带图书实体
// @param bookId
// @param studentId
// @return
Appointment queryByKeyWithBook(@Param("bookId") long bookId,@Param("studentId") long studentId);
}
相应的mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ts.dao.AppointmentDao">
<insert id="insertAppointment">
<!--主键冲突报错-->
INSERT ignore INTO appointment(book_id,student_id)
VALUE (#{bookId},#{studentId})
</insert>
<select id="queryByKeyWithBook" resultType="Appointment">
SELECT a.book_id,
a.student_id,
a.appoint_time,
b.book_id "book.book_id",
b.name "book.name",
b.number "book.number"
FROM appointment a
INNER JOIN book b ON a.book_id = b.book_id
WHERE a.book_id = #{bookId} AND a.student_id = #{studentId}
</select>
</mapper>
然后是各种配置文件
首先是Spring和mybatis的整合配置文件,我的命名为
spring-dao.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<!--(1)配置数据库-->
<!--加载数据库连接配置-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--c3po最重要的api-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--c3po连接处私有属性-->
<!--最大连接数-->
<property name="maxPoolSize" value="30"/>
<!--最小连接数-->
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动commint-->
<property name="autoCommitOnClose" value="false"/>
<!--表示当连接数到达最大时,超时时间-->
<property name="checkoutTimeout" value="60000"/>
<!--重试次数-->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--(2)配置SqlSessionFactoryBean 来自mybatis-spring-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--数据源-->
<property name="dataSource" ref="dataSource"/>
<!--配置mybatis的全局配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--扫描model包,-->
<property name="typeAliasesPackage" value="com.ts.entities"/>
<!--扫描sql配置文件-->
<property name="mapperLocations" value="classpath:mapping/*.xml"/>
</bean>
<!--扫描dao接口,动态实现接口,并且注入到spring容器中
就是xml配置文件中namespace中的接口
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--给出要扫描的包的地址-->
<property name="basePackage" value="com.ts.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
这里的jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc.username=root
jdbc.password=<mima>
密码处更改为数据库密码
然后是mybatis的配置文件
<?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>
<!-- 配置全局属性 -->
<settings>
<!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 使用列别名替换列名 默认:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
这个配置文件的dtd头不能缺少,之前我写的时候缺了,然后师兄帮忙解决的
缺少报错如下
最后是测试类了
首先我们配置一个公有类,完成重复操作,然后各个测试继承即可
BaseTest.java
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 配置spring和junit整合,junit启动时加载springIOC容器 spring-test,junit
*/
@RunWith(SpringJUnit4ClassRunner.class)
// 告诉junit spring配置文件
@ContextConfiguration({ "classpath:spring/spring-dao.xml"})
public class BaseTest {
}
然后是两个接口的各个测试类
BookDaoTest.java
import com.ts.dao.BookDao;
import com.ts.entities.Book;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* Created by Administrator on 2017/07/31.
*/
public class BookDaoTest extends BaseTest{
@Autowired
private BookDao bookDao;
@Test
public void testQueryById() throws Exception{
long bookId = 1000;
Book book = bookDao.queryById(bookId);
System.out.println(book);
}
@Test
public void testQueryAll() throws Exception{
List<Book> books = bookDao.queryAll(0,4);
for(Book book:books){
System.out.println(book);
}
}
@Test
public void testReduceNumber() throws Exception{
long bookId = 1000;
int update = bookDao.reduceNumber(bookId);
System.out.println("update = "+ update);
}
}
AppointmentDaoTest.java
import com.ts.dao.AppointmentDao;
import com.ts.entities.Appointment;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by Administrator on 2017/07/31.
*/
public class AppointmentDaoTest extends BaseTest{
@Autowired
private AppointmentDao appointmentDao;
@Test
public void testInsertAppointment() throws Exception{
long bookId = 1000;
long studentId = 12345678910L;
int insert = appointmentDao.insertAppointment(bookId,studentId);
System.out.println("insert = "+ insert);
}
@Test
public void testQueryByKeyWithBook() throws Exception{
long bookId = 1000;
long studentId = 12345678910L;
Appointment appointment = appointmentDao.queryByKeyWithBook(bookId,studentId);
System.out.println(appointment);
System.out.println(appointment.getBook());
}
}
测试成功的结果就不放了。
至此,Spring和mybatis的整合已完成。
接下来是整合SpringMVC,不过目前还有bug,正在受阻,正在调试。
目前service层刚刚调试成功
遇到的bug竟然是
配置文件中的一行
之前Location的L是小写l,导致报错如下
将这个更改过来就好了,因为Spring的严格规定。
最后service层已经跑通,但是业务逻辑还没有看懂,用到了枚举以及事务。
所以需要明天继续好好的理解一下。
明天计划:继续学习SSM框架;然后将springMVC的配置文件弄明白。
遇到问题:几个bug;
首先,在测试时要将与测试的模块不相关的部分注释掉,特别是多出来的这块还有错误。
然后有的一些报错要考虑到是否缺少jar包或者各个jar包版本不兼容,今天的spring-test这个jar包就出现兼容性问题,升级版本就好了。
最后就是之前讲的那个配置文件缺少dtd头。
然后之后的springMVC的整合遇到bug,有待解决
收获:和之前的Spring和mybatis的整合不一样,这次的整合使用自动扫描的形式,自动为dao接口进行注入
如下
<!--扫描dao接口,动态实现接口,并且注入到spring容器中
就是xml配置文件中namespace中的接口
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--给出要扫描的包的地址-->
<property name="basePackage" value="com.ts.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
评论