略(在1中末尾有体现)
2:删除操作根据学号删除一条学生信息
步骤:
在StudentDAO中定义删除方法
在StudentMapper.xml中对接口方法进行"实现"(插件可以生成)
测试:在StudentDAO的测试类中添加测试方法
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//SqlSessionFactory表示mybatis的会话工厂,工厂模式
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//SqlSession 对象是mybatis和数据库之间的连接,也就是会话,创建了连接,可以得到所有的mapper对象(映射关系)
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过SqlSession 对象调用getMapper方法获取DAO接口对象
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
//调用被测试方法
int i = studentDAO.deleteStudent("10001");
//提交事务
sqlSession.commit();
System.out.println(i);
} catch (IOException e) {
e.printStackTrace();
}
}
3.修改操作
根据学号,修改其他字段信息
update tb_students set stu_name = #{stuName}, stu_gender = #{stuGender}, stu_age = #{stuAge} where stu_num = #{stuNum}
@Test
public void testUpdateStudent(){
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
int i = studentDAO.updateStudent(new Student(2,"10002","can","男",18));
sqlSession.commit();
assertEquals(1,i);//期望,单元测试的期望返回结果
System.out.println(i);
} catch (IOException e) {
e.printStackTrace();
}
}
assertEquals(1,i)
如果两者一致, 程序继续往下运行.
如果两者不一致, 中断测试方法, 抛出异常信息 AssertionFailedError .
- 在studentDAO接口中定义方法,返回多条,所以用List集合来装
在studentMapper文件中写
下面为两种实现方案:法一取别名,法二用resultMap
这里resulttype就可以不写了,因为map里已经有了
这里直接复制数据库的
- test方法里面写
@Test
public void testStudentList() {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
List studentList = studentDAO.listStudents();
assertNotNull(studentList);
sqlSession.commit();
for (Student student : studentList
) {
System.out.println(student);
}
} catch (IOException e) {
}
}
最终得到结果
根据学号查询一个学生信息
和上文同样的方法
几个注意点:
- 多个查询操作可以使用同一个map
- 查询不需要提交事务牢记三部曲-在StudentDAO中定义接口方法;用插件+自己写的mysql语句在StudentDAOMappperxml 中配置StudentDAO接口的方法实现–SQL;写单元测试
参数 start ,pagesize
在StudentDAO中定义操作方法,如果方法有多个参数,使用@Param 注解声明参数的别名
package com.liguoqing.dao;
public interface StudentDAO {
public int insertStudent(Student student);
public int deleteStudent(String stuNum);
public int updateStudent(Student student);
public List listStudents();
public Student queryStudent(String stuNum);
// public List listStudentsByPage(HashMap map);
// public List listStudentsByPage(int start,int pageSize);
public List listStudentsByPage(@Param("start") int start
,@Param("pageSize") int pageSize);
}
在StudentMapper.xml配置sql时,使用#{}获取到指定的参数
—注意:如果DAO操作方法,没有通过@Param指定参数别名,在SQL中也可以通过MyBatis自带的arg0 ,arg1… 或者 param1,param2…获取参数
单元测试
@Test
public void testlistStudentsByPage() {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
// HashMap map = new HashMap();
// map.put("start",0);
// map.put("pageSize",2);
// List studentList = studentDAO.listStudentsByPage(map);
List studentList = studentDAO.listStudentsByPage(0,2);
assertNotNull(studentList);
sqlSession.commit();
for (Student student : studentList
) {
System.out.println(student);
}
} catch (IOException e) {
}
}
7.查询操作-查询总记录数
StudentDAO
public int getCount();
在StudentMapper.xml配置sql时,使用 resultType 指定当前操作的返回类型为int(插件自动生成java.lang.Integer也没问题)
单元测试
@Test
public void testGetStudentCount(){
try{
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
int i = studentDAO.getCount();
System.out.println(i);
}catch (IOException e){
}
}
8.添加操作回填生成的主键
在StudentMapper.xml
在insert标签中 useGeneratedKeys 设置添加操作是否需要回填生成的主键 keyProperty 设置回填的位置
insert into tb_students(stu_num, stu_name, stu_gender, stu_age)
values (#{stuNum}, #{stuName}, #{stuGender}, #{stuAge})
二.MyBatis工具类封装
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
public class MyBatisUtil {
private static SqlSessionFactory factory;//单例的
private static final ThreadLocal local = new ThreadLocal(); //线程锁,各个线程之间不影响,例如开启关闭数据库连接之类的
static {
try {
//加载myBatis配置文件,创建会话工厂
factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
//得到sqlSession对象
public static SqlSession getSqlSession() throws IOException {
SqlSession sqlSession = local.get();
if (sqlSession == null){
sqlSession = factory.openSession();
local.set(sqlSession);
}
return sqlSession;
}
public static T getMapper(Class C) throws IOException {
SqlSession sqlSession = getSqlSession();
T dao = sqlSession.getMapper(C);
return dao;
}
public static SqlSessionFactory getFactory() throws IOException {
if (factory == null){
factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}
return factory;
}
}
这样就可以简短的写测试内容
sqlSession对象的作用:
- getMapper(DAO.class) 获取Mapper(DAO接口的实例)事务管理
1:手动提交事务
sqlSession .commit() 提交事务
sqlSession.rollback() 事务回滚
@Test
public void insertStudent() {
try {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//1:当我们获取sqlSession对象时,就默认开启了事务
try{
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
Student student = new Student(0, "10005", "java少年", "男", 24);
int i = studentDAO.insertStudent(student);
//2:操作完成并成功以后,需要手动提交
sqlSession.commit();
System.out.println(student);
System.out.println(i);
}catch (Exception e){
//3:当操作出现异常,调用rollback进行回滚
sqlSession.rollback();
}
} catch (IOException e) {
e.printStackTrace();
}
}
2:自动提交事务
sqlSession = factory.openSession(true);//这里的参数,如果不填,默认是false,也就是需要手动进行提交,如果填了true会自动提交事务
待补
四.MyBatis主配置文件mybatis-config.xml 是MyBatis框架的主配置文件,主要用于配置MyBatis数据源以及工作属性信息
注意:
标签使用时需要注意顺序
空标签会导致报错
可以使用properties读取properties配置文件。使用其中的resource属性来设置配置文件的路径。
然后使用${key}来获取配置文件中的值
例如:
在resources目录下有jdbc.properties文件,内容如下:
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db jdbc.driver=com.mysql.jdbc.Driver jdbc.username=root jdbc.password=root
在mybatis-config.xml中:
7.2 settings
可以使用该标签来设置进行一些设置
例如:
具体的设置参考:https://mybatis.org/mybatis-3/zh/configuration.html#settings
7.3 typeAliases 可以用来设置给全类名设置别名,简化书写。一般设置一个包下的类全部具有默认别名。默认别名是类目首字母小写。例如:com.sangeng.pojo.User别名为user
7.4 environments
配置数据库相关的环境,例如事物管理器,连接池相关参数等。
7.5 mappers
该标签的作用是加载映射的,加载方式有如下几种(主要使用第四种):
①使用相对于类路径的资源引用,例如:
②使用完全限定资源定位符(URL),例如:
③使用映射器接口实现类的完全限定类名,例如:
④将包内的映射器接口实现全部注册为映射器,例如:
此时对应包下所有xml映射文件都能找到
8. 打印日志①log4j配置 在resources目录下创建log4j.properties文件:
在Create resource bundle的弹出框中,在Resource bundel base name的输入框中填写资源文件的名称,不要带properties后缀,例如:validatemessage,其余都默认设置,点击OK按钮后就可以在resources文件夹中新增了一个validatemessage.properties文件
内容如下:
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
②引入依赖
log4j log4j 1.2.17
看这些是最重要的
如果使用#{}.他是预编译的sql可以防止SQL注入攻击
如果使用${}他是直接把参数值拿来进行拼接,这样会有SQL注入的危险
如果使用的是#{}来获取参数值日志如下:
Preparing: select * from user where id = ? and username = ? and age = ? and address = ?
Parameters: 2(Integer), 快乐风男(String), 29(Integer), 北京(String)
如果使用${}来获取参数值日志如下:
Preparing: select * from user where id = 2 and username = 快乐风男 and age = 29 and address = 北京



