diff --git a/adapter.go b/adapter.go
index 20ece493c9fb8914594f0cc813df3072be495483..3dd009277a81789a2da9498379471ffce5984612 100644
--- a/adapter.go
+++ b/adapter.go
@@ -233,6 +233,24 @@ func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
 	return err
 }
 
+// AddPolicies adds policy rules to the storage.
+func (a *Adapter) AddPolicies(sec string, ptype string, rules [][]string) error {
+	var lines []*CasbinRule
+	for _,rule := range rules{
+		line := savePolicyLine(ptype, rule)
+		lines = append(lines, line)
+	}
+	
+	err := a.db.RunInTransaction(func(tx *pg.Tx) error {
+		_, err := tx.Model(&lines).
+		OnConflict("DO NOTHING").
+		Insert()
+		return err
+	})
+	
+	return err
+}
+
 // RemovePolicy removes a policy rule from the storage.
 func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
 	line := savePolicyLine(ptype, rule)
@@ -240,6 +258,23 @@ func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
 	return err
 }
 
+// RemovePolicies removes policy rules from the storage.
+func (a *Adapter) RemovePolicies(sec string, ptype string, rules [][]string) error {
+	var lines []*CasbinRule
+	for _,rule := range rules{
+		line := savePolicyLine(ptype, rule)
+		lines = append(lines, line)
+	}
+
+	err := a.db.RunInTransaction(func(tx *pg.Tx) error {
+		_, err := tx.Model(&lines).
+		Delete()
+		return err
+	})
+	
+	return err
+}
+
 // RemoveFilteredPolicy removes policy rules that match the filter from the storage.
 func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
 	query := a.db.Model((*CasbinRule)(nil)).Where("p_type = ?", ptype)
diff --git a/adapter_test.go b/adapter_test.go
index 44eaa8f2dc42f7ba32b21087da1e799412d47919..c74aea0407ecd7b8153a8d0cdb148edb21c5ce78 100644
--- a/adapter_test.go
+++ b/adapter_test.go
@@ -105,6 +105,35 @@ func (s *AdapterTestSuite) TestAutoSave() {
 		[][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"alice", "data1", "write"}},
 		s.e.GetPolicy(),
 	)
+
+	_, err = s.e.AddPolicies([][]string{
+		{"bob", "data2", "read"},
+		{"alice", "data2", "write"},
+		{"alice", "data2", "read"},
+		{"bob", "data1", "write"},
+		{"bob", "data1", "read"},
+	})
+	s.Require().NoError(err)
+	// Reload the policy from the storage to see the effect.
+	err = s.e.LoadPolicy()
+	s.Require().NoError(err)
+	// The policy has a new rule: {"alice", "data1", "write"}.
+	s.assertPolicy(
+		[][]string{
+		{"alice", "data1", "read"},
+		{"bob", "data2", "write"},
+		{"data2_admin", "data2", "read"},
+		{"data2_admin", "data2", "write"},
+		{"alice", "data1", "write"},
+		{"bob", "data2", "read"},
+		{"alice", "data2", "write"},
+		{"alice", "data2", "read"},
+		{"bob", "data1", "write"},
+		{"bob", "data1", "read"},
+	},
+		s.e.GetPolicy(),
+	)
+
 	s.Require().NoError(err)
 }
 
@@ -141,6 +170,17 @@ func (s *AdapterTestSuite) TestRemovePolicy() {
 		[][]string{{"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}},
 		s.e.GetPolicy(),
 	)
+
+	_, err = s.e.RemovePolicies([][]string{
+		{"data2_admin", "data2", "read"},
+		{"data2_admin", "data2", "write"},
+	})
+	s.Require().NoError(err)
+
+	s.assertPolicy(
+		[][]string{{"bob", "data2", "write"}},
+		s.e.GetPolicy(),
+	)
 }
 
 func (s *AdapterTestSuite) TestRemoveFilteredPolicy() {
diff --git a/go.mod b/go.mod
index bab686a6d67aa206355b5abc32c50b8db2e78079..3fac4cc0e5b145e7f608822911300fb20114d5e4 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/casbin/casbin-pg-adapter
 go 1.12
 
 require (
-	github.com/casbin/casbin/v2 v2.1.2
+	github.com/casbin/casbin/v2 v2.4.1
 	github.com/go-pg/pg/v9 v9.1.0
 	github.com/mmcloughlin/meow v0.0.0-20181112033425-871e50784daf
 	github.com/stretchr/testify v1.4.0
diff --git a/go.sum b/go.sum
index bcc65dd7559c353dec898b77304ea3bb60547a9c..51c2a0a5988db0e10353e9f0dc279b87d81192f9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,10 @@
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
 github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g=
 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/casbin/casbin/v2 v2.4.1 h1:1dDJbnUoCTUu5ysFhaYND0yY8YReQ+GDQ7yDy5FNHyY=
+github.com/casbin/casbin/v2 v2.4.1/go.mod h1:XXtYGrs/0zlOsJMeRteEdVi/FsB0ph7KgNfjoCoJUD8=
 github.com/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA=
 github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=