Mybatis
1. No constructor found in com.model.User matching[java.lang.Integer, ...]
原因
因为在User类中没有构造方法,mybatis希望实体类中有一个默认的无参构造方法【必须要】。
参考
措施
User.class
public User() {}
2. Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource xxx
原因
- idea不会编译src的java目录的xml文件,放置在java.com文件夹下的xml文件无法找到
- 匹配混乱,实体类User.class对应的应该是User.xml,但是又写了一个接口Userim.class和Userim.xml,使用User.xml来查找Userim
参考
措施
原因1
在pom.xml中添加如下
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
原因2
搞清各个xml的应用范围和路径匹配
User.xml中需注意的点有
- 命名空间namespace
- resultType为对应的实体类
<mapper namespace="test">
<!-- 通过Id查询一个用户 -->
<select id="findUserById" parameterType="Integer" resultType="com.User">
select * from user where id = #{id};
</select>
</mapper>
SqlMapConfig.xml需注意的点有
- 符合dtd规范,!DOCTYPE等必须有
- mybatis和mysql的环境必须配置正确
- 映射配置文件的位置指定的是实体类对应的mapper文件即User类所对应的User.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="mysql">
<!--配置mysql的环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置连接池-->
<dataSource type="POOLED">
<!--配置连接数据库的4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<mapper resource="sqlMap/User.xml"/>
</mappers>
</configuration>
3. 非法反射 An illegal reflective access operation has occurred
原因
jdk版本设置为了jdk14,因为jdk9之前都不会有这个问题
参考
An illegal reflective access operation has occurred
措施
换成jdk1.8即可
sqlSessionFactory的NullPointerException
bug
java.lang.NullPointerException
at test2.dao.UserDaoImpl.findUserById(UserDaoImpl.java:32)
at test2.test.UserDaoTest.findbyID(UserDaoTest.java:57)
原因
@Before此注解用于在测试方法前使用,但是经测试语句System.out.println(33333);发现setUp没有启动,因此factory没有创建。
NullPointerException说明对象没有创建,用于此处即SqlSessionFactory未创建。
总结:@Before、@After注解失效,无法创建SqlSessionFactory对象
@Before
public void setUp() throws Exception{
//1.读取配置文件
in = Resources.getResourceAsStream("UTestConfig.xml");
//2.创建SqlSessionFactory工厂
factory = new SqlSessionFactoryBuilder().build(in);
System.out.println(factory);
System.out.println(33333);
}
@After//在测试方法执行完成之后执行
public void destroy() throws IOException {
System.out.println(11111);
}
措施
法1:将下列语句放置测试方法体内
可用test0.java测试
in = Resources.getResourceAsStream("UTestConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
UserDaoTest.java
private SqlSessionFactory factory;
private UserDao userdao;
private InputStream in;
@Test
public void findbyID() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("UTestConfig.xml");
//2.创建SqlSessionFactory工厂
factory = new SqlSessionFactoryBuilder().build(in);
// 将初始化好的工厂注入到实现类中
userdao = new UserDaoImpl(factory);
User user1 = userdao.findUserById(2);
System.out.println(user1);
in.close();
}
法2:使用testng.annotations中的注解而不是org.junit中的注解【推荐使用】
可用test1.java测试
原因:
- 经查证发现junit中的@Before等注解已经失效,逐渐替换成junit5中的@BeforeEach等注解
- 本机的快捷键shift+G 【Generate】可直接生成Test、BeforeMethod等
package test2.test;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import test2.dao.UserDao;
import test2.dao.UserDaoImpl;
import test2.entiy.User;
import java.io.IOException;
import java.io.InputStream;
public class test1 {
private SqlSessionFactory factory;
private UserDao userdao;
private InputStream in;
@BeforeMethod
public void setUp() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("UTestConfig.xml");
//2.创建SqlSessionFactory工厂
factory = new SqlSessionFactoryBuilder().build(in);
}
@Test
public void testName() {
userdao = new UserDaoImpl(factory);
User user1 = userdao.findUserById(2);
System.out.println(user1);
}
@AfterMethod
public void tearDown() throws IOException {
in.close();
}
}
更新
经前面的曲折的过程,发现注解失效,但是那是因为@Test和@Before、@After所引导的包是不同的,@Before和@After所在的包是org.junit,而
@Test所在的包却是org.testng.annotations,因此注解失效,导致了SqlSessionFactory对象无法创建。
如下代码所示。
import org.junit.After;
import org.junit.Before;
//import org.junit.Test;
import org.testng.annotations.Test;
总结
# org.junit包下的注解
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@Before
public void setUp() throws Exception {
}
@Test
public void say(){
}
@After
public void tearDown() throws Exception {
}
# org.testng.annotations包下的注解
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@BeforeMethod
public void setUp() throws IOException {
}
@Test
public void testName() {
}
@AfterMethod
public void tearDown() throws IOException {
}
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'
原因
主键字段id,没有添加自增关键字 AUTO_INCREMENT
参考
Duplicate entry ‘0’ for key ‘PRIMARY’
措施
console[@localhost]
drop table user;
create table user
(
id INTEGER null AUTO_INCREMENT,
username VARCHAR(50) null,
sex VARCHAR(50) null,
birthday DATE null,
address VARCHAR(50) null,
constraint user_pk
primary key (id)
);