踩坑记录
MySQL踩坑记录
1,插入数据时 报Unknown column '张三' in 'field list'
-- 错误方式
insert into `user`(`user_id`,`user_name`,`user_pwd`) values(3,`王五`,`wangwu`);
-- 正确方式
insert into `user`(`user_id`,`user_name`,`user_pwd`) values(3,'王五','wangwu');
复制代码
原因 : 对于数据库名,表名,字段名使用user
(反双撇号引用-table键上面那个)而对于字符串则使用' 张三'引用(enter键旁边)。
MyBatis踩坑记录
1.,在.java文件中和在.xml文件中配置mysql的url的区别
-
在.java文件中配置
jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8 复制代码
-
在.xml文件中配置
jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
复制代码
原因: 在.xml文件中&不能直接解析,需要使用转义字符转义,&对应的转义字符为&
2,报not known to the MapperRegistry. 异常
当在.xml文件中写sql语句时,该.xml文件要在mybatis-config.xml文件中进行注册(即加入以下内容)否则会报Type interface com.jgsu.dao.UserMapper is not known to the MapperRegistry. 异常
<mappers>
<mapper resource="com/jgsu/dao/UserMapper.xml"/>
</mappers>
复制代码
3,报 Could not find resource com/jgsu/dao/UserMapper.xml异常
org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/jgsu/dao/UserMapper.xml
原因:I DEA是不会编译src的java目录的xml文件,所以在Mybatis的配置文件中找不到xml文件!(也有可能是Maven构建项目的问题,网上教程很多项目是普通的Java web项目,所以可以放到src下面也能读取到)
解决方法: 在当前pom.xml中添加节点(可以放在父级)
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
复制代码
4,Parsing error was found in mapping #{}异常
org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in com/zuoyueer/dao/UserMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Parsing error was found in mapping #{}. Check syntax #{property|(expression), var1=value1, var2=value2, ...}
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80)
....
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Parsing error was found in mapping #{}. Check syntax #{property|(expression), var1=value1, var2=value2, ...}
复制代码
意思就是说,我的映射文件中#{}
里没有写值, 于是我找啊找,我的全部配置都加了值啊,最后我一个一个删除,终于定位到了异常,居然是注释的锅!!!
异常代码如下:
<select id="getUserById" resultType="com.jgsu.pojo.User" parameterType="int">
/*user_id`:数据库中表名,#{}中填该方法对应的参数名*/
select `user_id`,`user_name`,`user_pwd` from `user` where `user_id`=#{user_id};
</select>
复制代码
原因: 注释中含有#{},这里使用的注释是/**/,会导致xmll文件解析异常,将注释中的#{}也解析了。
解决办法: 删除该注释或采用进行注释,这样注释内容就不会被解析。
参考:mybatis异常Parsing error was found in mapping #{}. mybatis映射文件中使用注释的坑
5,使用mybatis进行insert/delete/update操作时,明明执行成功了,但是数据库中的数据没有更新
原因: mybatis中使用sqlSession对数据进行更新操作后要进行事务的提交即sqlSession.commit();数据才能在数据库中进行更新。
6,万能map
当实体类中或者数据库表中的字段或参数过多时,而我们只需要对部分值在SQL中进行传参时可以考虑使用map。
参考: mybatis中传入多个参数的解决方法
7,模糊查询Like
不建议直接在SQL语句中进行模糊查询,而是将%%放在Java中进行,如下
<!--方法一:根据name中某个字符查-->
<select id="getUserListByLike" resultType="com.jgsu.pojo.User" parameterType="string">
select `user_id`,`user_name`,`user_pwd` from user where `user_name` like #{value};
</select>
<!--方法二:在sql中拼接%-->
<select id="getUserListByLike" resultType="com.jgsu.pojo.User" parameterType="string">
select `user_id`,`user_name`,`user_pwd` from user where `user_name` like "%"#{value}"%";
</select>
复制代码
在java中
// 接口UserMapper中如下定义
/**
* 模糊查询
* */
List<User> getUserListByLike(String value);
@Test
public void getUserListByLike(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// %表示任意个或多个字符。可匹配任意类型和长度的字符 -- 在代码中拼接
String temp = "%";
List<User> userList = userMapper.getUserListByLike(temp+"张"+temp);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
复制代码
8,在xxx.xml文件中的某条sql语句中引入另一个xxx2.xml文件中的某条sql。
目的: 实现多个学生关联一个老师实现多对一查询。
思路:
1.在TeacherMapper.xml文件中编写sql实现根据teacher_id查询对应的teacher。对应的select标签中的id为getTeacherById
2.在StudentMapper.xml文件中编写sql实现全表查询,但是因为student类中存放的是teacher类而不是teacherId,所以要用到resultMap实现数据库中的列于对应的类中的属性一一对应,而对于复杂的属性比如对象teacher则需要用association进行处理,将student类中的teacher属性跟数据库中的t_id进行绑定,获取t_id的值则通过select标签对TeacherMapper.xml中的getTeacherById方法进行绑定。(意思就是从TeacherMapper.xml中的getTeacherById获取到teacher对象然后再将这个对象传给StudentMapper.xml中属性为teacher实现绑定从而实现一对多查询)
复制代码
**1)**其对应的pojo包中的teacher类和student类分别为:
// ----------------------pojo包中的student类
@AllArgsConstructor // lombok插件简化生成set,get,Constructor等方法
@NoArgsConstructor
@Data
public class Student {
// id
private int studentId;
// name
private String studentName;
// 对应的teacher
private Teacher teacher;
}
// ----------------------pojo包中的teacher类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
// id
private int teacherId;
// name
private String teacherName;
}
复制代码
**2)**创建的student表和teacher表如下:
# 创建student表其中t_id对应的是teacher中的teacher_id
create table if not exists `student`(
`student_id` int not null primary key ,
`student_name` varchar(30) not null,
`t_id` int not null
)engine =innodb default charset =utf8;
use mybatis;
# student表中插入数据
insert into `student`(`student_id`,`student_name`,`t_id`) values (1,'小明',1),(2,'小红',1),(3,'小绿',1);
# 创建teacher表
create table if not exists `teacher`(
`teacher_id` int not null primary key ,
`teacher_name` varchar(30) not null
)engine =innodb default charset =utf8;
# teacher表中插入数据
insert into `teacher`(`teacher_id`,`teacher_name`)values (1,'张老师');
# sql语句实现两张表关联查询
select `student_id`,`student_name`,`teacher_name` from `student`,`teacher` where `t_id` = `teacher_id`;
复制代码
**3) **创建的TeacherMapper接口,TeacherMapper.xml,StudentMapper接口,StudentMapper.xml如下:
-
TeacherMapper接口和StudentMapper接口
public interface StudentMapper {
/**
* 多对一连表查询
* */
List<Student> getStudentList();
}
public interface TeacherMapper {
/**
* 根据Id获取老师信息
* */
Teacher getTeacherById(@Param("t_id") int id);
}
复制代码
-
TeacherMapper.xml,StudentMapper.xml
<!--StudentMapper对应的StudentMapper.xml文件------------------------------------>
<?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">
<!--namespace=绑定一个对应的dao/mapper接口的路径-->
<mapper namespace="com.jgsu.dao.StudentMapper">
<!--多对一查询:查询多个学生对应同样一个老师的所有学生-->
<select id="getStudentList" resultMap="StudentTeacher">
select `student_id`,`student_name`,`t_id` from `student`;
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="studentId" column="student_id"/>
<result property="studentName" column="student_name"/>
<!--对于复杂的属性需要单独处理: association处理对象,collection:处理集合-->
<association property="teacher" column="t_id" javaType="com.jgsu.pojo.Teacher" select="getTeacherById"/><!---注意:这里应该写:com.jgsu.dao.TeacherMapper.getTeacherById-->
</resultMap>
</mapper>
<!--TeacherMapper对应的TeacherMapper.xml文件----------------------------------->
<?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">
<!--namespace=绑定一个对应的dao/mapper接口的路径-->
<mapper namespace="com.jgsu.dao.TeacherMapper">
<!--多对一查询:查询多个学生对应同样一个老师的所有学生-->
<select id="getTeacherById" resultType="Teacher">
select `teacher_id`,`teacher_name` from `teacher` where `teacher_id` = #{t_id};
</select>
</mapper>
复制代码
**4)**测试用例如下:
public class StudentMapperTest {
@Test
public void getStudentList(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudentList();
for (Student student : studentList) {
System.out.println(student);
}
sqlSession.close();
}
}
复制代码
问题: 系统会默认去找StudentMapper下的方法,但是问题是我们引入的方法在Teacher类中,写的sql语句也是在TeacherMapper.xml文件中。
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.jgsu.dao.StudentMapper.getTeacherById
### The error may exist in com/jgsu/dao/StudentMapper.xml
### The error may involve com.jgsu.dao.StudentMapper.getStudentList
### The error occurred while handling results
### SQL: select `student_id`,`student_name`,`t_id` from `student`;
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.jgsu.dao.StudentMapper.getTeacherById
复制代码
解决方法: 在StudentMapper.xml文件引入另有一个文件的引用出应该写该方法的完全限定名,而不是该方法的方法名,否则会识别不出。
<!--对于复杂的属性需要单独处理: association处理对象,collection:处理集合-->
<association property="teacher" column="t_id" javaType="com.jgsu.pojo.Teacher" select="com.jgsu.dao.TeacherMapper.getTeacherById"/>
<!--错误用例-->
<association property="teacher" column="t_id" javaType="com.jgsu.pojo.Teacher" select="getTeacherById"/>
复制代码
Spring踩坑记录
1,什么是IOC?
我的理解:
将一些本由程序员自己做的事,现在可以交给客户去做。就比如程序员给客户提供了三种分别连接sqlserver,mysql,oracle的接口,假设用户现在需要连接的数据库mysql,程序员在业务层直接指定数据库是mysql,然后用户直接使用。但是过了一段时间,用户公司转型了,现在需要对接的数据库是Oracle,那么此时就要叫程序员在业务层对数据库类型进行更改,如果用户公司需要频繁的切换数据库那怎么办呢???如果交给程序员去做的话,那程序员岂不累死,这需要频繁的对原来的代码进行修改。此时我们就可以考虑在不更改源代码的前提下,这种切换数据库的操作就由用户自己去解决,程序员只需要提供对应的数据库的接口即可,用户通过调用对应的数据库接口实现对数据库的切换。
2,静态代理,JDK动态代理,cglib动态代理的主要区别
-
静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
-
动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中。比如:interface不能实例化,那有没有可能不编写实现类,直接在运行期创建某个interface的实例呢?答案是可能的,我们可以使用动态代理提供在运行期创建某个interface的实例。
-
使用JDK动态代理的对象必须实现一个或多个接口
-
使用cglib代理的对象则无需实现接口,达到代理类的无侵入
-
jdk动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。
参考: 1) www.liaoxuefeng.com/wiki/125259…
-
segmentfault.com/a/119000001…
-
推荐阅读:
来源 微信公众号:撸Java源码