1、maven
一种辅助工具,对程序中用到的jar包进行管理,及jar包之间的依赖关系。
1)maven三要素
groupId(公司的标识,表明该项目所属的公司)
artifactId(项目的唯一标识,也可理解为项目名)
version版本(SNAPSSHOT快照版,也可理解为测试版),(RELEASE发布版
,也可理解为稳定版)
2)maven项目的目录结构不同以往的java项目目录,有一个src目录,还有
一个pom.xml文件。其src目录下多了main目录以及test目录,main目录下又
包含java与resources目录,java目录下放的是java源代码,resources目录
下放的是程序的配置文件及mapper映射文件;test目录下包含java目录,放
的是java测试代码。pom.xml文件下放的是maven项目自身的配置文件(一些
框架的jar包依赖)
2、mybatis属于ORM型框架,是通过关系型数据库与实体类间的映射关系
来简化数据库操作的一种框架。
2.1
1)在main目录下的java目录下写实体类
```
package entity;
import java.io.Serializable;
public class Emp implements Serializable {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
```
2)在resources下新建一个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="mapper.EmpMapper">
<insert id="insert" parameterType="entity.Emp"
useGeneratedKeys="true"
keyColumn="id"
keyProperty="id"
>
insert into emp(id,name,age) values(null,#{name},#{age})
</insert>
<delete id="delete" parameterType="list">
delete from emp where id in
<foreach collection="list" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</delete>
<!--<select id="selectByCondition" parameterType="map" resultType="entity.Emp">
select * from emp where 1=1
<if test="name !=null ">
and name like #{name}
</if>
<if test="minAge !=null and maxAge !=null">
and age between #{minAge} and #{maxAge}
</if>
</select>-->
<select id="selectByCondition" parameterType="map" resultType="entity.Emp">
select * from emp
<!--使用where标签可以去掉多余的and-->
<where>
<if test="name !=null ">
and name like #{name}
</if>
<if test="minAge !=null and maxAge !=null">
and age between #{minAge} and #{maxAge}
</if>
</where>
</select>
<update id="update" parameterType="entity.Emp">
update emp
<set>
<if test="name !=null">
name= #{name},
</if>
<if test="age !=0">
age= #{age}
</if>
</set>
where id=#{id}
</update>
<select id="selectByPage" parameterType="map" resultType="entity.Emp">
select * from emp limit #{index},#{number }
</select>
<select id="selectByLogical" resultType="entity.Emp">
select * from emp;
</select>
</mapper>
```
3)在resources目录下建一个mybatis-config.xml文件,是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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test3?
serverTimezone=GMT%2B8&useSSL=false&useServerPrepStmts
=true&cachePrepStmts=true&rewriteBatchedStatements=true
&useCursorFetch=true&defaultFetchSize=100&
allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="9315"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 让mabatis知道有哪些映射文件 -->
<mapper resource="mapper/User1Mapper.xml"/>
<mapper resource="mapper/EmpMapper.xml"/>
<mapper resource="mapper/DogMapper.xml"/>
<mapper resource="mapper/ProductMapper.xml"/>
</mappers>
</configuration>
```
4)在test目录下编写测试代码
4.1)获取配置文件的输入流
```
InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
```
4.2)创建SqlSessionFactory工厂类对象
```
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resource);
```
4.3)创建SqlSession对象
```
SqlSession sqlSession = factory.openSession();
```
4.4)进行sql语句操作
```
sqlSession.insert("mapper.EmpMapper.insert",emp);
```
4.5)提交事务
```
sqlSession.commit();
```
4.6)关闭资源
```
sqlSession.close();
```
2.2
1)
(
1.1)新增,获取自增长值;
1.2)动态sql,一次删除多条信息;
1.3)动态sql,按条件查询;
1.4)动态更新,修改姓名或是年龄任意一项时,不用依赖于另一项的条件;
1.5)物理分页查询,效率高,但是不通用,数据库改变,sql语句也得改变;
1.6)逻辑分页查询,查询全部数据,因而效率低,但是通用,适用于数据量
较少的情况
)
相关代码
```
<?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="mapper.EmpMapper">
<!--获取自增长的值,将数据库插入后生成的id值,同步到java对象
useGeneratedKeys="是否使用由数据库生成的主键"
keyColumn="主键列的名称"
keyProperty="主键要存入哪个属性"-->
<insert id="insert" parameterType="entity.Emp"
useGeneratedKeys="true"
keyColumn="id"
keyProperty="id"
>
insert into emp(id,name,age) values(null,#{name},#{age})
</insert>
<!--动态删除,一次删除多个
collection="要遍历的集合"
item="临时变量名称"
open="循环之前的符号"
close="循环之后的符号"
separator="每个元素的分隔符"-->
<delete id="delete" parameterType="list">
delete from emp where id in
<foreach collection="list" item="i" open="(" close=")" separator=",">
#{i}
</foreach>
</delete>
<!--<select id="selectByCondition" parameterType="map" resultType="entity.Emp">
select * from emp where 1=1
<if test="name !=null ">
and name like #{name}
</if>
<if test="minAge !=null and maxAge !=null">
and age between #{minAge} and #{maxAge}
</if>
</select>-->
<!--按条件查询-->
<select id="selectByCondition" parameterType="map" resultType="entity.Emp">
select * from emp
<!--使用where标签可以去掉多余的and-->
<where>
<if test="name !=null ">
and name like #{name}
</if>
<if test="minAge !=null and maxAge !=null">
and age between #{minAge} and #{maxAge}
</if>
</where>
</select>
<update id="update" parameterType="entity.Emp">
update emp
<set>
<if test="name !=null">
name= #{name},
</if>
<if test="age !=0">
age= #{age}
</if>
</set>
where id=#{id}
</update>
<!--物理分页查询,不通用,数据库不同sql语法有差异,但效率高-->
<select id="selectByPage" parameterType="map" resultType="entity.Emp">
select * from emp limit #{index},#{number }
</select>
<!--逻辑分页查询,查询所有,通用,效率低,适合数据较少的情况-->
<select id="selectByLogical" resultType="entity.Emp">
select * from emp;
</select>
</mapper>
```
```
import entity.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
public class TestEmp {
static SqlSessionFactory factory;
static {
try {
InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
factory=new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
//插入数据,依赖建表规则实现主键的自增
public void test1(){
SqlSession sqlSession = factory.openSession();
Emp emp = new Emp();
System.out.println("插入之前的id:"+emp.getId());
emp.setName("金秀贤");
emp.setAge(35);
sqlSession.insert("mapper.EmpMapper.insert",emp);
sqlSession.commit();
sqlSession.close();
System.out.println("插入之后的id:"+emp.getId());
}
@Test
//一次删除多条数据
public void test2(){
SqlSession sqlSession = factory.openSession();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
sqlSession.delete("mapper.EmpMapper.delete",list);
sqlSession.commit();
sqlSession.close();
}
@Test
//按条件查询
public void test3(){
SqlSession sqlSession = factory.openSession();
HashMap<String, Object> map = new HashMap<>();
//map.put("name","李%");
map.put("minAge",21);
map.put("maxAge",35);
List<Emp> list = sqlSession.selectList("mapper.EmpMapper.selectByCondition", map);
sqlSession.commit();
sqlSession.close();
for (Emp object:list){
System.out.println(object);
System.out.println("_________________________________________________");
}
}
@Test
//修改姓名或是年龄任意一项时,不用依赖于另一项的条件
public void test4(){
SqlSession sqlSession = factory.openSession();
Emp emp = new Emp();
emp.setAge(33);
emp.setId(5);
sqlSession.update("mapper.EmpMapper.update",emp);
sqlSession.commit();
sqlSession.close();
}
@Test
//分页查询1(物理查询,数据库类型改变,sql代码也会改变)
public void test5(){
SqlSession sqlSession = factory.openSession();
HashMap<String, Object> map = new HashMap<>();
map.put("index",4);
map.put("number",4);
List<Emp> list = sqlSession.selectList("mapper.EmpMapper.selectByPage",map);
Iterator<Emp> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
System.out.println("_____________________________________");
}
sqlSession.close();
}
@Test
//分页查询2(逻辑查询,查询所有,效率低,sql语句不因数据库类型的改变而改变,兼容性强)
public void test6(){
SqlSession sqlSession = factory.openSession();
List<Emp> list = sqlSession.selectList("mapper.EmpMapper.selectByLogical", null,
new RowBounds(4, 4));
sqlSession.close();
Iterator<Emp> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
System.out.println("__________________________________________");
}
}
}
```
2)数据库表中的数据与实体类的属性不匹配时
(
1)使用别名来解决该问题;
2)使用resultMap代替resultType
)
相关代码:
```
package entity;
import java.io.Serializable;
public class Dog implements Serializable {
private int id;
private String firstName;
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "Dog{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
```
```
<?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="mapper.DogMapper">
<!--方法一,采用别名解决-->
<!-- <select id="select" parameterType="int" resultType="entity.Dog">
<!–select id,first_name,last_name from dog where id=#{id}–>
select id,first_name firstName,last_name lastName from dog where id= #{id}
</select>-->
<!--方法二,使用resultMap代替resultType-->
<select id="select" parameterType="int" resultMap="mm">
select id,first_name,last_name from dog where id=#{id}
</select>
<!--id:主键列,result:其余列;column:数据库对应的列名;property:数据库列对应的实体类的属性名
type="实体对象的类型"
id 标签用来映射主键
result 标签用来映射其它列-->
<resultMap id="mm" type="entity.Dog">
<id column="id" property="id"></id>
<result column="first_name" property="firstName"></result>
<result column="last_name" property="lastName"></result>
</resultMap>
</mapper>
```
```
import entity.Dog;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class DogTest {
static SqlSessionFactory factory;
static {
//获取配置文件的输入流
try {
InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
factory=new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
//查询(当数据库的属性名和java中的实体类的属性不一致时)
public void test1(){
SqlSession sqlSession = factory.openSession();
Dog dog= sqlSession.selectOne("mapper.DogMapper.select",2);
sqlSession.close();
System.out.println(dog);
}
}
```
3)
(
1)当数据库中多个表之间存在连接关系时,想要获得多个表的信息时,
,把连接查询映射到多个有关系的实体类上;
2)mybatis中的一级缓存,每一个SqlSession都有一个一级缓存,只有在
首次查询数据库时,会把结果放入到缓存中,缓存中是以map键值对的形式
存储信息的,查询语句相当于键,结果相当于值,只要后续执行相同的sql
语句,就会直接从一级缓存中获取结果,不会再去查询数据库,作用范围
仅限同一个SqlSession对象;
3)mybatis中的二级缓存,其意义在于减少与数据库的交互,提高效率,不同于
一级缓存的地方是,它需要在对应的映射文件中的mapper标签下加一个 <cache/>
标签,这样,该映射文件中的所有查询操作都可以共享二级缓存了;
4)以上两种缓存,只要对数据库表执行了增、删、改操作,便会立即失效,
再次执行相同的查询语句,它会首先去数据库中查,不会去缓存中找了;
5)#{}与${}的区别
#{}是以占位符的方式生成sql语句,能够防止sql注入攻击,但是#{}不能进行
运算操作,不能对表名、列名进行改动,只能替换值;${}是以拼接字符串的方式生成sql语句,
不安全,但是能够进行运算操作,可以替换sql语句的任何部分
)
相关代码
```
package entity;
import java.io.Serializable;
public class Product implements Serializable {
private int id;
private String name;
private double price;
private Category category;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", category=" + category +
'}';
}
}
```
```
package entity;
import java.io.Serializable;
public class Category implements Serializable {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Category{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
```
```
<?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="mapper.ProductMapper">
<!--二级缓存配置方法-->
<cache/>
<!--连接查询,当多个表之间有连接关系时,想把有连接关系
的表的信息也显示出来-->
<select id="select" parameterType="int" resultMap="kkk">
select p.id,p.name,p.price,c.id cid,c.name cname from product p inner
join category c on p.category_id=c.id where p.id=#{id}
</select>
<resultMap id="kkk" type="entity.Product">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="price" property="price"></result>
<!--association关联-->
<association property="category" javaType="entity.Category">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</association>
</resultMap>
<!--一级缓存-->
<select id="select1" parameterType="int" resultType="entity.Product">
select id,name,price from product where id=#{id}
</select>
<update id="update" parameterType="entity.Product">
update product set price= ${price+500} where id= #{id}
</update>
</mapper>
```
```
import entity.Product;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class ProductTest {
static SqlSessionFactory factory;
static {
try {
//获取配置文件的输入流
InputStream resource = Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSession工厂类
factory = new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test1(){
//创建SqlSession对象
SqlSession sqlSession = factory.openSession();
Product product = sqlSession.selectOne("mapper.ProductMapper.select", 1);
System.out.println(product);
System.out.println("_____________________");
System.out.println(product.getCategory());
}
@Test
public void test2(){
SqlSession sqlSession1 = factory.openSession();
Product product1 = sqlSession1.selectOne("mapper.ProductMapper.select1", 1);
System.out.println("___________________________________");
Product product2 = sqlSession1.selectOne("mapper.ProductMapper.select1", 1);
System.out.println("___________________________________");
Product product3 = sqlSession1.selectOne("mapper.ProductMapper.select1", 2);
sqlSession1.close();
System.out.println("________________________________________");
SqlSession sqlSession2 = factory.openSession();
Product product4 = sqlSession2.selectOne("mapper.ProductMapper.select1", 1);
sqlSession2.close();
}
@Test
public void test3(){
SqlSession sqlSession = factory.openSession();
Product product = new Product();
product.setPrice(2499);
product.setId(1);
sqlSession.update("mapper.ProductMapper.update",product);
sqlSession.commit();
sqlSession.close();
}
}
```