1.Mybaties
1.概述:
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
JDBC连接:
//加载驱动
class.forname("com.mysql.cj.jdbc.Driver");
//获取连接对象并获取连接
String url = "";
String user ="root";
String password ="";
Connection connecton = DriverManager.getconnection("url","user","password");
//定义sql语句
String sql = "select * from user";
//获取执行sql对象
PreparedStatement statement=connection.prepareStatement(sql);
//给占位符赋值
prepareStatement.setString(1,name);
prepareStatement.setString(2,password);
//执行命令
ResultSet resultSet = PreparedStatement.executeQuery()
//处理
return resultSet.next()
pom.xml文件代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>MybatisCRUD</artifactId>
<groupId>com.wdzl</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../MybatisCRUD/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>MybatisManyToMany</artifactId>
</project>
//1.读取配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
(构建者模式:把复杂的对象构建细节进行隐藏,使用者直接调用方法获取对象)
//3.使用工厂生成SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
(工厂模式:1.解耦合,屏蔽new关键字2.便于维护:将对象的创建和使用进行了分离)
//4.使用SqlSession创建Dao层的代理对象
UserDao mapper = sqlSession.getMapper(UserDao.class);
(代理模式:不修改源码的基础上对已经有的方法进行增强)
2.环境搭载
1.创建Maven工程,导入依赖坐标
2.创建实体类: a:属性名和列名相同 b:实现Serializable接口
3.dao层接口
4.创建Mybatis主配置文件:(SqlConfigMap.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>
<!--配置别名-->
<typeAliases>
<package name="com.wdzl.bean"/>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis2?userSSL=true&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!--指定映射文件配置的位置-->
<mappers>
<mapper resource="com/wdzl/dao/UserDao.xml"></mapper>//指向UserDao.xml的位置。
<mapper resource="com/wdzl/dao/AccountDao.xml"></mapper>//AccountDao.xml的全限定类名。
</mappers>
</configuration>
5.创建映射配置文件:userDao.xml
1.对接口的方法实现
注意事项:
1.命名问题
2.创建Directory 和Paxkage的区别
Directory: 一级一级的建
Package:一次性创建多级
3
//1.读取配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
(构建者模式:把复杂的对象构建细节进行隐藏,使用者直接调用方法获取对象)
//3.使用工厂生成SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
(工厂模式:1.解耦合,屏蔽new关键字2.便于维护:将对象的创建和使用进行了分离)
//4.使用SqlSession创建Dao层的代理对象
UserDao mapper = sqlSession.getMapper(UserDao.class);
(代理模式:不修改源码的基础上对已经有的方法进行增强)
3.连接池
1.Mybatis支持三种内置的
数据源类型
1.POOLED:实现了DataSource接口,并使用连接池的思想
2.UNPOOLED:实现了DataSource接口,没有使用连接池的思想
3.JDNL:采用服务器提供的DNI技术实现的,并且不同服务器之间的获取的连接池也是不同的
2.事物
SqlSession sqlSession = build.openSession();
可以进行事物的控制,true
自动提交
SqlSession sqlSession = build.openSession(true);
手动提交
SqlSession sqlSession = build.openSession(flase);
SqlSession sqlSession = build.openSession();
是flase 的时候手动提交
不写的时候默认提交;
可以通过openSession()传入一个boolean值的
3.Mybatis 多表查询
在mysql中,表于表之间的关系有几种
1.一对一
2.一对多
2.1.根据账户查询对应用户的信息
(多读一的问题转化成一对一来解决)
1.bean层(User Account)2.dao层接口(UserDao AccountDao) 3.配置文件(AccountDao.xml UserDao.xml)
public Class Account{
private Integer id;
private Integer uid;
private Double money;
private User user; //账户只属于一个用户
}
public interface AccountDao {
List<Account> findAll();//接口定义的查询方法,返回的结果为list集合
}
public interface UserDao {
List<User> findById(Integer id);
}
<?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="com.wdzl.dao.AccountDao">
/*id="accountUserMap" :封装结果集的一个名称
type="Account" :User实体类定义的List<Account> 返回的结果集类型*/
<resultMap id="accountUserMap" type="Account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="id" javaType="com.wdzl.bean.User">
<id property="id" column="id"></id> //因为id是主键
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<sql id="accountBase">
select * from account;
</sql>
<select id="findAll" resultMap="accountUserMap" >
SELECT a.id,u.*, a.money FROM account a,USER u WHERE u.`id` = a.`id`
</select>
</mapper>
public class AccountTest {
@Test
public void findAllTest2() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSession sqlSession = factory.openSession();
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
List<Account> account = accountDao.findAll();
for (Account account1: account){
System.out.println(account1);
}
}
}
控制台结果
Account{id=1, uid=null, money=1000.0, user=User{id=1, username='老王', birthday=Sun May 28 02:27:09 CST 2017, sex='男', address='北京', accounts=null}}
Account{id=2, uid=null, money=1000.0, user=User{id=2, username='小王', birthday=Wed Apr 03 23:09:37 CST 2019, sex='女', address='西安', accounts=null}}
Account{id=3, uid=null, money=2000.0, user=User{id=3, username='小李', birthday=Tue Jul 23 01:44:33 CST 2019, sex='女', address='咸阳', accounts=null}}
2.1.2通过账户id查询用户信息(在AccountDao.xml配置)
<select id="findById" resultMap="accountUserMap" parameterType="java.lang.Integer" >
select* from account a, user u where u.id=a.id and a.id = #{id }
</select>
参数id返回值类型为Integer,它的的位置在java.lang.Integer
2.2.根据用户查询账户信息
Userdao 配置文件信息
一对一:用assocation标签
一对多:装的是collection标签
<association property="user" column="id" javaType="com.wdzl.bean.User">
<collection property="accounts" ofType="Account" column="id">
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
List<Account> accounts;//一个用户有多个账户,放在List集合里
}
public interface UserDao {
List<User> findAll();//定义的方法
}
public interface AccountDao {
List<Account> findAll();//接口定义的查询方法,返回的结果为list集合
}
<?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="com.wdzl.dao.UserDao">
<resultMap id="UserAccountMap" type="User">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<collection property="accounts" ofType="Account" column="id">
<id property="id" column="id"></id>
<result property="uid" column="id"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
<sql id="userBase" >
select * from user ;
</sql>
<select id="findAll" resultMap="UserAccountMap" >/*这个resultMap必须对应封装结果集的名称,不 要写成resultType*/
select* from user u left join account a on u.id=a.id
</select>
</mapper>
public class UserTest {
@Test
public void findAllTest() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSession sqlSession = factory.openSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> all = userDao.findAll();
for (User user: all){
System.out.println(user);
}
}
}
控制台结果
User{id=1, username='老王', birthday=Sun May 28 02:27:09 CST 2017, sex='男', address='北京', accounts=[Account{id=1, uid=1, money=1000.0, user=null}]}
User{id=2, username='小王', birthday=Wed Apr 03 23:09:37 CST 2019, sex='女', address='西安', accounts=[Account{id=2, uid=2, money=1000.0, user=null}]}
User{id=3, username='小李', birthday=Tue Jul 23 01:44:33 CST 2019, sex='女', address='咸阳', accounts=[Account{id=3, uid=3, money=2000.0, user=null}]}
User{id=4, username='小刘', birthday=Sun Mar 04 23:52:36 CST 2018, sex='男', address='渭南', accounts=[Account{id=4, uid=4, money=null, user=null}]}
User{id=5, username='大王', birthday=Fri Nov 04 01:37:26 CST 2016, sex='男', address='富平', accounts=[Account{id=5, uid=5, money=null, user=null}]}
User{id=6, username='小马', birthday=Sat Apr 09 09:24:40 CST 2016, sex='女', address='上海', accounts=[Account{id=6, uid=6, money=null, user=null}]}
2.2.2通过用户id去查询账户信息(在UserDao.xml配置)
<select id="findById" resultMap="UserAccountMap" parameterType="java.lang.Integer">
select* from user u, account a where u.id=a.id and a.id = #{id}
</select>
3.多对多
根据用户信息查询查询所有角色信息(一个角色可以被多个用户使用,一个用户可以使用多个角色)
public class Role {
private int roleId;
private String roleName;
private String roleDesc;
private List<User> users;//一个角色可以被多个用户使用
}
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
List<Account> accounts;
List<Role> roles; //一个用户可以使用多个角色
}
在角色里面定义User,在User里面定义role。 相互的就是多对多。
/*RoleDao.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">
<mapper namespace="com.wdzl.dao.RoleDao">
<resultMap id="roleMap" type="Role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_Name"></result>
<result property="roleDesc" column="role_Desc"></result>
<collection property="users" ofType="User" column="id">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</collection>
</resultMap>
<sql id="RoleBase">
select * from role;
</sql>
<select id="findAll" resultMap="roleMap">
//Role里面的sql语句
SELECT u.*,r.* FROM USER u
LEFT JOIN user_role ur ON u.`id`=ur.`uID`
LEFT JOIN role r ON r.`rid` = ur.`rID`
</select>
</mapper>
/*UserDao.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">
<mapper namespace="com.wdzl.dao.UserDao">
<resultMap id="UserAccountMap" type="User">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<collection property="roles" ofType="Role" column="id">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_Name"></result>
<result property="roleDesc" column="role_Desc"></result>
</collection>
</resultMap>
<sql id="userBase" >
select * from user ;
</sql>
<select id="findAll" resultMap="UserAccountMap" >
//User里面的sql语句
select * from user u
left join role r on u.id=r.rid
</select>
</mapper>
1.UserTest控制台结果:
User{id=1, username='老王', birthday=Sun May 28 02:27:09 CST 2017, sex='男', address='北京', accounts=[Account{id=1, uid=1, money=null, user=null}], roles=[Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=null}]}
User{id=2, username='小王', birthday=Wed Apr 03 23:09:37 CST 2019, sex='女', address='西安', accounts=[Account{id=2, uid=2, money=null, user=null}], roles=[Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=null}]}
User{id=3, username='小李', birthday=Tue Jul 23 01:44:33 CST 2019, sex='女', address='咸阳', accounts=[Account{id=3, uid=3, money=null, user=null}], roles=[Role{roleId=3, roleName='校长', roleDesc='管理整个学校', users=null}]}
User{id=4, username='小刘', birthday=Sun Mar 04 23:52:36 CST 2018, sex='男', address='渭南', accounts=[Account{id=4, uid=4, money=null, user=null}], roles=[]}
User{id=5, username='大王', birthday=Fri Nov 04 01:37:26 CST 2016, sex='男', address='富平', accounts=[Account{id=5, uid=5, money=null, user=null}], roles=[]}
User{id=6, username='小马', birthday=Sat Apr 09 09:24:40 CST 2016, sex='女', address='上海', accounts=[Account{id=6, uid=6, money=null, user=null}], roles=[]}
2.RoleTest控制台结果:
Role{roleId=1, roleName='院长', roleDesc='管理整个学院', users=[User{id=1, username='老王', birthday=Sun May 28 02:27:09 CST 2017, sex='男', address='北京', accounts=null, roles=null}, User{id=3, username='小李', birthday=Tue Jul 23 01:44:33 CST 2019, sex='女', address='咸阳', accounts=null, roles=null}]}
Role{roleId=2, roleName='总裁', roleDesc='管理整个公司', users=[User{id=1, username='老王', birthday=Sun May 28 02:27:09 CST 2017, sex='男', address='北京', accounts=null, roles=null}]}
Role{roleId=0, roleName='null', roleDesc='null', users=[User{id=2, username='小王', birthday=Wed Apr 03 23:09:37 CST 2019, sex='女', address='西安', accounts=null, roles=null}]}
Role{roleId=0, roleName='null', roleDesc='null', users=[User{id=5, username='大王', birthday=Fri Nov 04 01:37:26 CST 2016, sex='男', address='富平', accounts=null, roles=null}]}
Role{roleId=0, roleName='null', roleDesc='null', users=[User{id=6, username='小马', birthday=Sat Apr 09 09:24:40 CST 2016, sex='女', address='上海', accounts=null, roles=null}]}
4、Mybatis的注解开发
注意:注解开发是为了简化映射配置文件,但是主配置文件还是存在的
注意分类:
Mybatis针对CRUD操作一共有四个注解
-
@Select
-
@Insert
-
@Delete
-
@Update
//查询所有用户(返回集合)
@Select("select * from account")
List<Account> findAll();
//插入一行账户数据
@Insert("insert into account (id,uid,money) values (#{id},#{id},#{money})")
void addAccount(Account account);
//删除账户(根据账户id)
@Delete("delete from account where id = #{id}")
void deleteAccount(Integer id);
//修改账户信息
@Update("update account set money=#{money} where id=#{id} ")
void updateAccount(Account account);
//增加账户信息
@Test
public void addAccountTest() {
Account account = new Account(4, 2, 1999);
mapper.addAccount(account);
System.out.println(account);
}
//删除账户信息
@Test
public void deleteAccountTest() {
mapper.deleteAccount(1);
}
//修改账户信息
@Test
public void updateAccountTest() {
Account account = new Account(2,1,179);
mapper.updateAccount(account);
System.out.println(account);
}
//查找账户信息
@Test
public void findAllTest() throws IOException {
List<Account> byId = mapper.findAll();
for (Account account : byId) {
System.out.println(account);
}
}