SqlSession接口:定义了操作数据的方法,例如:selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()
使用要求:SqlSession对象线程不安全,需要在方法内使用,在执行sql语句之前,使用openSession()获取sqlSession对象。在执行完sql语句后,需要关闭它,执行SqlSession.close(),这样保证他的使用是线程安全的
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目一个就够了
SqlSessionFactory是个接口,实现类是defaultSqlSessionFactory。作用是获取sqlSession对象。
openSession()方法说明:
openSession(): 无参,获取是非自动提交事务的sqlSession对象
openSession(boolean); openSession(true)获取自动提交事务的Sqlsession
SqlSession sqlSession = factory.openSession();
mybatis中负责读取主配置文件
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
mybatis-mapper模板,设置–>代码模板中添加mybatis-mapper.xml模板,下次写dao映射文件直接改这个模板就行
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao接口的全限定名称">
//查询
<select id="接口中方法名" resultType="结果类型,类的全限定名称">
//sql语句
select>
//插入
<insert id="....">
insert>
//更新
<update id="...." >
update>
//删除
<delete id="...">
delete>
mapper>
设置好模板,下次新建就有 mybatis-mapper 可以选择,如下图
同理,创建mybatis-config模板,下次创建主配置文件mybatis.xml直接改模板就行
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
<environments default="和某个environmentid值一致,表示连接哪个数据库">
<environment id="">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/"/>
<property name="username" value="root"/>
<property name="password" value="137171"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="映射文件的类路径位置"/>
mappers>
configuration>
mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句
使用动态代理方式
1.获取SqlSession对象,SqlSessionFactory.openSession()
2.使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class)
3.使用dao接口的方法,调用方法就执行了mapper文件中的sql语句
使用动态代理的要求
1.dao接口和mapper文件放在一起,同一个目录
2.dao接口和mapper文件名称一致
3.mapper文件中的namespace的值是dao接口的全限定名称
4.mapper文件中的<select>,<insert>,<update>,<delete>等的id是接口中方法名称
5.dao接口中不要使用重载方法,不要使用同名的,不同参数的方法
MyBatisUtils.java 用于获取 sqlSession对象
public class MyBatisUtils {
private static SqlSessionFactory factory = null;
static {
String config="mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(config);
//使用SqlSessionFactoryBuilder,创建SqlSessionFactory对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession的方法
public static SqlSession getSqlSession(){
SqlSession sqlSession = null;
if (factory != null){
sqlSession = factory.openSession();//非自动提交事务
}
return sqlSession;
}
}
实现类 StudentDaoImpl.java
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.zh.dao.StudentDao.selectStudents";
//执行sql语句,用SqlSession类里面的方法
List<Student> students = sqlSession.selectList(sqlId);
//关闭事务
sqlSession.close();
return students;
}
}
测试类
public class TestMyBatis {
@Test
public void testSelectStudent(){
StudentDao Dao = new StudentDaoImpl();
List<Student> students = Dao.selectStudents();
for (Student student: students){
System.out.println(student);
}
}
}
不用创建实现类,直接调用 SqlSession.getMapper(dao接口.class),就可以得到dao接口的实现类
public class TestMyBatis {
@Test
public void testSelectStudent(){
/*
* 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口.class)
* getMapper能获取dao接口对应的实现类对象
*
* */
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class); //重点
System.out.println("dao="+dao.getClass().getName());//dao=com.sun.proxy.$Proxy2,JDK动态代理
List<Student> students = dao.selectStudents();
for (Student student : students){
System.out.println("学生"+student);
}
}
}
把数据传入映射文件的sql语句中
传入参数的几种方式
1 一个简单类型的参数:#{
任意字符}
2 多个简单类型的参数,使用 @Param("自定义名称")
3 使用一个java对象,对象的属性值作为mapper文件找到参数,#{
java对象的属性值名称}
简单类型:mybatis把java的 基本数据类型 和 String 都叫简单类型
在mapper文件获取简单类型的一个参数的值,使用 #{任意字符},这个是:id=#{id}
接口方法
//按ID查询,参数是Integer类型,返回值类型是Student类型
public Student selectStudentById(Integer id);
映射文件语句
<select id="selectStudentById" resultType="com.zh.entity.Student" parameterType="java.lang.Integer">
select id,name,email,age from student where id=#{id}
select>
对应的测试方法
@Test
public void testSelectStudentById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectStudentById(2);
System.out.println("student="+student);
}
接口
public List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") String age)
映射文件
<select>
select id,name,email,age from student where name=#{myname} or age=#{myage}
select>
测试方法
//多参查询 @param 命名参数
@Test
public void testSelectMultiParam(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectMultiParam("梁家辉", 33);
System.out.println("students="+students);
sqlSession.close();
}
先定义一个实体类 QueryParam.java
package com.zh.vo;
public class QueryParam {
private String paramName;
private Integer paramAge;
public String getParamName() {
return paramName;}
public void setParamName(String paramName) {
this.paramName = paramName;}
public Integer getParamAge() {
return paramAge;}
public void setParamAge(Integer paramAge) {
this.paramAge = paramAge;}}
}
接口
List<Student> selectMultiObject(QueryParam param);
mapper文件
<select id="selectMultiObject" resultType="com.zh.entity.Student">
select * from Student where name=#{paramName} or age=#{paramAge}
select>
测试方法
//多参查询 对象方式
@Test
public void testSelectMultiObject(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
QueryParam queryParam = new QueryParam();
queryParam.setParamName("李小龙");
queryParam.setParamAge(32);
List<Student> students = dao.selectMultiObject(queryParam);
System.out.println("students="+students);
sqlSession.close();
}
1 #是占位符,表示列值的,放在等号右侧
2 $是占位符,表示字符串的连接,把sql语句连接成一个字符串
3 #使用JDBC指定PreparedStatement对象执行SQL语句,效率高,没有sql注入的风险
4 $使用Starement对象执行sql,效率低,有sql注入的风险
1 resultType 结果类型,指sql语句执行完成后,数据转为java对象,java类型是任意的
resultType 结果类型,它的值
1、类型的全限定名称
2、类型的别名,例如 java.lang.Integer的别名为int
接口方法
public Student selectStudentById(Integer id);
mapper映射
<select id="selectStudentById" resultType="com.zh.entity.Student" >
select id,name,email,age from student where id=#{id}
select>
测试方法
@Test
public void testSelectStudentById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectStudentById(2);
System.out.println("student="+student);
}
resultMap 可以自定义sql的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。
自定义类型的别名
1 在mybatis主配置文件中定义,使用 <typeAlias> 定义别名
2 可以在resultType中使用自定义别名
resultMap 结果映射,指定列名和java对象属性的对应关系
1 你自定义列值赋值给哪个属性
2 当你的列名和属性名不一样时,一定使用resultMap
接口
//使用resultMap定义映射关系
List<Student> selectAllStudent();
mapper映射文件
<resultMap id="StudentMap" type="com.zh.entity.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<result property="age" column="age"/>
resultMap>
<select id="selectAllStudent" resultMap="StudentMap">
select id,name,email,age from student
select>
方式一
自定义MyStudent类,这里属性定义分别为:stuid,stuname,stuemail,stuage
package com.zh.entity;
public class MyStudent {
private Integer stuid;
private String stuname;
private String stuemail;
private Integer stuage;
public Integer getStuid() {
return stuid;}
public void setStuid(Integer stuid) {
this.stuid = stuid;}
public String getStuname() {
return stuname;}
public void setStuname(String stuname) {
this.stuname = stuname;}
public String getEmail() {
return stuemail;}
public void setEmail(String email) {
this.stuemail = email;}
public Integer getStuage() {
return stuage;}
public void setStuage(Integer stuage) {
this.stuage = stuage;}
@Override
public String toString() {
return "myStudent{" +
"stuid=" + stuid +
", stuname='" + stuname + '\'' +
", email='" + stuemail + '\'' +
", stuage=" + stuage +
'}';
}
}
mapper映射文件,这里student表的属性分别为:id,name,email,age和自定义MyStudent类中属性不一致,这时用resultMap映射关系
<resultMap id="myStudentMap" type="com.zh.entity.MyStudent">
<id property="stuid" column="id"/>
<result property="stuname" column="name"/>
<result property="stuemail" column="email"/>
<result property="stuage" column="age"/>
resultMap>
<select id="selectMyStudent" resultMap="myStudentMap">
select id,name,email,age from student
select>
方式二
mapper映射: 直接在sql语句中添加 ( as 对象属性名,简单常用)
<select id="selectDiffColProperty" resultType="com.zh.entity.MyStudent">
select id as stuid,name as stuname,email as stuemail,age as stuage from student
select>
在java代码中指定like的内容
接口
//第一种模糊查询,在java代码指定like的内容
List<Student> selectLikeOne(String name);
mapper映射
<select id="selectLikeOne" resultType="com.zh.entity.Student">
select id,name,email,age from student where name like #{name}
select>
测试类
@Test
public void testSelectLikeOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//定义一个String类型的值
String name = "%周%";
List<Student> students = dao.selectLikeOne(name);
for (Student stu : students){
System.out.println(stu);
}
sqlSession.close();
}
结果如下
sql内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。
动态sql的实现,使用的是mybatis提供的标签,< if >,< where >,< foreach >
语法:
<if test="判断java对象的属性值">
部分sql语句
if>
当多个 if 有一个成立时,< where >会自动生成一个WHERE关键字,并去掉 if 中多余的and,or等
接口
//where
List<Student> selectStudentWhere(Student student);
mapper映射
<select id="selectStudentWhere" resultType="com.zh.entity.Student">
select id,name,email,age from student
<where>
<if test="name != null and name != ''">
name = #{name}
if>
<if test="age > 0">
or age = #{age}
if>
where>
select>
测试
//where
@Test
public void testSelectStudentWhere(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("周润发");
student.setAge(20);
List<Student> students = dao.selectStudentWhere(student);
for (Student student1 : students){
System.out.println("Where="+student1);
}
sqlSession.close();
}
去掉一个student.setName(“周润发”);执行结果:
主要用在 sql 的 in语句中
接口
//foreach
List<Student> selectForeachOne(List<Integer> idlist);
mapper映射
<select id="selectForeachOne" resultType="com.zh.entity.Student">
select * from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
foreach>
select>
测试
//foreach 方式一
@Test
public void testSelectForeachOne() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//定义一个list数组
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
List<Student> students = dao.selectForeachOne(list);
for (Student student : students) {
System.out.println("foreach=" + student);
}
}
接口
//foreach 用法二 根据对象属性查询
List<Student> selectForeachTwo(List<Student> stulist);
mapper
<select id="selectForeachTwo" resultType="com.zh.entity.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
foreach>
select>
测试
//foreach 方式二
@Test
public void testSelectForeachTwo() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> stuList = new ArrayList<>();
Student s1 = new Student();
s1.setId(1);
stuList.add(s1);
Student s2 = new Student();
s2.setId(2);
stuList.add(s2);
List<Student> students = dao.selectForeachTwo(stuList);
for (Student student : students) {
System.out.println("foreach=" + student);
}
}
单独定义sql代码片段,替代相同sql语句
mapper映射
<sql id="studentSql">
select id,name,email,age from student
sql>
<select id="selectStudentIf" resultType="com.zh.entity.Student">
-- select id,name,email,age from student
<include refid="studentSql"/>
where id > 0
<if test="name != null and name != ''">
name = #{name}
if>
<if test="age >0">
or age > #{age}
if>
select>
把数据库连接信息放到一个单独的文件中。便于修改,保存,处理多个数据库信息。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssh
jdbc.username=root
jdbc.password=137171
<properties resource="jdbc.properties"/>
<environments default="one">
<environment id="one">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="#{jdbc.driver}"/>
<property name="url" value="#{jdbc.url}"/>
<property name="username" value="#{jdbc.username}"/>
<property name="password" value="#{jdbc.password}"/>
dataSource>
environment>
name:mapper文件所在的包名,包中所有xml一次性加载,要求:
1、mapper文件名需要和接口名一样
2、mapper文件和dao接口在同一目录下
实例如下
<mappers>
<mapper resource="com/zh/dao/StudentDao.xml"/>
<package name="com.zh.dao"/>
mappers>
https://www.bilibili.com/video/BV185411s7Ry
#代做毕业设计,有需求私信